Loading packages/DocumentsUI/res/drawable/cabinet.png 0 → 100644 +21.3 KiB Loading image diff... packages/DocumentsUI/res/layout/fragment_directory.xml +28 −15 Original line number Diff line number Diff line Loading @@ -36,8 +36,8 @@ android:background="@color/material_grey_50" android:visibility="gone"/> <!-- The empty directory view --> <LinearLayout <!-- The empty container view --> <FrameLayout android:id="@android:id/empty" android:gravity="center" android:layout_width="match_parent" Loading @@ -45,6 +45,25 @@ android:orientation="vertical" android:visibility="gone"> <LinearLayout android:id="@+id/content" android:gravity="center" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/artwork" android:src="@drawable/cabinet" android:adjustViewBounds="true" android:layout_height="250dp" android:layout_width="fill_parent" android:alpha="1" android:layout_centerVertical="true" android:layout_marginBottom="25dp" android:scaleType="fitCenter" android:contentDescription="@null" /> <TextView android:id="@+id/message" android:layout_width="wrap_content" Loading @@ -52,14 +71,8 @@ android:text="@string/empty" style="@android:style/TextAppearance.Material.Subhead" /> <Button android:id="@+id/button_retry" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_retry" style="?android:attr/buttonBarPositiveButtonStyle" /> </LinearLayout> </FrameLayout> <!-- This FrameLayout works around b/24189541 --> <FrameLayout Loading packages/DocumentsUI/res/values/strings.xml +2 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,8 @@ <!-- Text shown when a directory of documents is empty [CHAR LIMIT=24] --> <string name="empty">No items</string> <!-- Text shown when a file search returns no items [CHAR LIMIT=32] --> <string name="no_results">No matches in %1$s</string> <!-- Toast shown when no app can be found to open the selected document [CHAR LIMIT=48] --> <string name="toast_no_application">Can\'t open file</string> Loading packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +98 −73 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.internal.util.Preconditions.checkState; import static com.google.common.base.Preconditions.checkArgument; import android.annotation.StringRes; import android.app.Activity; import android.app.ActivityManager; import android.app.Fragment; Loading Loading @@ -131,6 +132,7 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi private static final int LOADER_ID = 42; private static final int DELETE_UNDO_TIMEOUT = 5000; private static final int DELETE_JOB_DELAY = 5500; private static final int EMPTY_REVEAL_DURATION = 250; private static final String EXTRA_TYPE = "type"; private static final String EXTRA_ROOT = "root"; Loading Loading @@ -167,63 +169,6 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi private MessageBar mMessageBar; private View mProgressBar; public static void showDirectory(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) { show(fm, TYPE_NORMAL, root, doc, null, anim); } public static void showSearch(FragmentManager fm, RootInfo root, String query, int anim) { show(fm, TYPE_SEARCH, root, null, query, anim); } public static void showRecentsOpen(FragmentManager fm, int anim) { show(fm, TYPE_RECENT_OPEN, null, null, null, anim); } private static void show(FragmentManager fm, int type, RootInfo root, DocumentInfo doc, String query, int anim) { final Bundle args = new Bundle(); args.putInt(EXTRA_TYPE, type); args.putParcelable(EXTRA_ROOT, root); args.putParcelable(EXTRA_DOC, doc); args.putString(EXTRA_QUERY, query); final FragmentTransaction ft = fm.beginTransaction(); switch (anim) { case ANIM_SIDE: args.putBoolean(EXTRA_IGNORE_STATE, true); break; case ANIM_DOWN: args.putBoolean(EXTRA_IGNORE_STATE, true); ft.setCustomAnimations(R.animator.dir_down, R.animator.dir_frozen); break; case ANIM_UP: ft.setCustomAnimations(R.animator.dir_frozen, R.animator.dir_up); break; } final DirectoryFragment fragment = new DirectoryFragment(); fragment.setArguments(args); ft.replace(R.id.container_directory, fragment); ft.commitAllowingStateLoss(); } private static String buildStateKey(RootInfo root, DocumentInfo doc) { final StringBuilder builder = new StringBuilder(); builder.append(root != null ? root.authority : "null").append(';'); builder.append(root != null ? root.rootId : "null").append(';'); builder.append(doc != null ? doc.documentId : "null"); return builder.toString(); } public static @Nullable DirectoryFragment get(FragmentManager fm) { // TODO: deal with multiple directories shown at once Fragment fragment = fm.findFragmentById(R.id.container_directory); return fragment instanceof DirectoryFragment ? (DirectoryFragment) fragment : null; } @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Loading Loading @@ -917,25 +862,43 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi return mTuner.isDocumentEnabled(docMimeType, docFlags); } void showEmptyView() { mEmptyView.setVisibility(View.VISIBLE); mRecView.setVisibility(View.GONE); TextView msg = (TextView) mEmptyView.findViewById(R.id.message); msg.setText(R.string.empty); // No retry button for the empty view. mEmptyView.findViewById(R.id.button_retry).setVisibility(View.GONE); private void showEmptyDirectory() { showEmptyView(R.string.empty); } private void showNoResults(RootInfo root) { CharSequence msg = getContext().getResources().getText(R.string.no_results); showEmptyView(String.format(String.valueOf(msg), root.title)); } void showErrorView() { // Shows an error indicating documents couldn't be queried. private void showQueryError() { showEmptyView(R.string.query_error); } private void showEmptyView(@StringRes int id) { showEmptyView(getContext().getResources().getText(id)); } private void showEmptyView(CharSequence msg) { View content = mEmptyView.findViewById(R.id.content); TextView msgView = (TextView) mEmptyView.findViewById(R.id.message); msgView.setText(msg); content.animate().cancel(); // cancel any ongoing animations content.setAlpha(0); mEmptyView.setVisibility(View.VISIBLE); mRecView.setVisibility(View.GONE); TextView msg = (TextView) mEmptyView.findViewById(R.id.message); msg.setText(R.string.query_error); // TODO: Enable this once the retry button does something. mEmptyView.findViewById(R.id.button_retry).setVisibility(View.GONE); // fade in the content, so it looks purdy like content.animate() .alpha(1f) .setDuration(EMPTY_REVEAL_DURATION) .setListener(null); } void showRecyclerView() { private void showDirectory() { mEmptyView.setVisibility(View.GONE); mRecView.setVisibility(View.VISIBLE); } Loading Loading @@ -1300,16 +1263,20 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi mProgressBar.setVisibility(model.isLoading() ? View.VISIBLE : View.GONE); if (model.isEmpty()) { showEmptyView(); if (getDisplayState().currentSearch != null) { showNoResults(getDisplayState().stack.root); } else { showRecyclerView(); showEmptyDirectory(); } } else { showDirectory(); mAdapter.notifyDataSetChanged(); } } @Override public void onModelUpdateFailed(Exception e) { showErrorView(); showQueryError(); } } Loading Loading @@ -1419,4 +1386,62 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi } } } public static void showDirectory( FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) { show(fm, TYPE_NORMAL, root, doc, null, anim); } public static void showSearch(FragmentManager fm, RootInfo root, String query, int anim) { show(fm, TYPE_SEARCH, root, null, query, anim); } public static void showRecentsOpen(FragmentManager fm, int anim) { show(fm, TYPE_RECENT_OPEN, null, null, null, anim); } private static void show(FragmentManager fm, int type, RootInfo root, DocumentInfo doc, String query, int anim) { final Bundle args = new Bundle(); args.putInt(EXTRA_TYPE, type); args.putParcelable(EXTRA_ROOT, root); args.putParcelable(EXTRA_DOC, doc); args.putString(EXTRA_QUERY, query); final FragmentTransaction ft = fm.beginTransaction(); switch (anim) { case ANIM_SIDE: args.putBoolean(EXTRA_IGNORE_STATE, true); break; case ANIM_DOWN: args.putBoolean(EXTRA_IGNORE_STATE, true); ft.setCustomAnimations(R.animator.dir_down, R.animator.dir_frozen); break; case ANIM_UP: ft.setCustomAnimations(R.animator.dir_frozen, R.animator.dir_up); break; } final DirectoryFragment fragment = new DirectoryFragment(); fragment.setArguments(args); ft.replace(R.id.container_directory, fragment); ft.commitAllowingStateLoss(); } private static String buildStateKey(RootInfo root, DocumentInfo doc) { final StringBuilder builder = new StringBuilder(); builder.append(root != null ? root.authority : "null").append(';'); builder.append(root != null ? root.rootId : "null").append(';'); builder.append(doc != null ? doc.documentId : "null"); return builder.toString(); } public static @Nullable DirectoryFragment get(FragmentManager fm) { // TODO: deal with multiple directories shown at once Fragment fragment = fm.findFragmentById(R.id.container_directory); return fragment instanceof DirectoryFragment ? (DirectoryFragment) fragment : null; } } Loading
packages/DocumentsUI/res/layout/fragment_directory.xml +28 −15 Original line number Diff line number Diff line Loading @@ -36,8 +36,8 @@ android:background="@color/material_grey_50" android:visibility="gone"/> <!-- The empty directory view --> <LinearLayout <!-- The empty container view --> <FrameLayout android:id="@android:id/empty" android:gravity="center" android:layout_width="match_parent" Loading @@ -45,6 +45,25 @@ android:orientation="vertical" android:visibility="gone"> <LinearLayout android:id="@+id/content" android:gravity="center" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/artwork" android:src="@drawable/cabinet" android:adjustViewBounds="true" android:layout_height="250dp" android:layout_width="fill_parent" android:alpha="1" android:layout_centerVertical="true" android:layout_marginBottom="25dp" android:scaleType="fitCenter" android:contentDescription="@null" /> <TextView android:id="@+id/message" android:layout_width="wrap_content" Loading @@ -52,14 +71,8 @@ android:text="@string/empty" style="@android:style/TextAppearance.Material.Subhead" /> <Button android:id="@+id/button_retry" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_retry" style="?android:attr/buttonBarPositiveButtonStyle" /> </LinearLayout> </FrameLayout> <!-- This FrameLayout works around b/24189541 --> <FrameLayout Loading
packages/DocumentsUI/res/values/strings.xml +2 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,8 @@ <!-- Text shown when a directory of documents is empty [CHAR LIMIT=24] --> <string name="empty">No items</string> <!-- Text shown when a file search returns no items [CHAR LIMIT=32] --> <string name="no_results">No matches in %1$s</string> <!-- Toast shown when no app can be found to open the selected document [CHAR LIMIT=48] --> <string name="toast_no_application">Can\'t open file</string> Loading
packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +98 −73 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.internal.util.Preconditions.checkState; import static com.google.common.base.Preconditions.checkArgument; import android.annotation.StringRes; import android.app.Activity; import android.app.ActivityManager; import android.app.Fragment; Loading Loading @@ -131,6 +132,7 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi private static final int LOADER_ID = 42; private static final int DELETE_UNDO_TIMEOUT = 5000; private static final int DELETE_JOB_DELAY = 5500; private static final int EMPTY_REVEAL_DURATION = 250; private static final String EXTRA_TYPE = "type"; private static final String EXTRA_ROOT = "root"; Loading Loading @@ -167,63 +169,6 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi private MessageBar mMessageBar; private View mProgressBar; public static void showDirectory(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) { show(fm, TYPE_NORMAL, root, doc, null, anim); } public static void showSearch(FragmentManager fm, RootInfo root, String query, int anim) { show(fm, TYPE_SEARCH, root, null, query, anim); } public static void showRecentsOpen(FragmentManager fm, int anim) { show(fm, TYPE_RECENT_OPEN, null, null, null, anim); } private static void show(FragmentManager fm, int type, RootInfo root, DocumentInfo doc, String query, int anim) { final Bundle args = new Bundle(); args.putInt(EXTRA_TYPE, type); args.putParcelable(EXTRA_ROOT, root); args.putParcelable(EXTRA_DOC, doc); args.putString(EXTRA_QUERY, query); final FragmentTransaction ft = fm.beginTransaction(); switch (anim) { case ANIM_SIDE: args.putBoolean(EXTRA_IGNORE_STATE, true); break; case ANIM_DOWN: args.putBoolean(EXTRA_IGNORE_STATE, true); ft.setCustomAnimations(R.animator.dir_down, R.animator.dir_frozen); break; case ANIM_UP: ft.setCustomAnimations(R.animator.dir_frozen, R.animator.dir_up); break; } final DirectoryFragment fragment = new DirectoryFragment(); fragment.setArguments(args); ft.replace(R.id.container_directory, fragment); ft.commitAllowingStateLoss(); } private static String buildStateKey(RootInfo root, DocumentInfo doc) { final StringBuilder builder = new StringBuilder(); builder.append(root != null ? root.authority : "null").append(';'); builder.append(root != null ? root.rootId : "null").append(';'); builder.append(doc != null ? doc.documentId : "null"); return builder.toString(); } public static @Nullable DirectoryFragment get(FragmentManager fm) { // TODO: deal with multiple directories shown at once Fragment fragment = fm.findFragmentById(R.id.container_directory); return fragment instanceof DirectoryFragment ? (DirectoryFragment) fragment : null; } @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Loading Loading @@ -917,25 +862,43 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi return mTuner.isDocumentEnabled(docMimeType, docFlags); } void showEmptyView() { mEmptyView.setVisibility(View.VISIBLE); mRecView.setVisibility(View.GONE); TextView msg = (TextView) mEmptyView.findViewById(R.id.message); msg.setText(R.string.empty); // No retry button for the empty view. mEmptyView.findViewById(R.id.button_retry).setVisibility(View.GONE); private void showEmptyDirectory() { showEmptyView(R.string.empty); } private void showNoResults(RootInfo root) { CharSequence msg = getContext().getResources().getText(R.string.no_results); showEmptyView(String.format(String.valueOf(msg), root.title)); } void showErrorView() { // Shows an error indicating documents couldn't be queried. private void showQueryError() { showEmptyView(R.string.query_error); } private void showEmptyView(@StringRes int id) { showEmptyView(getContext().getResources().getText(id)); } private void showEmptyView(CharSequence msg) { View content = mEmptyView.findViewById(R.id.content); TextView msgView = (TextView) mEmptyView.findViewById(R.id.message); msgView.setText(msg); content.animate().cancel(); // cancel any ongoing animations content.setAlpha(0); mEmptyView.setVisibility(View.VISIBLE); mRecView.setVisibility(View.GONE); TextView msg = (TextView) mEmptyView.findViewById(R.id.message); msg.setText(R.string.query_error); // TODO: Enable this once the retry button does something. mEmptyView.findViewById(R.id.button_retry).setVisibility(View.GONE); // fade in the content, so it looks purdy like content.animate() .alpha(1f) .setDuration(EMPTY_REVEAL_DURATION) .setListener(null); } void showRecyclerView() { private void showDirectory() { mEmptyView.setVisibility(View.GONE); mRecView.setVisibility(View.VISIBLE); } Loading Loading @@ -1300,16 +1263,20 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi mProgressBar.setVisibility(model.isLoading() ? View.VISIBLE : View.GONE); if (model.isEmpty()) { showEmptyView(); if (getDisplayState().currentSearch != null) { showNoResults(getDisplayState().stack.root); } else { showRecyclerView(); showEmptyDirectory(); } } else { showDirectory(); mAdapter.notifyDataSetChanged(); } } @Override public void onModelUpdateFailed(Exception e) { showErrorView(); showQueryError(); } } Loading Loading @@ -1419,4 +1386,62 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi } } } public static void showDirectory( FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) { show(fm, TYPE_NORMAL, root, doc, null, anim); } public static void showSearch(FragmentManager fm, RootInfo root, String query, int anim) { show(fm, TYPE_SEARCH, root, null, query, anim); } public static void showRecentsOpen(FragmentManager fm, int anim) { show(fm, TYPE_RECENT_OPEN, null, null, null, anim); } private static void show(FragmentManager fm, int type, RootInfo root, DocumentInfo doc, String query, int anim) { final Bundle args = new Bundle(); args.putInt(EXTRA_TYPE, type); args.putParcelable(EXTRA_ROOT, root); args.putParcelable(EXTRA_DOC, doc); args.putString(EXTRA_QUERY, query); final FragmentTransaction ft = fm.beginTransaction(); switch (anim) { case ANIM_SIDE: args.putBoolean(EXTRA_IGNORE_STATE, true); break; case ANIM_DOWN: args.putBoolean(EXTRA_IGNORE_STATE, true); ft.setCustomAnimations(R.animator.dir_down, R.animator.dir_frozen); break; case ANIM_UP: ft.setCustomAnimations(R.animator.dir_frozen, R.animator.dir_up); break; } final DirectoryFragment fragment = new DirectoryFragment(); fragment.setArguments(args); ft.replace(R.id.container_directory, fragment); ft.commitAllowingStateLoss(); } private static String buildStateKey(RootInfo root, DocumentInfo doc) { final StringBuilder builder = new StringBuilder(); builder.append(root != null ? root.authority : "null").append(';'); builder.append(root != null ? root.rootId : "null").append(';'); builder.append(doc != null ? doc.documentId : "null"); return builder.toString(); } public static @Nullable DirectoryFragment get(FragmentManager fm) { // TODO: deal with multiple directories shown at once Fragment fragment = fm.findFragmentById(R.id.container_directory); return fragment instanceof DirectoryFragment ? (DirectoryFragment) fragment : null; } }