diff --git a/app/src/androidTest/java/com/veniosg/dir/test/acceptance/FileManagerActivityTest.java b/app/src/androidTest/java/com/veniosg/dir/test/acceptance/FileManagerActivityTest.java
index 6aaebf32..71c2f6dc 100644
--- a/app/src/androidTest/java/com/veniosg/dir/test/acceptance/FileManagerActivityTest.java
+++ b/app/src/androidTest/java/com/veniosg/dir/test/acceptance/FileManagerActivityTest.java
@@ -49,12 +49,14 @@ public class FileManagerActivityTest {
private final Android android = android(intentsRule);
private final File storageDir = Environment.getExternalStorageDirectory();
private final File testDirectory = new File(storageDir, "testDir");
+ private final File testEmptyDirectory = new File(testDirectory, "emptyDir");
private final File testChildFile = new File(testDirectory, "testChildFile");
@SuppressWarnings("ResultOfMethodCallIgnored")
@Before
public void setUp() throws Exception {
testDirectory.mkdir();
+ testEmptyDirectory.mkdir();
testChildFile.createNewFile();
}
@@ -96,6 +98,20 @@ public void launchesSearchForCurrentDirectory() throws Exception {
android.launched().searchIntentFor(testDirectory);
}
+ @Test
+ public void showsEmptyViewWhenDirectoryEmpty() throws Exception {
+ user.launches().viewWithFileScheme(testEmptyDirectory);
+
+ user.sees().emptyView();
+ }
+
+ @Test
+ public void doesNotShowEmptyViewWhenDirectoryHasItems() throws Exception {
+ user.launches().viewWithFileScheme(testDirectory);
+
+ user.cannotSee().emptyView();
+ }
+
@Test
@Ignore
public void filtersBasedOnMimetypeExtra() {
diff --git a/app/src/androidTest/java/com/veniosg/dir/test/actor/assertion/CannotSeeAssertions.java b/app/src/androidTest/java/com/veniosg/dir/test/actor/assertion/CannotSeeAssertions.java
index 0f4b49af..50b587c3 100644
--- a/app/src/androidTest/java/com/veniosg/dir/test/actor/assertion/CannotSeeAssertions.java
+++ b/app/src/androidTest/java/com/veniosg/dir/test/actor/assertion/CannotSeeAssertions.java
@@ -40,6 +40,10 @@ public void visibleSearchResult(File result) {
}
public void searchEmptyView() {
+ emptyView();
+ }
+
+ public void emptyView() {
onView(withId(R.id.empty_text))
.check(matches(not(isDisplayed())));
onView(withId(R.id.empty_img))
diff --git a/app/src/androidTest/java/com/veniosg/dir/test/actor/assertion/SeesAssertions.java b/app/src/androidTest/java/com/veniosg/dir/test/actor/assertion/SeesAssertions.java
index b735e079..99f23e14 100644
--- a/app/src/androidTest/java/com/veniosg/dir/test/actor/assertion/SeesAssertions.java
+++ b/app/src/androidTest/java/com/veniosg/dir/test/actor/assertion/SeesAssertions.java
@@ -77,6 +77,14 @@ public void searchEmptyView() {
viewWithId(R.id.empty_img);
}
+ public void emptyView() {
+ onView(allOf(
+ withId(R.id.empty_text),
+ withText("Folder empty")
+ )).check(matches(isDisplayed()));
+ viewWithId(R.id.empty_img);
+ }
+
private void viewWithId(@IdRes int id) {
onView(withId(id)).check(matches(isDisplayed()));
}
diff --git a/app/src/main/java/com/veniosg/dir/android/adapter/FileHolderListAdapter.java b/app/src/main/java/com/veniosg/dir/android/adapter/FileHolderListAdapter.java
index 8efc792b..4256fe74 100644
--- a/app/src/main/java/com/veniosg/dir/android/adapter/FileHolderListAdapter.java
+++ b/app/src/main/java/com/veniosg/dir/android/adapter/FileHolderListAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 George Venios
+ * Copyright (C) 2018 George Venios
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,47 +16,36 @@
package com.veniosg.dir.android.adapter;
-import android.content.Context;
import android.support.annotation.Nullable;
-import android.view.LayoutInflater;
-import android.view.View;
+import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
-import com.veniosg.dir.R;
+import com.veniosg.dir.android.adapter.viewholder.FileListViewHolder;
+import com.veniosg.dir.android.adapter.viewholder.FileListViewHolder.OnItemClickListener;
+import com.veniosg.dir.android.fragment.RecyclerViewFragment;
import com.veniosg.dir.mvvm.model.FileHolder;
-import com.veniosg.dir.android.ui.ViewHolder;
import java.util.List;
-import static com.nostra13.universalimageloader.core.ImageLoader.getInstance;
-import static com.veniosg.dir.android.misc.ThumbnailHelper.requestIcon;
-
-public class FileHolderListAdapter extends BaseAdapter {
+public class FileHolderListAdapter extends RecyclerView.Adapter
+ implements RecyclerViewFragment.ClickableAdapter {
private List mItems;
- private int mItemLayoutId = R.layout.item_filelist;
- private OnItemToggleListener mOnItemToggleListener;
+ private OnItemToggleListener mOnItemToggleListener;
+ private OnItemClickListener onItemClickListener;
public FileHolderListAdapter(List files){
mItems = files;
+ setHasStableIds(true);
}
@Override
- public boolean hasStableIds() {
- return true;
- }
-
- @Override
- public int getCount() {
+ public int getItemCount() {
return mItems.size();
}
- @Override
@Nullable
- public Object getItem(int position) {
+ public FileHolder getItem(int position) {
if (position < 0 || position >= mItems.size()) return null;
return mItems.get(position);
@@ -67,53 +56,15 @@ public long getItemId(int position) {
return position;
}
- /**
- * Set the layout to be used for item drawing.
- * @param resId The item layout id. 0 to reset.
- */
- public void setItemLayout(int resId){
- if(resId > 0)
- mItemLayoutId = resId;
- else
- mItemLayoutId = R.layout.item_filelist;
- }
-
- /**
- * Creates a new list item view, along with it's ViewHolder set as a tag.
- * @return The new view.
- */
- private View newView(Context context){
- View view = LayoutInflater.from(context).inflate(mItemLayoutId, null);
-
- ViewHolder holder = new ViewHolder();
- holder.icon = (ImageView) view.findViewById(R.id.icon);
- holder.primaryInfo = (TextView) view.findViewById(R.id.primary_info);
- holder.secondaryInfo = (TextView) view.findViewById(R.id.secondary_info);
- holder.tertiaryInfo = (TextView) view.findViewById(R.id.tertiary_info);
-
- view.setTag(holder);
- return view;
- }
+ @Override
+ public FileListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ return new FileListViewHolder(parent);
+ }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- FileHolder item = mItems.get(position);
- if(convertView == null)
- convertView = newView(parent.getContext());
- ViewHolder holder = (ViewHolder) convertView.getTag();
-
- getInstance().cancelDisplayTask(holder.icon);
- holder.icon.setImageDrawable(item.getBestIcon());
- holder.primaryInfo.setText(item.getName());
- holder.secondaryInfo.setText(item.getFormattedModificationDate(convertView.getContext()));
- // Hide directories' size as it's irrelevant if we can't recursively find it.
- holder.tertiaryInfo.setText(item.getFile().isDirectory()? "" : item.getFormattedSize(
- convertView.getContext(), false));
-
- requestIcon(item, holder.icon);
-
- return convertView;
- }
+ @Override
+ public void onBindViewHolder(FileListViewHolder holder, int position) {
+ holder.bind(getItem(position), onItemClickListener);
+ }
public OnItemToggleListener getOnItemToggleListener() {
return mOnItemToggleListener;
@@ -123,11 +74,12 @@ public void setOnItemToggleListener(OnItemToggleListener mOnItemToggleListener)
this.mOnItemToggleListener = mOnItemToggleListener;
}
- private boolean shouldLoadIcon(FileHolder item){
- return item.getFile().isFile() && !item.getMimeType().equals("video/mpeg");
- }
+ @Override
+ public void setOnItemClickListener(OnItemClickListener onClickListener) {
+ this.onItemClickListener = onClickListener;
+ }
public interface OnItemToggleListener {
- public void onItemToggle(int position);
+ void onItemToggle(int position);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/veniosg/dir/android/adapter/SearchListAdapter.java b/app/src/main/java/com/veniosg/dir/android/adapter/SearchListAdapter.java
index 5b3e07fc..3ed25748 100644
--- a/app/src/main/java/com/veniosg/dir/android/adapter/SearchListAdapter.java
+++ b/app/src/main/java/com/veniosg/dir/android/adapter/SearchListAdapter.java
@@ -20,7 +20,8 @@
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
-import com.veniosg.dir.android.adapter.FileListViewHolder.OnItemClickListener;
+import com.veniosg.dir.android.adapter.viewholder.FileListViewHolder.OnItemClickListener;
+import com.veniosg.dir.android.adapter.viewholder.SearchListViewHolder;
import java.util.List;
diff --git a/app/src/main/java/com/veniosg/dir/android/adapter/SearchListViewHolder.java b/app/src/main/java/com/veniosg/dir/android/adapter/SearchListViewHolder.java
deleted file mode 100644
index f86985f4..00000000
--- a/app/src/main/java/com/veniosg/dir/android/adapter/SearchListViewHolder.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.veniosg.dir.android.adapter;
-
-import android.view.ViewGroup;
-
-public class SearchListViewHolder extends FileListViewHolder {
- SearchListViewHolder(ViewGroup parent) {
- super(parent);
- }
-
- @Override
- void bind(String filePath, OnItemClickListener listener) {
- super.bind(filePath, listener);
- secondaryInfo.setText(filePath);
- }
-}
diff --git a/app/src/main/java/com/veniosg/dir/android/adapter/FileListViewHolder.java b/app/src/main/java/com/veniosg/dir/android/adapter/viewholder/FileListViewHolder.java
similarity index 53%
rename from app/src/main/java/com/veniosg/dir/android/adapter/FileListViewHolder.java
rename to app/src/main/java/com/veniosg/dir/android/adapter/viewholder/FileListViewHolder.java
index ba8943b3..e1a053e0 100644
--- a/app/src/main/java/com/veniosg/dir/android/adapter/FileListViewHolder.java
+++ b/app/src/main/java/com/veniosg/dir/android/adapter/viewholder/FileListViewHolder.java
@@ -1,4 +1,20 @@
-package com.veniosg.dir.android.adapter;
+/*
+ * Copyright (C) 2018 George Venios
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.veniosg.dir.android.adapter.viewholder;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
@@ -10,9 +26,8 @@
import com.veniosg.dir.R;
import com.veniosg.dir.mvvm.model.FileHolder;
-import java.io.File;
-
import static android.view.LayoutInflater.from;
+import static com.nostra13.universalimageloader.core.ImageLoader.getInstance;
import static com.veniosg.dir.android.misc.ThumbnailHelper.requestIcon;
import static com.veniosg.dir.android.ui.Themer.getThemedResourceId;
@@ -22,25 +37,26 @@ public class FileListViewHolder extends RecyclerView.ViewHolder {
TextView secondaryInfo;
private TextView tertiaryInfo;
- FileListViewHolder(ViewGroup parent) {
+ public FileListViewHolder(ViewGroup parent) {
super(from(parent.getContext()).inflate(R.layout.item_filelist, parent, false));
- icon = (ImageView) itemView.findViewById(R.id.icon);
- primaryInfo = (TextView) itemView.findViewById(R.id.primary_info);
- secondaryInfo = (TextView) itemView.findViewById(R.id.secondary_info);
- tertiaryInfo = (TextView) itemView.findViewById(R.id.tertiary_info);
+ icon = itemView.findViewById(R.id.icon);
+ primaryInfo = itemView.findViewById(R.id.primary_info);
+ secondaryInfo = itemView.findViewById(R.id.secondary_info);
+ tertiaryInfo = itemView.findViewById(R.id.tertiary_info);
int selectorRes = getThemedResourceId(parent.getContext(), android.R.attr.listChoiceBackgroundIndicator);
itemView.setBackgroundResource(selectorRes);
}
- void bind(String filePath, OnItemClickListener listener) {
+ public void bind(FileHolder item, OnItemClickListener listener) {
Context context = itemView.getContext();
- FileHolder item = new FileHolder(new File(filePath), context);
boolean isDirectory = item.getFile().isDirectory();
+ getInstance().cancelDisplayTask(icon);
primaryInfo.setText(item.getName());
secondaryInfo.setText(item.getFormattedModificationDate(context));
+ // Hide directories' size as it's irrelevant if we can't recursively find it.
tertiaryInfo.setText(isDirectory ? "" : item.getFormattedSize(context, false));
icon.setImageDrawable(item.getBestIcon());
requestIcon(item, icon);
@@ -49,6 +65,6 @@ void bind(String filePath, OnItemClickListener listener) {
}
public interface OnItemClickListener {
- public void onClick(View itemView, FileHolder item);
+ void onClick(View itemView, FileHolder item);
}
}
diff --git a/app/src/main/java/com/veniosg/dir/android/adapter/viewholder/SearchListViewHolder.java b/app/src/main/java/com/veniosg/dir/android/adapter/viewholder/SearchListViewHolder.java
new file mode 100644
index 00000000..1db8bd7f
--- /dev/null
+++ b/app/src/main/java/com/veniosg/dir/android/adapter/viewholder/SearchListViewHolder.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 George Venios
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.veniosg.dir.android.adapter.viewholder;
+
+import android.view.ViewGroup;
+
+import com.veniosg.dir.mvvm.model.FileHolder;
+
+import java.io.File;
+
+public class SearchListViewHolder extends FileListViewHolder {
+ public SearchListViewHolder(ViewGroup parent) {
+ super(parent);
+ }
+
+ public void bind(String filePath, OnItemClickListener listener) {
+ FileHolder fileHolder = new FileHolder(new File(filePath), itemView.getContext());
+ super.bind(fileHolder, listener);
+ secondaryInfo.setText(filePath);
+ }
+}
diff --git a/app/src/main/java/com/veniosg/dir/android/fragment/FileListFragment.java b/app/src/main/java/com/veniosg/dir/android/fragment/FileListFragment.java
index da458546..8d7f9461 100644
--- a/app/src/main/java/com/veniosg/dir/android/fragment/FileListFragment.java
+++ b/app/src/main/java/com/veniosg/dir/android/fragment/FileListFragment.java
@@ -33,14 +33,14 @@
import android.view.View;
import android.view.ViewGroup;
-import com.veniosg.dir.android.FileManagerApplication;
import com.veniosg.dir.R;
+import com.veniosg.dir.android.FileManagerApplication;
import com.veniosg.dir.android.adapter.FileHolderListAdapter;
-import com.veniosg.dir.mvvm.model.DirectoryHolder;
import com.veniosg.dir.android.misc.DirectoryScanner;
-import com.veniosg.dir.mvvm.model.FileHolder;
-import com.veniosg.dir.android.util.Logger;
import com.veniosg.dir.android.ui.widget.WaitingViewFlipper;
+import com.veniosg.dir.android.util.Logger;
+import com.veniosg.dir.mvvm.model.DirectoryHolder;
+import com.veniosg.dir.mvvm.model.FileHolder;
import java.io.File;
import java.util.ArrayList;
@@ -49,10 +49,11 @@
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.preference.PreferenceManager.getDefaultSharedPreferences;
import static android.support.v4.content.ContextCompat.checkSelfPermission;
-import static com.veniosg.dir.IntentConstants.*;
import static com.veniosg.dir.IntentConstants.ACTION_REFRESH_LIST;
import static com.veniosg.dir.IntentConstants.EXTRA_DIRECTORIES_ONLY;
import static com.veniosg.dir.IntentConstants.EXTRA_DIR_PATH;
+import static com.veniosg.dir.IntentConstants.EXTRA_FILENAME;
+import static com.veniosg.dir.IntentConstants.EXTRA_FILTER_FILETYPE;
import static com.veniosg.dir.IntentConstants.EXTRA_FILTER_MIMETYPE;
import static com.veniosg.dir.IntentConstants.EXTRA_WRITEABLE_ONLY;
import static com.veniosg.dir.android.fragment.PreferenceFragment.PREFS_THEME;
@@ -61,7 +62,7 @@
import static com.veniosg.dir.android.ui.widget.WaitingViewFlipper.PAGE_INDEX_PERMISSION_DENIED;
/**
- * An {@link AbsListFragment} that displays the contents of a directory.
+ * An {@link RecyclerViewFragment} that displays the contents of a directory.
*
* Clicks do nothing.
*
@@ -73,8 +74,7 @@
* Requests permissions if they're not granted.
*
*/
-public abstract class FileListFragment extends AbsListFragment {
-
+public abstract class FileListFragment extends RecyclerViewFragment {
private static final int REQUEST_CODE_STORAGE_PERMISSION = 0;
private static final String INSTANCE_STATE_PATH = "path";
private static final String INSTANCE_STATE_FILES = "files";
@@ -150,7 +150,7 @@ public void onDestroy() {
}
@Override
- public void onSaveInstanceState(Bundle outState) {
+ public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(INSTANCE_STATE_PATH, mPath);
@@ -159,12 +159,12 @@ public void onSaveInstanceState(Bundle outState) {
}
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_filelist, null);
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Set auto refresh on preference change.
@@ -172,10 +172,10 @@ public void onViewCreated(View view, Bundle savedInstanceState) {
.registerOnSharedPreferenceChangeListener(preferenceListener);
// Set list properties
- getListView().requestFocus();
- getListView().requestFocusFromTouch();
+ getRecyclerView().requestFocus();
+ getRecyclerView().requestFocusFromTouch();
- mFlipper = (WaitingViewFlipper) view.findViewById(R.id.flipper);
+ mFlipper = view.findViewById(R.id.flipper);
view.findViewById(R.id.empty_img).setOnClickListener(mEmptyViewClickListener);
view.findViewById(R.id.permissions_button).setOnClickListener(mRequestPermissionsListener);
@@ -303,9 +303,11 @@ public void handleMessage(Message msg) {
mFiles.addAll(c.listFile);
onDataReady();
+ // TODO Run a diff instead of updating everything
mAdapter.notifyDataSetChanged();
+ // TODO Scroll up, we had other content. Check if needed.
if (getView() != null) {
- getListView().setSelection(0);
+ getRecyclerView().setSelection(0);
}
showLoading(false);
onDataApplied();
diff --git a/app/src/main/java/com/veniosg/dir/android/fragment/PickFileListFragment.java b/app/src/main/java/com/veniosg/dir/android/fragment/PickFileListFragment.java
index 4c63c812..f9c949ef 100644
--- a/app/src/main/java/com/veniosg/dir/android/fragment/PickFileListFragment.java
+++ b/app/src/main/java/com/veniosg/dir/android/fragment/PickFileListFragment.java
@@ -20,6 +20,7 @@
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
+import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
@@ -44,7 +45,7 @@ public class PickFileListFragment extends SimpleFileListFragment {
private PickBar mPickBar;
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.fragment_filelist_pick, container, false);
}
@@ -56,7 +57,7 @@ public void onPrepareOptionsMenu(Menu menu) {
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewFlipper modeSelector = (ViewFlipper) view.findViewById(R.id.modeSelector);
@@ -95,16 +96,14 @@ public void pickRequested(String filename) {
}
}
- @Override
- public void onListItemClick(AbsListView l, View v, int position, long id) {
- FileHolder item = (FileHolder) mAdapter.getItem(position);
-
+ @Override
+ public void onListItemClick(View itemView, FileHolder item) {
if (item != null && item.getFile().isFile()) {
mPickBar.setText(item.getName());
} else {
- super.onListItemClick(l, v, position, id);
+ super.onListItemClick(itemView, item);
}
- }
+ }
/**
* Act upon picking.
diff --git a/app/src/main/java/com/veniosg/dir/android/fragment/AbsListFragment.java b/app/src/main/java/com/veniosg/dir/android/fragment/RecyclerViewFragment.java
similarity index 63%
rename from app/src/main/java/com/veniosg/dir/android/fragment/AbsListFragment.java
rename to app/src/main/java/com/veniosg/dir/android/fragment/RecyclerViewFragment.java
index 7d42c78a..54df8482 100644
--- a/app/src/main/java/com/veniosg/dir/android/fragment/AbsListFragment.java
+++ b/app/src/main/java/com/veniosg/dir/android/fragment/RecyclerViewFragment.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 The Android Open Source Project
- * Copyright (C) 2014 George Venios
+ * Copyright (C) 2018 George Venios
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,21 +20,22 @@
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
+import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
+import android.support.v7.widget.RecyclerView;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
-import android.widget.AbsListView;
-import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
-import android.widget.ListAdapter;
import android.widget.ProgressBar;
import android.widget.TextView;
-import com.veniosg.dir.android.ui.widget.DividerGridView;
+import com.veniosg.dir.android.adapter.viewholder.FileListViewHolder.OnItemClickListener;
+import com.veniosg.dir.android.ui.widget.DividerRecyclerView;
+import com.veniosg.dir.mvvm.model.FileHolder;
/**
* Static library support version of the framework's {@link android.app.ListFragment}.
@@ -43,7 +44,7 @@
* to switch to the framework's implementation. See the framework SDK
* documentation for a class overview.
*/
-public class AbsListFragment extends Fragment {
+public class RecyclerViewFragment extends Fragment {
static final int INTERNAL_EMPTY_ID = 0x00ff0001;
static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002;
static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003;
@@ -56,33 +57,61 @@ public void run() {
}
};
- final private AdapterView.OnItemClickListener mOnClickListener
- = new AdapterView.OnItemClickListener() {
- public void onItemClick(AdapterView> parent, View v, int position, long id) {
- onListItemClick((AbsListView)parent, v, position, id);
- }
- };
+ final private OnItemClickListener mOnClickListener = this::onListItemClick;
- ListAdapter mAdapter;
- AbsListView mList;
- View mEmptyView;
+ RecyclerView.Adapter mAdapter;
+ RecyclerView mList;
+ View mCustomEmptyView;
TextView mStandardEmptyView;
View mProgressContainer;
View mListContainer;
CharSequence mEmptyText;
+ View mEmptyView;
boolean mListShown;
+ private final RecyclerView.AdapterDataObserver mEmptyViewUpdatingObserver = new RecyclerView.AdapterDataObserver() {
+ @Override
+ public void onChanged() {
+ super.onChanged();
+ ensureEmptyView(true);
+ }
+
+ @Override
+ public void onItemRangeChanged(int positionStart, int itemCount) {
+ onChanged();
+ }
+
+ @Override
+ public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
+ onChanged();
+ }
+
+ @Override
+ public void onItemRangeInserted(int positionStart, int itemCount) {
+ onChanged();
+ }
+
+ @Override
+ public void onItemRangeRemoved(int positionStart, int itemCount) {
+ onChanged();
+ }
+
+ @Override
+ public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
+ onChanged();
+ }
+ };
- public AbsListFragment() {
+ public RecyclerViewFragment() {
}
/**
* Provide default implementation to return a simple list view. Subclasses
* can override to replace with their own layout. If doing so, the
- * returned view hierarchy must have a AbsListView whose id
+ * returned view hierarchy must have a RecyclerView whose id
* is {@link android.R.id#list android.R.id.list} and can optionally
* have a sibling view id {@link android.R.id#empty android.R.id.empty}
* that is to be shown when the list is empty.
- *
+ *
*
If you are overriding this method with your own custom content,
* consider including the standard layout {@link android.R.layout#list_content}
* in your layout file, so that you continue to retain all of the standard
@@ -90,7 +119,7 @@ public AbsListFragment() {
* way to have the built-in indeterminant progress state be shown.
*/
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final Context context = getActivity();
@@ -110,7 +139,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
root.addView(pframe, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
// ------------------------------------------------------------------
@@ -121,21 +150,20 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
tv.setId(INTERNAL_EMPTY_ID);
tv.setGravity(Gravity.CENTER);
lframe.addView(tv, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
- AbsListView lv = new DividerGridView(getActivity());
+ RecyclerView lv = new DividerRecyclerView(getActivity());
lv.setId(android.R.id.list);
- lv.setDrawSelectorOnTop(false);
lframe.addView(lv, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
root.addView(lframe, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
// ------------------------------------------------------------------
root.setLayoutParams(new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
return root;
}
@@ -144,7 +172,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
* Attach to list view once the view hierarchy has been created.
*/
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ensureList();
}
@@ -157,7 +185,7 @@ public void onDestroyView() {
mHandler.removeCallbacks(mRequestFocus);
mList = null;
mListShown = false;
- mEmptyView = mProgressContainer = mListContainer = null;
+ mCustomEmptyView = mProgressContainer = mListContainer = null;
mStandardEmptyView = null;
super.onDestroyView();
}
@@ -165,70 +193,73 @@ public void onDestroyView() {
/**
* This method will be called when an item in the list is selected.
* Subclasses should override. Subclasses can call
- * getListView().getItemAtPosition(position) if they need to access the
+ * getRecyclerView().getItemAtPosition(position) if they need to access the
* data associated with the selected item.
*
- * @param l The AbsListView where the click happened
- * @param v The view that was clicked within the AbsListView
- * @param position The position of the view in the list
- * @param id The row id of the item that was clicked
+ * @param itemView The view that was clicked within the RecyclerView
+ * @param item The data item represented by itemView
*/
- public void onListItemClick(AbsListView l, View v, int position, long id) {
+ public void onListItemClick(View itemView, FileHolder item) {
}
/**
* Provide the cursor for the list view.
*/
- public void setListAdapter(ListAdapter adapter) {
+ public void setListAdapter(@NonNull RecyclerView.Adapter adapter) {
boolean hadAdapter = mAdapter != null;
+ if (hadAdapter) {
+ mAdapter.unregisterAdapterDataObserver(mEmptyViewUpdatingObserver);
+ }
mAdapter = adapter;
if (mList != null) {
mList.setAdapter(adapter);
+ boolean shouldAnimate = getView() != null && getView().getWindowToken() != null;
if (!mListShown && !hadAdapter) {
// The list was hidden, and previously didn't have an
- // adapter. It is now time to show it.
- setListShown(true, getView().getWindowToken() != null);
+ // adapter. It is now time to show it.
+ setListShown(true, shouldAnimate);
+ } else {
+ ensureEmptyView(shouldAnimate);
}
}
+ mAdapter.registerAdapterDataObserver(mEmptyViewUpdatingObserver);
}
- /**
- * Set the currently selected list item to the specified
- * position with the adapter's data
- *
- * @param position
- */
- public void setSelection(int position) {
- ensureList();
- mList.setSelection(position);
- }
-
- /**
- * Get the position of the currently selected list item.
- */
- public int getSelectedItemPosition() {
- ensureList();
- return mList.getSelectedItemPosition();
- }
+ private void ensureEmptyView(boolean animate) {
+ boolean hideEmpty = false;
+ if (mAdapter != null) {
+ hideEmpty = !mListShown || mAdapter.getItemCount() > 0;
+ }
- /**
- * Get the cursor row ID of the currently selected list item.
- */
- public long getSelectedItemId() {
- ensureList();
- return mList.getSelectedItemId();
+ if (hideEmpty) {
+ if (animate) {
+ mEmptyView.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_out));
+ } else {
+ mEmptyView.clearAnimation();
+ }
+ mEmptyView.setVisibility(View.GONE);
+ } else {
+ if (animate) {
+ mEmptyView.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_in));
+ } else {
+ mEmptyView.clearAnimation();
+ }
+ mEmptyView.setVisibility(View.VISIBLE);
+ }
}
/**
* Get the activity's list view widget.
*/
- public AbsListView getListView() {
+ public RecyclerView getRecyclerView() {
ensureList();
return mList;
}
/**
- * The default content for a ListFragment has a TextView that can
+ * The default content for a RecyclerViewFragment has a TextView that can
* be shown when the list is empty. If you would like to have it
* shown, call this method to supply the text it should use.
*/
@@ -239,7 +270,7 @@ public void setEmptyText(CharSequence text) {
}
mStandardEmptyView.setText(text);
if (mEmptyText == null) {
- mList.setEmptyView(mStandardEmptyView);
+ setEmptyView(mStandardEmptyView);
}
mEmptyText = text;
}
@@ -248,15 +279,15 @@ public void setEmptyText(CharSequence text) {
* Control whether the list is being displayed. You can make it not
* displayed if you are waiting for the initial data to show in it. During
* this time an indeterminant progress indicator will be shown instead.
- *
+ *
*
Applications do not normally need to use this themselves. The default
* behavior of ListFragment is to start with the list not being shown, only
- * showing it once an adapter is given with {@link #setListAdapter(ListAdapter)}.
+ * showing it once an adapter is given with {@link #setListAdapter(RecyclerView.Adapter)}.
* If the list at that point had not been shown, when it does get shown
* it will be do without the user ever seeing the hidden state.
*
* @param shown If true, the list view is shown; if false, the progress
- * indicator. The initial value is true.
+ * indicator. The initial value is true.
*/
public void setListShown(boolean shown) {
setListShown(shown, true);
@@ -275,10 +306,10 @@ public void setListShownNoAnimation(boolean shown) {
* displayed if you are waiting for the initial data to show in it. During
* this time an indeterminant progress indicator will be shown instead.
*
- * @param shown If true, the list view is shown; if false, the progress
- * indicator. The initial value is true.
+ * @param shown If true, the list view is shown; if false, the progress
+ * indicator. The initial value is true.
* @param animate If true, an animation will be used to transition to the
- * new state.
+ * new state.
*/
private void setListShown(boolean shown, boolean animate) {
ensureList();
@@ -314,12 +345,13 @@ private void setListShown(boolean shown, boolean animate) {
mProgressContainer.setVisibility(View.VISIBLE);
mListContainer.setVisibility(View.GONE);
}
+ ensureEmptyView(animate);
}
/**
- * Get the ListAdapter associated with this activity's AbsListView.
+ * Get the RecyclerView.Adapter associated with this activity's RecyclerView.
*/
- public ListAdapter getListAdapter() {
+ public RecyclerView.Adapter getListAdapter() {
return mAdapter;
}
@@ -331,42 +363,44 @@ private void ensureList() {
if (root == null) {
throw new IllegalStateException("Content view not yet created");
}
- if (root instanceof AbsListView) {
- mList = (AbsListView)root;
+ if (root instanceof RecyclerView) {
+ mList = (RecyclerView) root;
} else {
- mStandardEmptyView = (TextView)root.findViewById(INTERNAL_EMPTY_ID);
+ mStandardEmptyView = (TextView) root.findViewById(INTERNAL_EMPTY_ID);
if (mStandardEmptyView == null) {
- mEmptyView = root.findViewById(android.R.id.empty);
+ mCustomEmptyView = root.findViewById(android.R.id.empty);
} else {
mStandardEmptyView.setVisibility(View.GONE);
}
mProgressContainer = root.findViewById(INTERNAL_PROGRESS_CONTAINER_ID);
mListContainer = root.findViewById(INTERNAL_LIST_CONTAINER_ID);
- View rawAbsListView = root.findViewById(android.R.id.list);
- if (!(rawAbsListView instanceof AbsListView)) {
- if (rawAbsListView == null) {
+ View rawRecyclerView = root.findViewById(android.R.id.list);
+ if (!(rawRecyclerView instanceof RecyclerView)) {
+ if (rawRecyclerView == null) {
throw new RuntimeException(
- "Your content must have a AbsListView whose id attribute is " +
+ "Your content must have a RecyclerView whose id attribute is " +
"'android.R.id.list'");
}
throw new RuntimeException(
"Content has view with id attribute 'android.R.id.list' "
- + "that is not a AbsListView class");
+ + "that is not a RecyclerView class");
}
- mList = (AbsListView)rawAbsListView;
- if (mEmptyView != null) {
- mList.setEmptyView(mEmptyView);
+ mList = (RecyclerView) rawRecyclerView;
+ if (mCustomEmptyView != null) {
+ setEmptyView(mCustomEmptyView);
} else if (mEmptyText != null) {
mStandardEmptyView.setText(mEmptyText);
- mList.setEmptyView(mStandardEmptyView);
+ setEmptyView(mStandardEmptyView);
}
}
mListShown = true;
- mList.setOnItemClickListener(mOnClickListener);
if (mAdapter != null) {
- ListAdapter adapter = mAdapter;
+ RecyclerView.Adapter adapter = mAdapter;
mAdapter = null;
setListAdapter(adapter);
+ if (adapter instanceof ClickableAdapter) {
+ ((ClickableAdapter) adapter).setOnItemClickListener(mOnClickListener);
+ }
} else {
// We are starting without an adapter, so assume we won't
// have our data right away and start with the progress indicator.
@@ -376,4 +410,18 @@ private void ensureList() {
}
mHandler.post(mRequestFocus);
}
+
+ private void setEmptyView(View emptyView) {
+ if (emptyView != mEmptyView) {
+ if (mEmptyView != null) {
+ mEmptyView.setVisibility(View.GONE);
+ }
+ }
+ mEmptyView = emptyView;
+ ensureEmptyView(false);
+ }
+
+ public interface ClickableAdapter {
+ void setOnItemClickListener(OnItemClickListener onClickListener);
+ }
}
diff --git a/app/src/main/java/com/veniosg/dir/android/fragment/SearchListFragment.java b/app/src/main/java/com/veniosg/dir/android/fragment/SearchListFragment.java
index e8368fb3..f3c43e28 100644
--- a/app/src/main/java/com/veniosg/dir/android/fragment/SearchListFragment.java
+++ b/app/src/main/java/com/veniosg/dir/android/fragment/SearchListFragment.java
@@ -35,7 +35,7 @@
import com.veniosg.dir.R;
import com.veniosg.dir.android.activity.FileManagerActivity;
-import com.veniosg.dir.android.adapter.FileListViewHolder.OnItemClickListener;
+import com.veniosg.dir.android.adapter.viewholder.FileListViewHolder.OnItemClickListener;
import com.veniosg.dir.android.adapter.SearchListAdapter;
import com.veniosg.dir.android.util.Logger;
import com.veniosg.dir.android.ui.widget.WaitingViewFlipper;
diff --git a/app/src/main/java/com/veniosg/dir/android/fragment/SideNavFragment.java b/app/src/main/java/com/veniosg/dir/android/fragment/SideNavFragment.java
index 34ae8332..61b91bbf 100644
--- a/app/src/main/java/com/veniosg/dir/android/fragment/SideNavFragment.java
+++ b/app/src/main/java/com/veniosg/dir/android/fragment/SideNavFragment.java
@@ -19,6 +19,7 @@
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
+import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
@@ -29,7 +30,6 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
-import android.widget.GridView;
import android.widget.ListView;
import android.widget.TextView;
@@ -46,41 +46,34 @@
import static com.veniosg.dir.android.ui.Themer.getThemedResourceId;
import static com.veniosg.dir.android.ui.Themer.setStatusBarColour;
-public class SideNavFragment extends AbsListFragment implements LoaderManager.LoaderCallbacks {
+public class SideNavFragment extends RecyclerViewFragment
+ implements LoaderManager.LoaderCallbacks {
private WaitingViewFlipper mFlipper;
- private View.OnClickListener mSettingsClickListener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(getActivity(), PreferenceActivity.class);
- startActivity(intent);
- }
+ private View.OnClickListener mSettingsClickListener = v -> {
+ Intent intent = new Intent(getActivity(), PreferenceActivity.class);
+ startActivity(intent);
};
- private View.OnClickListener mAboutClickListener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(getActivity(), AboutActivity.class);
- startActivity(intent);
- }
+ private View.OnClickListener mAboutClickListener = v -> {
+ Intent intent = new Intent(getActivity(), AboutActivity.class);
+ startActivity(intent);
};
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_drawer, null);
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
- mFlipper = (WaitingViewFlipper) view.findViewById(R.id.flipper);
+ mFlipper = view.findViewById(R.id.flipper);
setLoading(true);
view.findViewById(R.id.empty_img).setVisibility(GONE);
((TextView) view.findViewById(R.id.empty_text)).setText(R.string.bookmark_empty);
- if (getListView() instanceof GridView) {
- ((GridView) getListView()).setNumColumns(1);
- }
setListAdapter(new BookmarkListAdapter(getActivity(), null));
setListChoiceListener();
view.setBackgroundResource(getThemedResourceId(getActivity(), android.R.attr.colorBackground));
@@ -91,7 +84,7 @@ public void onViewCreated(View view, Bundle savedInstanceState) {
}
@Override
- public void onListItemClick(AbsListView l, View v, int position, long id) {
+ public void onListItemClick(View itemView, int position, long id) {
Cursor c = ((Cursor) getListAdapter().getItem(position));
((BookmarkContract) getActivity()).onBookmarkSelected(c.getString(
c.getColumnIndex(BookmarkProvider.PATH)));
@@ -109,13 +102,13 @@ void setLoading(boolean loading) {
}
private void setListChoiceListener() {
- getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
+ getRecyclerView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
@Override
public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
menu.clear();
mode.getMenuInflater().inflate(R.menu.cab_bookmarks, menu);
- if (getListView().getCheckedItemCount() != 1) {
+ if (getRecyclerView().getCheckedItemCount() != 1) {
menu.removeItem(R.id.menu_open_parent);
}
return true;
@@ -136,9 +129,9 @@ public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_delete:
- long[] ids = getListView().getCheckedItemIds();
+ long[] ids = getRecyclerView().getCheckedItemIds();
for (long id : ids) {
- getListView().getContext().getContentResolver().delete(BookmarkProvider.CONTENT_URI,
+ getRecyclerView().getContext().getContentResolver().delete(BookmarkProvider.CONTENT_URI,
BookmarkProvider._ID + "=?", new String[]{"" + id});
}
mode.finish();
@@ -146,8 +139,8 @@ public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item)
case R.id.menu_open_parent:
int pos = 0;
- SparseBooleanArray checked = getListView().getCheckedItemPositions();
- for (int i = 0; i < getListView().getCount(); i++) {
+ SparseBooleanArray checked = getRecyclerView().getCheckedItemPositions();
+ for (int i = 0; i < getRecyclerView().getCount(); i++) {
if (checked.get(i)) {
pos = i;
}
@@ -165,16 +158,16 @@ public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item)
@Override
public void onItemCheckedStateChanged(android.view.ActionMode mode,
int position, long id, boolean checked) {
- if (getListView().getCheckedItemCount() != 0) {
+ if (getRecyclerView().getCheckedItemCount() != 0) {
- mode.setTitle(getListView().getCheckedItemCount() + " " + getString(R.string.selected));
+ mode.setTitle(getRecyclerView().getCheckedItemCount() + " " + getString(R.string.selected));
// Force actions' refresh
mode.invalidate();
}
}
});
- getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ getRecyclerView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
}
@Override
diff --git a/app/src/main/java/com/veniosg/dir/android/fragment/SimpleFileListFragment.java b/app/src/main/java/com/veniosg/dir/android/fragment/SimpleFileListFragment.java
index 9aeeb906..4e6f9f97 100644
--- a/app/src/main/java/com/veniosg/dir/android/fragment/SimpleFileListFragment.java
+++ b/app/src/main/java/com/veniosg/dir/android/fragment/SimpleFileListFragment.java
@@ -25,6 +25,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
+import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.view.ActionMode;
import android.view.LayoutInflater;
@@ -97,10 +98,10 @@ public class SimpleFileListFragment extends FileListFragment {
@Override
public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
- if (getView() == null) return false; // Prevent crash from getListView()'s ensureList().
+ if (getView() == null) return false; // Prevent crash from getRecyclerView()'s ensureList().
menu.clear();
- switch (getListView().getCheckedItemCount()) {
+ switch (getRecyclerView().getCheckedItemCount()) {
// Single selection
case 1:
FileHolder fHolder = (FileHolder) getListAdapter().getItem(getCheckedItemPosition());
@@ -158,12 +159,12 @@ public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
@Override
public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.menu_select_all) {
- for (int i = 0; i < getListView().getCount(); i++)
- getListView().setItemChecked(i, true);
+ for (int i = 0; i < getRecyclerView().getCount(); i++)
+ getRecyclerView().setItemChecked(i, true);
return true;
}
- switch (getListView().getCheckedItemCount()) {
+ switch (getRecyclerView().getCheckedItemCount()) {
// Single selection
case 1:
return handleSingleSelectionAction(mode, item);
@@ -176,8 +177,8 @@ public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item)
@Override
public void onItemCheckedStateChanged(android.view.ActionMode mode,
int position, long id, boolean checked) {
- if (getListView().getCheckedItemCount() != 0) {
- mode.setTitle(getListView().getCheckedItemCount() + " "
+ if (getRecyclerView().getCheckedItemCount() != 0) {
+ mode.setTitle(getRecyclerView().getCheckedItemCount() + " "
+ getString(R.string.selected));
// Force actions' refresh
@@ -188,8 +189,8 @@ public void onItemCheckedStateChanged(android.view.ActionMode mode,
private FileHolderListAdapter.OnItemToggleListener mOnItemToggleListener = new FileHolderListAdapter.OnItemToggleListener() {
@Override
public void onItemToggle(int position) {
- getListView().setItemChecked(position,
- !Utils.getItemChecked(getListView(), position));
+ getRecyclerView().setItemChecked(position,
+ !Utils.getItemChecked(getRecyclerView(), position));
}
};
private ActivityProvider mActivityProvider = new ActivityProvider() {
@@ -372,12 +373,12 @@ private void addBookmark(File file) {
}
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_filelist_simple, container, false);
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// We expect the pathbar to add the bottom shadow in this case
@@ -417,8 +418,8 @@ public void directoryChanged(File newCurrentDir) {
private void initContextualActions() {
if (mActionsEnabled) {
- getListView().setMultiChoiceModeListener(mMultiChoiceModeListener);
- getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ getRecyclerView().setMultiChoiceModeListener(mMultiChoiceModeListener);
+ getRecyclerView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
((FileHolderListAdapter) getListAdapter()).setOnItemToggleListener(mOnItemToggleListener);
setHasOptionsMenu(true);
@@ -426,10 +427,9 @@ private void initContextualActions() {
}
@Override
- public void onListItemClick(AbsListView l, View v, int position, long id) {
- FileHolder item = (FileHolder) mAdapter.getItem(position);
+ public void onListItemClick(View itemView, FileHolder item) {
if (item != null) {
- heroView = v;
+ heroView = itemView;
openInformingPathBar(item);
heroView = null;
}
@@ -692,18 +692,18 @@ void inflateMultipleChoiceMenu(MenuInflater menuInflater, Menu menu) {
* @return
*/
int getCheckedItemPosition() {
- return (int) getListView().getCheckedItemIds()[0];
+ return (int) getRecyclerView().getCheckedItemIds()[0];
}
private void useFolderScroll(final ScrollPosition pos) {
if (getView() != null) {
- Utils.scrollToPosition(getListView(), pos, false);
+ Utils.scrollToPosition(getRecyclerView(), pos, false);
}
}
private void keepFolderScroll() {
- int firstVisiblePosition = getListView().getFirstVisiblePosition();
- View firstVisibleChild = getListView().getChildAt(0);
+ int firstVisiblePosition = getRecyclerView().getFirstVisiblePosition();
+ View firstVisibleChild = getRecyclerView().getChildAt(0);
if (firstVisibleChild != null) {
sScrollPositions.put(getPath(), new ScrollPosition(firstVisiblePosition,
@@ -717,7 +717,7 @@ private void keepFolderScroll() {
private ArrayList getCheckedItems() {
ArrayList items = new ArrayList();
- for (long pos : getListView().getCheckedItemIds()) {
+ for (long pos : getRecyclerView().getCheckedItemIds()) {
FileHolder item = (FileHolder) getListAdapter().getItem((int) pos);
if (item != null) items.add(item);
}
diff --git a/app/src/main/java/com/veniosg/dir/android/ui/widget/DividerGridView.java b/app/src/main/java/com/veniosg/dir/android/ui/widget/DividerRecyclerView.java
similarity index 89%
rename from app/src/main/java/com/veniosg/dir/android/ui/widget/DividerGridView.java
rename to app/src/main/java/com/veniosg/dir/android/ui/widget/DividerRecyclerView.java
index 23e45c12..bc373267 100644
--- a/app/src/main/java/com/veniosg/dir/android/ui/widget/DividerGridView.java
+++ b/app/src/main/java/com/veniosg/dir/android/ui/widget/DividerRecyclerView.java
@@ -20,28 +20,28 @@
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
-import android.widget.GridView;
import static android.R.attr.listDivider;
import static com.veniosg.dir.android.ui.Themer.getThemedResourceId;
-public class DividerGridView extends GridView {
+public class DividerRecyclerView extends RecyclerView {
private int mDividerSize;
private Drawable mDivider;
- public DividerGridView(Context context) {
+ public DividerRecyclerView(Context context) {
super(context);
init(context);
}
- public DividerGridView(Context context, AttributeSet attrs) {
+ public DividerRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
- public DividerGridView(Context context, AttributeSet attrs, int defStyle) {
+ public DividerRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
@@ -54,6 +54,7 @@ private void init(Context context) {
@Override
protected void dispatchDraw(Canvas canvas) {
+ // TODO move this to default item decoration
double count = getChildCount();
int bottom, top, right;
int numColumns = getNumColumns();
diff --git a/app/src/main/res/layout/fragment_filelist.xml b/app/src/main/res/layout/fragment_filelist.xml
index d88530f1..02a8d673 100644
--- a/app/src/main/res/layout/fragment_filelist.xml
+++ b/app/src/main/res/layout/fragment_filelist.xml
@@ -30,7 +30,7 @@
android:orientation="vertical">
-