summaryrefslogtreecommitdiffstats
path: root/packages/DocumentsUI/src/com/android/documentsui
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2013-09-13 13:42:19 -0700
committerJeff Sharkey <jsharkey@android.com>2013-09-13 16:02:14 -0700
commitf6db154975ef575479ba4ab59d80bcf592288252 (patch)
treee2dab1b025abe925dd70a368a8bd4919f9fae6f4 /packages/DocumentsUI/src/com/android/documentsui
parent3e1189b3590aefb65a2af720ae2ba959bbd4188d (diff)
downloadframeworks_base-f6db154975ef575479ba4ab59d80bcf592288252.zip
frameworks_base-f6db154975ef575479ba4ab59d80bcf592288252.tar.gz
frameworks_base-f6db154975ef575479ba4ab59d80bcf592288252.tar.bz2
More UX updates around picking images.
When picking images or videos, hide the titles in recents, since the thumbnails should speak for themselves. Also respect new flag that allows a directory to request their titles be hidden. Show directory icon hint in grid mode when showing a thumbnail, to remind user it's a directory. Filter directories out of recents. Hide most action bar icons on phones, even when room. Only show drawer on first launch. Hide most drawer headers to match spec. Bug: 10710331 Change-Id: I0ef1973ddd62750f57345336388366eda1449720
Diffstat (limited to 'packages/DocumentsUI/src/com/android/documentsui')
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java77
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java9
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java6
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java3
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RootsCache.java4
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java25
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java4
7 files changed, 90 insertions, 38 deletions
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index aee865b..198927c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -102,6 +102,8 @@ public class DirectoryFragment extends Fragment {
private int mLastSortOrder = SORT_ORDER_UNKNOWN;
private boolean mLastShowSize = false;
+ private boolean mHideGridTitles = false;
+
private Point mThumbSize;
private DocumentsAdapter mAdapter;
@@ -112,11 +114,6 @@ public class DirectoryFragment extends Fragment {
private static final String EXTRA_DOC = "doc";
private static final String EXTRA_QUERY = "query";
- /**
- * MIME types that should always show thumbnails in list mode.
- */
- private static final String[] LIST_THUMBNAIL_MIMES = new String[] { "image/*", "video/*" };
-
private static AtomicInteger sLoaderId = new AtomicInteger(4000);
private final int mLoaderId = sLoaderId.incrementAndGet();
@@ -182,14 +179,23 @@ public class DirectoryFragment extends Fragment {
final Context context = getActivity();
final State state = getDisplayState(DirectoryFragment.this);
+ final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
+ final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
+
mAdapter = new DocumentsAdapter();
mType = getArguments().getInt(EXTRA_TYPE);
+ if (mType == TYPE_RECENT_OPEN) {
+ // Hide titles when showing recents for picking images/videos
+ mHideGridTitles = MimePredicate.mimeMatches(
+ MimePredicate.VISUAL_MIMES, state.acceptMimes);
+ } else {
+ mHideGridTitles = (doc != null) && doc.isGridTitlesHidden();
+ }
+
mCallbacks = new LoaderCallbacks<DirectoryResult>() {
@Override
public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) {
- final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
- final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
final String query = getArguments().getString(EXTRA_QUERY);
Uri contentsUri;
@@ -643,6 +649,8 @@ public class DirectoryFragment extends Fragment {
final Context context = parent.getContext();
final State state = getDisplayState(DirectoryFragment.this);
+ final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
+
final RootsCache roots = DocumentsApplication.getRootsCache(context);
final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache(
context, mThumbSize);
@@ -671,12 +679,15 @@ public class DirectoryFragment extends Fragment {
final String docSummary = getCursorString(cursor, Document.COLUMN_SUMMARY);
final long docSize = getCursorLong(cursor, Document.COLUMN_SIZE);
+ final View line1 = convertView.findViewById(R.id.line1);
+ final View line2 = convertView.findViewById(R.id.line2);
+
final View icon = convertView.findViewById(android.R.id.icon);
final ImageView iconMime = (ImageView) convertView.findViewById(R.id.icon_mime);
final ImageView iconThumb = (ImageView) convertView.findViewById(R.id.icon_thumb);
final TextView title = (TextView) convertView.findViewById(android.R.id.title);
- final View line2 = convertView.findViewById(R.id.line2);
final ImageView icon1 = (ImageView) convertView.findViewById(android.R.id.icon1);
+ final ImageView icon2 = (ImageView) convertView.findViewById(android.R.id.icon2);
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);
@@ -692,10 +703,11 @@ public class DirectoryFragment extends Fragment {
final boolean supportsThumbnail = (docFlags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0;
final boolean allowThumbnail = (state.derivedMode == MODE_GRID)
- || MimePredicate.mimeMatches(LIST_THUMBNAIL_MIMES, docMimeType);
+ || MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, docMimeType);
+ final boolean showThumbnail = supportsThumbnail && allowThumbnail;
boolean cacheHit = false;
- if (supportsThumbnail && allowThumbnail) {
+ if (showThumbnail) {
final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId);
final Bitmap cachedResult = thumbs.get(uri);
if (cachedResult != null) {
@@ -726,15 +738,19 @@ public class DirectoryFragment extends Fragment {
}
}
- title.setText(docDisplayName);
-
+ boolean hasLine1 = false;
boolean hasLine2 = false;
+ final boolean hideTitle = (state.derivedMode == MODE_GRID) && mHideGridTitles;
+ if (!hideTitle) {
+ title.setText(docDisplayName);
+ hasLine1 = true;
+ }
+
+ Drawable iconDrawable = null;
if (mType == TYPE_RECENT_OPEN) {
final RootInfo root = roots.getRoot(docAuthority, docRootId);
- final Drawable iconDrawable = root.loadIcon(context);
- icon1.setVisibility(View.VISIBLE);
- icon1.setImageDrawable(iconDrawable);
+ iconDrawable = root.loadIcon(context);
if (summary != null) {
final boolean alwaysShowSummary = getResources()
@@ -756,7 +772,13 @@ public class DirectoryFragment extends Fragment {
}
}
} else {
- icon1.setVisibility(View.GONE);
+ // Directories showing thumbnails in grid mode get a little icon
+ // hint to remind user they're a directory.
+ if (Document.MIME_TYPE_DIR.equals(docMimeType) && state.derivedMode == MODE_GRID
+ && showThumbnail) {
+ iconDrawable = context.getResources().getDrawable(R.drawable.ic_root_folder);
+ }
+
if (summary != null) {
if (docSummary != null) {
summary.setText(docSummary);
@@ -768,6 +790,19 @@ public class DirectoryFragment extends Fragment {
}
}
+ if (icon1 != null) icon1.setVisibility(View.GONE);
+ if (icon2 != null) icon2.setVisibility(View.GONE);
+
+ if (iconDrawable != null) {
+ if (hasLine1) {
+ icon1.setVisibility(View.VISIBLE);
+ icon1.setImageDrawable(iconDrawable);
+ } else {
+ icon2.setVisibility(View.VISIBLE);
+ icon2.setImageDrawable(iconDrawable);
+ }
+ }
+
if (docLastModified == -1) {
date.setText(null);
} else {
@@ -787,6 +822,9 @@ public class DirectoryFragment extends Fragment {
size.setVisibility(View.GONE);
}
+ if (line1 != null) {
+ line1.setVisibility(hasLine1 ? View.VISIBLE : View.GONE);
+ }
if (line2 != null) {
line2.setVisibility(hasLine2 ? View.VISIBLE : View.GONE);
}
@@ -796,11 +834,13 @@ public class DirectoryFragment extends Fragment {
if (enabled) {
setEnabledRecursive(convertView, true);
icon.setAlpha(1f);
- icon1.setAlpha(1f);
+ if (icon1 != null) icon1.setAlpha(1f);
+ if (icon2 != null) icon2.setAlpha(1f);
} else {
setEnabledRecursive(convertView, false);
icon.setAlpha(0.5f);
- icon1.setAlpha(0.5f);
+ if (icon1 != null) icon1.setAlpha(0.5f);
+ if (icon2 != null) icon2.setAlpha(0.5f);
}
return convertView;
@@ -943,6 +983,7 @@ public class DirectoryFragment extends Fragment {
}
private void setEnabledRecursive(View v, boolean enabled) {
+ if (v == null) return;
if (v.isEnabled() == enabled) return;
v.setEnabled(enabled);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index b1e51a0..f6cb481 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -244,6 +244,7 @@ public class DocumentsActivity extends Activity {
} else {
// Restore last stack for calling package
// TODO: move into async loader
+ boolean restoredStack = false;
final String packageName = getCallingPackage();
final Cursor cursor = getContentResolver()
.query(RecentsProvider.buildResume(packageName), null, null, null, null);
@@ -252,6 +253,7 @@ public class DocumentsActivity extends Activity {
final byte[] rawStack = cursor.getBlob(
cursor.getColumnIndex(ResumeColumns.STACK));
DurableUtils.readFromArray(rawStack, mState.stack);
+ restoredStack = true;
}
} catch (IOException e) {
Log.w(TAG, "Failed to resume", e);
@@ -264,10 +266,13 @@ public class DocumentsActivity extends Activity {
final List<RootInfo> matchingRoots = mRoots.getMatchingRoots(mState);
if (!matchingRoots.contains(root)) {
mState.stack.reset();
+ restoredStack = false;
}
- // Only open drawer when showing recents
- if (mState.stack.isRecents()) {
+ // Only open drawer when not restoring stack, and when not showing
+ // visual content.
+ if (!restoredStack
+ && !MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, mState.acceptMimes)) {
setRootsDrawerOpen(true);
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java b/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
index b55ce82..2d96876 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
@@ -22,6 +22,12 @@ import com.android.internal.util.Predicate;
public class MimePredicate implements Predicate<DocumentInfo> {
private final String[] mFilters;
+ /**
+ * MIME types that are visual in nature. For example, they should always be
+ * shown as thumbnails in list mode.
+ */
+ public static final String[] VISUAL_MIMES = new String[] { "image/*", "video/*" };
+
public MimePredicate(String[] filters) {
mFilters = filters;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java b/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
index a7173b6..1912010 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
@@ -27,6 +27,7 @@ import android.database.Cursor;
import android.database.MergeCursor;
import android.net.Uri;
import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Root;
import android.util.Log;
@@ -176,7 +177,7 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
try {
final Cursor cursor = task.get();
final FilteringCursorWrapper filtered = new FilteringCursorWrapper(
- cursor, mAcceptMimes) {
+ cursor, mAcceptMimes, new String[] { Document.MIME_TYPE_DIR }) {
@Override
public void close() {
// Ignored, since we manage cursor lifecycle internally
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index 4d313e8..9b54948 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -137,12 +137,14 @@ public class RootsCache {
@GuardedBy("ActivityThread")
public boolean isIconUnique(RootInfo root) {
+ final int rootIcon = root.derivedIcon != 0 ? root.derivedIcon : root.icon;
for (RootInfo test : mRoots) {
if (Objects.equal(test.authority, root.authority)) {
if (Objects.equal(test.rootId, root.rootId)) {
continue;
}
- if (test.icon == root.icon) {
+ final int testIcon = test.derivedIcon != 0 ? test.derivedIcon : test.icon;
+ if (testIcon == rootIcon) {
return false;
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index 54dcf1c..908729c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -35,6 +35,7 @@ import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
+import android.widget.Space;
import android.widget.TextView;
import com.android.documentsui.DocumentsActivity.State;
@@ -136,11 +137,8 @@ public class RootsFragment extends Fragment {
};
private static class RootsAdapter extends ArrayAdapter<RootInfo> implements SectionAdapter {
- private int mHeaderId;
-
- public RootsAdapter(Context context, int headerId) {
+ public RootsAdapter(Context context) {
super(context, 0);
- mHeaderId = headerId;
}
@Override
@@ -177,13 +175,8 @@ public class RootsFragment extends Fragment {
@Override
public View getHeaderView(View convertView, ViewGroup parent) {
if (convertView == null) {
- convertView = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.item_root_header, parent, false);
+ convertView = new Space(parent.getContext());
}
-
- final TextView title = (TextView) convertView.findViewById(android.R.id.title);
- title.setText(mHeaderId);
-
return convertView;
}
}
@@ -237,9 +230,9 @@ public class RootsFragment extends Fragment {
private final AppsAdapter mApps;
public SectionedRootsAdapter(Context context, List<RootInfo> roots, Intent includeApps) {
- mServices = new RootsAdapter(context, R.string.root_type_service);
- mShortcuts = new RootsAdapter(context, R.string.root_type_shortcut);
- mDevices = new RootsAdapter(context, R.string.root_type_device);
+ mServices = new RootsAdapter(context);
+ mShortcuts = new RootsAdapter(context);
+ mDevices = new RootsAdapter(context);
mApps = new AppsAdapter(context);
for (RootInfo root : roots) {
@@ -274,15 +267,15 @@ public class RootsFragment extends Fragment {
mShortcuts.sort(comp);
mDevices.sort(comp);
- if (mServices.getCount() > 0) {
- addSection(mServices);
- }
if (mShortcuts.getCount() > 0) {
addSection(mShortcuts);
}
if (mDevices.getCount() > 0) {
addSection(mDevices);
}
+ if (mServices.getCount() > 0) {
+ addSection(mServices);
+ }
if (mApps.getCount() > 0) {
addSection(mApps);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
index ab55d94..681cc9b 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -204,6 +204,10 @@ public class DocumentInfo implements Durable, Parcelable {
return (flags & Document.FLAG_SUPPORTS_DELETE) != 0;
}
+ public boolean isGridTitlesHidden() {
+ return (flags & Document.FLAG_DIR_HIDE_GRID_TITLES) != 0;
+ }
+
public static String getCursorString(Cursor cursor, String columnName) {
final int index = cursor.getColumnIndex(columnName);
return (index != -1) ? cursor.getString(index) : null;