Fragment can now be used together with action bar
Now possible to load the fragment even with existing toolbar, as long as setupToolbar() is overriden. Fixes #32 Signed-off-by: Jonas Kalderstam <jonas@kalderstam.se>
This commit is contained in:
parent
4124e8ea20
commit
2ede72dca9
|
|
@ -70,15 +70,15 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
public static final String KEY_ALLOW_MULTIPLE = "KEY_ALLOW_MULTIPLE";
|
||||
// Used for saving state.
|
||||
protected static final String KEY_CURRENT_PATH = "KEY_CURRENT PATH";
|
||||
protected final HashSet<T> checkedItems;
|
||||
protected final HashSet<CheckableViewHolder> checkedVisibleViewHolders;
|
||||
protected T currentPath = null;
|
||||
protected final HashSet<T> mCheckedItems;
|
||||
protected final HashSet<CheckableViewHolder> mCheckedVisibleViewHolders;
|
||||
protected T mCurrentPath = null;
|
||||
protected boolean allowCreateDir = false;
|
||||
protected boolean allowMultiple = false;
|
||||
private OnFilePickedListener listener;
|
||||
private FileItemAdapter<T> mAdapter = null;
|
||||
private TextView currentDirView;
|
||||
private SortedList<T> mFiles = null;
|
||||
protected OnFilePickedListener mListener;
|
||||
protected FileItemAdapter<T> mAdapter = null;
|
||||
protected TextView mCurrentDirView;
|
||||
protected SortedList<T> mFiles = null;
|
||||
|
||||
protected FileItemAdapter<T> getAdapter() {
|
||||
return mAdapter;
|
||||
|
|
@ -93,8 +93,8 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
* fragment (e.g. upon screen orientation changes).
|
||||
*/
|
||||
public AbstractFilePickerFragment() {
|
||||
checkedItems = new HashSet<>();
|
||||
checkedVisibleViewHolders = new HashSet<>();
|
||||
mCheckedItems = new HashSet<>();
|
||||
mCheckedVisibleViewHolders = new HashSet<>();
|
||||
|
||||
// Retain this fragment across configuration changes, to allow
|
||||
// asynctasks and such to be used with ease.
|
||||
|
|
@ -126,9 +126,10 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.nnf_fragment_filepicker, container, false);
|
||||
|
||||
Toolbar mToolbar = (Toolbar) view.findViewById(R.id.picker_toolbar);
|
||||
((AppCompatActivity) getActivity()).setSupportActionBar(mToolbar);
|
||||
|
||||
Toolbar toolbar = (Toolbar) view.findViewById(R.id.nnf_picker_toolbar);
|
||||
if (toolbar != null) {
|
||||
setupToolbar(toolbar);
|
||||
}
|
||||
|
||||
RecyclerView mRecyclerView = (RecyclerView) view.findViewById(android.R.id.list);
|
||||
// improve performance if you know that changes in content
|
||||
|
|
@ -141,26 +142,26 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
mAdapter = new FileItemAdapter<>(this);
|
||||
mRecyclerView.setAdapter(mAdapter);
|
||||
|
||||
view.findViewById(R.id.button_cancel)
|
||||
view.findViewById(R.id.nnf_button_cancel)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
if (listener != null) {
|
||||
listener.onCancelled();
|
||||
if (mListener != null) {
|
||||
mListener.onCancelled();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
view.findViewById(R.id.button_ok)
|
||||
view.findViewById(R.id.nnf_button_ok)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
if (listener == null) {
|
||||
if (mListener == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Some invalid cases first
|
||||
if ((allowMultiple || mode == MODE_FILE) && checkedItems.isEmpty()) {
|
||||
if ((allowMultiple || mode == MODE_FILE) && mCheckedItems.isEmpty()) {
|
||||
Toast.makeText(getActivity(),
|
||||
R.string.nnf_select_something_first,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
|
|
@ -168,33 +169,44 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
}
|
||||
|
||||
if (allowMultiple) {
|
||||
listener.onFilesPicked(toUri(checkedItems));
|
||||
mListener.onFilesPicked(toUri(mCheckedItems));
|
||||
} else if (mode == MODE_FILE) {
|
||||
listener.onFilePicked(toUri(getFirstCheckedItem()));
|
||||
mListener.onFilePicked(toUri(getFirstCheckedItem()));
|
||||
} else if (mode == MODE_DIR) {
|
||||
listener.onFilePicked(toUri(currentPath));
|
||||
mListener.onFilePicked(toUri(mCurrentPath));
|
||||
} else {
|
||||
// single FILE OR DIR
|
||||
if (checkedItems.isEmpty()) {
|
||||
listener.onFilePicked(toUri(currentPath));
|
||||
if (mCheckedItems.isEmpty()) {
|
||||
mListener.onFilePicked(toUri(mCurrentPath));
|
||||
} else {
|
||||
listener.onFilePicked(toUri(getFirstCheckedItem()));
|
||||
mListener.onFilePicked(toUri(getFirstCheckedItem()));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
currentDirView = (TextView) view.findViewById(R.id.current_dir);
|
||||
mCurrentDirView = (TextView) view.findViewById(R.id.nnf_current_dir);
|
||||
// Restore state
|
||||
if (currentPath != null) {
|
||||
currentDirView.setText(getFullPath(currentPath));
|
||||
if (mCurrentPath != null && mCurrentDirView != null) {
|
||||
mCurrentDirView.setText(getFullPath(mCurrentPath));
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the toolbar anyway you like here. Default is to set it as the activity's
|
||||
* main action bar. Override if you already provide an action bar.
|
||||
* Not called if no toolbar was found.
|
||||
*
|
||||
* @param toolbar from layout with id "picker_toolbar"
|
||||
*/
|
||||
protected void setupToolbar(Toolbar toolbar) {
|
||||
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
|
||||
}
|
||||
|
||||
public T getFirstCheckedItem() {
|
||||
for (T file : checkedItems) {
|
||||
for (T file : mCheckedItems) {
|
||||
return file;
|
||||
}
|
||||
return null;
|
||||
|
|
@ -224,7 +236,7 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
try {
|
||||
listener = (OnFilePickedListener) activity;
|
||||
mListener = (OnFilePickedListener) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString() +
|
||||
" must implement OnFilePickedListener");
|
||||
|
|
@ -255,14 +267,14 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
// Only if we have no state
|
||||
if (currentPath == null) {
|
||||
if (mCurrentPath == null) {
|
||||
if (savedInstanceState != null) {
|
||||
mode = savedInstanceState.getInt(KEY_MODE, mode);
|
||||
allowCreateDir = savedInstanceState
|
||||
.getBoolean(KEY_ALLOW_DIR_CREATE, allowCreateDir);
|
||||
allowMultiple = savedInstanceState
|
||||
.getBoolean(KEY_ALLOW_MULTIPLE, allowMultiple);
|
||||
currentPath =
|
||||
mCurrentPath =
|
||||
getPath(savedInstanceState.getString(KEY_CURRENT_PATH));
|
||||
} else if (getArguments() != null) {
|
||||
mode = getArguments().getInt(KEY_MODE, mode);
|
||||
|
|
@ -271,14 +283,14 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
allowMultiple = getArguments()
|
||||
.getBoolean(KEY_ALLOW_MULTIPLE, allowMultiple);
|
||||
if (getArguments().containsKey(KEY_START_PATH)) {
|
||||
currentPath =
|
||||
mCurrentPath =
|
||||
getPath(getArguments().getString(KEY_START_PATH));
|
||||
}
|
||||
}
|
||||
|
||||
// If still null
|
||||
if (currentPath == null) {
|
||||
currentPath = getRoot();
|
||||
if (mCurrentPath == null) {
|
||||
mCurrentPath = getRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -311,7 +323,7 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
@Override
|
||||
public void onSaveInstanceState(Bundle b) {
|
||||
super.onSaveInstanceState(b);
|
||||
b.putString(KEY_CURRENT_PATH, currentPath.toString());
|
||||
b.putString(KEY_CURRENT_PATH, mCurrentPath.toString());
|
||||
b.putBoolean(KEY_ALLOW_MULTIPLE, allowMultiple);
|
||||
b.putBoolean(KEY_ALLOW_DIR_CREATE, allowCreateDir);
|
||||
b.putInt(KEY_MODE, mode);
|
||||
|
|
@ -320,7 +332,7 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
listener = null;
|
||||
mListener = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -352,11 +364,13 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
@Override
|
||||
public void onLoadFinished(final Loader<SortedList<T>> loader,
|
||||
final SortedList<T> data) {
|
||||
checkedItems.clear();
|
||||
checkedVisibleViewHolders.clear();
|
||||
mCheckedItems.clear();
|
||||
mCheckedVisibleViewHolders.clear();
|
||||
mFiles = data;
|
||||
mAdapter.setList(data);
|
||||
currentDirView.setText(getFullPath(currentPath));
|
||||
if (mCurrentDirView != null) {
|
||||
mCurrentDirView.setText(getFullPath(mCurrentPath));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -447,12 +461,12 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
vh.text.setText(getName(data));
|
||||
|
||||
if (isCheckable(data)) {
|
||||
if (checkedItems.contains(data)) {
|
||||
checkedVisibleViewHolders.add((CheckableViewHolder) vh);
|
||||
if (mCheckedItems.contains(data)) {
|
||||
mCheckedVisibleViewHolders.add((CheckableViewHolder) vh);
|
||||
((CheckableViewHolder) vh).checkbox.setChecked(true);
|
||||
} else {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
checkedVisibleViewHolders.remove(vh);
|
||||
mCheckedVisibleViewHolders.remove(vh);
|
||||
((CheckableViewHolder) vh).checkbox.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -474,9 +488,9 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
*/
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
currentPath = getParent(currentPath);
|
||||
checkedItems.clear();
|
||||
checkedVisibleViewHolders.clear();
|
||||
mCurrentPath = getParent(mCurrentPath);
|
||||
mCheckedItems.clear();
|
||||
mCheckedVisibleViewHolders.clear();
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
|
@ -503,9 +517,9 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
if (isDir(file)) {
|
||||
currentPath = file;
|
||||
checkedItems.clear();
|
||||
checkedVisibleViewHolders.clear();
|
||||
mCurrentPath = file;
|
||||
mCheckedItems.clear();
|
||||
mCheckedVisibleViewHolders.clear();
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
|
@ -545,9 +559,9 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
if (isDir(file)) {
|
||||
currentPath = file;
|
||||
checkedItems.clear();
|
||||
checkedVisibleViewHolders.clear();
|
||||
mCurrentPath = file;
|
||||
mCheckedItems.clear();
|
||||
mCheckedVisibleViewHolders.clear();
|
||||
refresh();
|
||||
} else {
|
||||
onLongClick(v);
|
||||
|
|
@ -562,17 +576,17 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
*/
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
if (checkedItems.contains(file)) {
|
||||
if (mCheckedItems.contains(file)) {
|
||||
checkbox.setChecked(false);
|
||||
checkedItems.remove(file);
|
||||
checkedVisibleViewHolders.remove(this);
|
||||
mCheckedItems.remove(file);
|
||||
mCheckedVisibleViewHolders.remove(this);
|
||||
} else {
|
||||
if (!allowMultiple) {
|
||||
clearSelections();
|
||||
}
|
||||
checkbox.setChecked(true);
|
||||
checkedItems.add(file);
|
||||
checkedVisibleViewHolders.add(this);
|
||||
mCheckedItems.add(file);
|
||||
mCheckedVisibleViewHolders.add(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -583,11 +597,11 @@ public abstract class AbstractFilePickerFragment<T> extends Fragment
|
|||
* selected set.
|
||||
*/
|
||||
public void clearSelections() {
|
||||
for (CheckableViewHolder vh : checkedVisibleViewHolders) {
|
||||
for (CheckableViewHolder vh : mCheckedVisibleViewHolders) {
|
||||
vh.checkbox.setChecked(false);
|
||||
}
|
||||
checkedVisibleViewHolders.clear();
|
||||
checkedItems.clear();
|
||||
mCheckedVisibleViewHolders.clear();
|
||||
mCheckedItems.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ public class FilePickerFragment extends AbstractFilePickerFragment<File> {
|
|||
|
||||
@Override
|
||||
public SortedList<File> loadInBackground() {
|
||||
File[] listFiles = currentPath.listFiles();
|
||||
File[] listFiles = mCurrentPath.listFiles();
|
||||
final int initCap = listFiles == null ? 0 : listFiles.length;
|
||||
|
||||
SortedList<File> files = new SortedList<>(File.class, new SortedListAdapterCallback<File>(getDummyAdapter()) {
|
||||
|
|
@ -174,12 +174,12 @@ public class FilePickerFragment extends AbstractFilePickerFragment<File> {
|
|||
super.onStartLoading();
|
||||
|
||||
// handle if directory does not exist. Fall back to root.
|
||||
if (currentPath == null || !currentPath.isDirectory()) {
|
||||
currentPath = getRoot();
|
||||
if (mCurrentPath == null || !mCurrentPath.isDirectory()) {
|
||||
mCurrentPath = getRoot();
|
||||
}
|
||||
|
||||
// Start watching for changes
|
||||
fileObserver = new FileObserver(currentPath.getPath(),
|
||||
fileObserver = new FileObserver(mCurrentPath.getPath(),
|
||||
FileObserver.CREATE |
|
||||
FileObserver.DELETE
|
||||
| FileObserver.MOVED_FROM | FileObserver.MOVED_TO
|
||||
|
|
@ -220,10 +220,10 @@ public class FilePickerFragment extends AbstractFilePickerFragment<File> {
|
|||
*/
|
||||
@Override
|
||||
public void onNewFolder(final String name) {
|
||||
File folder = new File(currentPath, name);
|
||||
File folder = new File(mCurrentPath, name);
|
||||
|
||||
if (folder.mkdir()) {
|
||||
currentPath = folder;
|
||||
mCurrentPath = folder;
|
||||
refresh();
|
||||
} else {
|
||||
Toast.makeText(getActivity(), R.string.nnf_create_folder_error,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
tools:context=".FilePickerActivity">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/picker_toolbar"
|
||||
android:id="@+id/nnf_picker_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
android:theme="?nnf_toolbarTheme">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/current_dir"
|
||||
android:id="@+id/nnf_current_dir"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="start"
|
||||
|
|
@ -45,19 +45,19 @@
|
|||
android:id="@android:id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@+id/button_container"
|
||||
android:layout_below="@+id/picker_toolbar"
|
||||
tools:listitem="@layout/filepicker_listitem_dir" />
|
||||
android:layout_above="@+id/nnf_button_container"
|
||||
android:layout_below="@+id/nnf_picker_toolbar"
|
||||
tools:listitem="@layout/nnf_filepicker_listitem_dir" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_container"
|
||||
android:id="@+id/nnf_button_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_cancel"
|
||||
android:id="@+id/nnf_button_cancel"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
android:text="@android:string/cancel" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_ok"
|
||||
android:id="@+id/nnf_button_ok"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
- Added two base themes for convenience.
|
||||
- Now possible to specify a specific Toolbar-theme separate from the rest
|
||||
of your theme.
|
||||
- Now possible to override toolbar behaviour in the fragment.
|
||||
|
||||
# 2.1
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class DropboxFilePickerFragment
|
|||
|
||||
@Override
|
||||
public void onNewFolder(final String name) {
|
||||
File folder = new File(currentPath.path, name);
|
||||
File folder = new File(mCurrentPath.path, name);
|
||||
|
||||
if (folderCreator == null) {
|
||||
folderCreator = new FolderCreator();
|
||||
|
|
@ -147,13 +147,13 @@ public class DropboxFilePickerFragment
|
|||
|
||||
try {
|
||||
|
||||
if (!dbApi.metadata(currentPath.path, 1, null, false,
|
||||
if (!dbApi.metadata(mCurrentPath.path, 1, null, false,
|
||||
null).isDir) {
|
||||
currentPath = getRoot();
|
||||
mCurrentPath = getRoot();
|
||||
}
|
||||
|
||||
DropboxAPI.Entry dirEntry =
|
||||
dbApi.metadata(currentPath.path, 0, null, true,
|
||||
dbApi.metadata(mCurrentPath.path, 0, null, true,
|
||||
null);
|
||||
|
||||
files.beginBatchedUpdates();
|
||||
|
|
@ -179,8 +179,8 @@ public class DropboxFilePickerFragment
|
|||
protected void onStartLoading() {
|
||||
super.onStartLoading();
|
||||
|
||||
if (currentPath == null || !currentPath.isDir) {
|
||||
currentPath = getRoot();
|
||||
if (mCurrentPath == null || !mCurrentPath.isDir) {
|
||||
mCurrentPath = getRoot();
|
||||
}
|
||||
|
||||
forceLoad();
|
||||
|
|
@ -203,7 +203,7 @@ public class DropboxFilePickerFragment
|
|||
for (String path : paths) {
|
||||
try {
|
||||
dbApi.createFolder(path);
|
||||
currentPath = dbApi.metadata(path, 1, null, false, null);
|
||||
mCurrentPath = dbApi.metadata(path, 1, null, false, null);
|
||||
refresh();
|
||||
} catch (DropboxException e) {
|
||||
Toast.makeText(getActivity(), R.string.nnf_create_folder_error,
|
||||
|
|
|
|||
Loading…
Reference in New Issue