Recents in create, uniform item layouts.
Show recent directories in a separate fragment, and save as serialized
versions of new DirectoryStack. Cleaner behavior around recents and
search, instead of treating them as pseudo-Documents.
More uniform item layouts between list and grid, including both date
and size information, and originating storage root in recents. Avoid
clashing directory loaders by assigning unique numbers. Promote
list/grid switching up into activity.
Change-Id: I9a93460b896067ca036d7e772eeabde31face2e1
diff --git a/src/com/android/documentsui/DirectoryFragment.java b/src/com/android/documentsui/DirectoryFragment.java
index 1443f26..d986a51 100644
--- a/src/com/android/documentsui/DirectoryFragment.java
+++ b/src/com/android/documentsui/DirectoryFragment.java
@@ -26,11 +26,12 @@
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.text.format.DateUtils;
+import android.text.format.Formatter;
+import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@@ -46,20 +47,21 @@
import com.android.documentsui.DocumentsActivity.DisplayState;
import com.android.documentsui.model.Document;
+import com.android.documentsui.model.Root;
import com.android.internal.util.Predicate;
import com.google.android.collect.Lists;
+import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* Display the documents inside a single directory.
*/
public class DirectoryFragment extends Fragment {
- // TODO: show storage backend in item views when requested
-
private ListView mListView;
private GridView mGridView;
@@ -68,19 +70,35 @@
public static final int TYPE_NORMAL = 1;
public static final int TYPE_SEARCH = 2;
public static final int TYPE_RECENT_OPEN = 3;
- public static final int TYPE_RECENT_CREATE = 4;
private int mType = TYPE_NORMAL;
private DocumentsAdapter mAdapter;
private LoaderCallbacks<List<Document>> mCallbacks;
+ private static final String EXTRA_TYPE = "type";
private static final String EXTRA_URI = "uri";
- private static final int LOADER_DOCUMENTS = 2;
+ private static AtomicInteger sLoaderId = new AtomicInteger(4000);
- public static void show(FragmentManager fm, Uri uri) {
+ private final int mLoaderId = sLoaderId.incrementAndGet();
+
+ public static void showNormal(FragmentManager fm, Uri uri) {
+ show(fm, TYPE_NORMAL, uri);
+ }
+
+ public static void showSearch(FragmentManager fm, Uri uri, String query) {
+ final Uri searchUri = DocumentsContract.buildSearchUri(uri, query);
+ show(fm, TYPE_SEARCH, searchUri);
+ }
+
+ public static void showRecentsOpen(FragmentManager fm) {
+ show(fm, TYPE_RECENT_OPEN, null);
+ }
+
+ private static void show(FragmentManager fm, int type, Uri uri) {
final Bundle args = new Bundle();
+ args.putInt(EXTRA_TYPE, type);
args.putParcelable(EXTRA_URI, uri);
final DirectoryFragment fragment = new DirectoryFragment();
@@ -97,12 +115,6 @@
}
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setHasOptionsMenu(true);
- }
-
- @Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final Context context = inflater.getContext();
@@ -118,19 +130,9 @@
mGridView.setMultiChoiceModeListener(mMultiListener);
mAdapter = new DocumentsAdapter();
- updateMode();
final Uri uri = getArguments().getParcelable(EXTRA_URI);
-
- if (uri.getQueryParameter(DocumentsContract.PARAM_QUERY) != null) {
- mType = TYPE_SEARCH;
- } else if (RecentsProvider.buildRecentOpen().equals(uri)) {
- mType = TYPE_RECENT_OPEN;
- } else if (RecentsProvider.buildRecentCreate().equals(uri)) {
- mType = TYPE_RECENT_CREATE;
- } else {
- mType = TYPE_NORMAL;
- }
+ mType = getArguments().getInt(EXTRA_TYPE);
mCallbacks = new LoaderCallbacks<List<Document>>() {
@Override
@@ -140,6 +142,8 @@
final Uri contentsUri;
if (mType == TYPE_NORMAL) {
contentsUri = DocumentsContract.buildContentsUri(uri);
+ } else if (mType == TYPE_RECENT_OPEN) {
+ contentsUri = RecentsProvider.buildRecentOpen();
} else {
contentsUri = uri;
}
@@ -147,8 +151,7 @@
final Predicate<Document> filter = new MimePredicate(state.acceptMimes);
final Comparator<Document> sortOrder;
- if (state.sortOrder == DisplayState.SORT_ORDER_DATE || mType == TYPE_RECENT_OPEN
- || mType == TYPE_RECENT_CREATE) {
+ if (state.sortOrder == DisplayState.SORT_ORDER_DATE || mType == TYPE_RECENT_OPEN) {
sortOrder = new Document.DateComparator();
} else if (state.sortOrder == DisplayState.SORT_ORDER_NAME) {
sortOrder = new Document.NameComparator();
@@ -170,56 +173,30 @@
}
};
+ updateDisplayState();
+
return view;
}
@Override
public void onStart() {
super.onStart();
- getLoaderManager().restartLoader(LOADER_DOCUMENTS, getArguments(), mCallbacks);
+ getLoaderManager().restartLoader(mLoaderId, getArguments(), mCallbacks);
}
@Override
public void onStop() {
super.onStop();
- getLoaderManager().destroyLoader(LOADER_DOCUMENTS);
+ getLoaderManager().destroyLoader(mLoaderId);
}
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- super.onCreateOptionsMenu(menu, inflater);
- inflater.inflate(R.menu.directory, menu);
- }
-
- @Override
- public void onPrepareOptionsMenu(Menu menu) {
- super.onPrepareOptionsMenu(menu);
+ public void updateDisplayState() {
final DisplayState state = getDisplayState(this);
- menu.findItem(R.id.menu_grid).setVisible(state.mode != DisplayState.MODE_GRID);
- menu.findItem(R.id.menu_list).setVisible(state.mode != DisplayState.MODE_LIST);
- }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- final DisplayState state = getDisplayState(this);
- final int id = item.getItemId();
- if (id == R.id.menu_grid) {
- state.mode = DisplayState.MODE_GRID;
- updateMode();
- getFragmentManager().invalidateOptionsMenu();
- return true;
- } else if (id == R.id.menu_list) {
- state.mode = DisplayState.MODE_LIST;
- updateMode();
- getFragmentManager().invalidateOptionsMenu();
- return true;
- } else {
- return super.onOptionsItemSelected(item);
- }
- }
-
- private void updateMode() {
- final DisplayState state = getDisplayState(this);
+ // TODO: avoid kicking loader when sort didn't change
+ getLoaderManager().restartLoader(mLoaderId, getArguments(), mCallbacks);
+ mListView.smoothScrollToPosition(0);
+ mGridView.smoothScrollToPosition(0);
mListView.setVisibility(state.mode == DisplayState.MODE_LIST ? View.VISIBLE : View.GONE);
mGridView.setVisibility(state.mode == DisplayState.MODE_GRID ? View.VISIBLE : View.GONE);
@@ -250,12 +227,6 @@
}
}
- public void updateSortOrder() {
- getLoaderManager().restartLoader(LOADER_DOCUMENTS, getArguments(), mCallbacks);
- mListView.smoothScrollToPosition(0);
- mGridView.smoothScrollToPosition(0);
- }
-
private OnItemClickListener mItemListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
@@ -309,7 +280,7 @@
if (checked) {
// Directories cannot be checked
final Document doc = mAdapter.getItem(position);
- if (DocumentsContract.MIME_TYPE_DIRECTORY.equals(doc.mimeType)) {
+ if (doc.isDirectory()) {
mCurrentView.setItemChecked(position, false);
}
}
@@ -337,10 +308,10 @@
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final Context context = parent.getContext();
+ final DisplayState state = getDisplayState(DirectoryFragment.this);
if (convertView == null) {
final LayoutInflater inflater = LayoutInflater.from(context);
- final DisplayState state = getDisplayState(DirectoryFragment.this);
if (state.mode == DisplayState.MODE_LIST) {
convertView = inflater.inflate(R.layout.item_doc_list, parent, false);
} else if (state.mode == DisplayState.MODE_GRID) {
@@ -352,9 +323,12 @@
final Document doc = getItem(position);
- final TextView title = (TextView) convertView.findViewById(android.R.id.title);
- final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
+ final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+ final ImageView icon1 = (ImageView) convertView.findViewById(android.R.id.icon1);
+ final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
+ final TextView date = (TextView) convertView.findViewById(R.id.date);
+ final TextView size = (TextView) convertView.findViewById(R.id.size);
if (doc.isThumbnailSupported()) {
// TODO: load thumbnails async
@@ -365,8 +339,37 @@
}
title.setText(doc.displayName);
- if (summary != null) {
- summary.setText(DateUtils.getRelativeTimeSpanString(doc.lastModified));
+
+ if (mType == TYPE_NORMAL || mType == TYPE_SEARCH) {
+ icon1.setVisibility(View.GONE);
+ if (doc.summary != null) {
+ summary.setText(doc.summary);
+ summary.setVisibility(View.VISIBLE);
+ } else {
+ summary.setVisibility(View.INVISIBLE);
+ }
+ } else if (mType == TYPE_RECENT_OPEN) {
+ final Root root = RootsCache.findRoot(context, doc);
+ icon1.setVisibility(View.VISIBLE);
+ icon1.setImageDrawable(root.icon);
+ summary.setText(root.getDirectoryString());
+ summary.setVisibility(View.VISIBLE);
+ }
+
+ // TODO: omit year from format
+ date.setText(DateUtils.formatSameDayTime(
+ doc.lastModified, System.currentTimeMillis(), DateFormat.SHORT,
+ DateFormat.SHORT));
+
+ if (state.showSize) {
+ size.setVisibility(View.VISIBLE);
+ if (doc.isDirectory()) {
+ size.setText(null);
+ } else {
+ size.setText(Formatter.formatFileSize(context, doc.size));
+ }
+ } else {
+ size.setVisibility(View.GONE);
}
return convertView;