summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/DocumentsUI/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml28
-rw-r--r--packages/DocumentsUI/res/drawable/vector_drawable_progress_indeterminate_horizontal_trimmed.xml53
-rw-r--r--packages/DocumentsUI/res/layout/fragment_directory.xml16
-rw-r--r--packages/DocumentsUI/res/values/styles.xml10
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java94
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/MessageBar.java2
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/DirectoryFragmentModelTest.java17
7 files changed, 158 insertions, 62 deletions
diff --git a/packages/DocumentsUI/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml b/packages/DocumentsUI/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml
new file mode 100644
index 000000000000..070b9a10351c
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ 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.
+-->
+
+<!-- Variant of progress_indeterminate_horizontal_material in frameworks/base/core/res, which
+ draws the whole height of the progress bar instead having blank space above and below the
+ bar. -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/vector_drawable_progress_indeterminate_horizontal_trimmed" >
+ <target
+ android:name="rect2_grp"
+ android:animation="@*android:anim/progress_indeterminate_horizontal_rect2" />
+ <target
+ android:name="rect1_grp"
+ android:animation="@*android:anim/progress_indeterminate_horizontal_rect1" />
+</animated-vector>
diff --git a/packages/DocumentsUI/res/drawable/vector_drawable_progress_indeterminate_horizontal_trimmed.xml b/packages/DocumentsUI/res/drawable/vector_drawable_progress_indeterminate_horizontal_trimmed.xml
new file mode 100644
index 000000000000..39e3a3738e28
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable/vector_drawable_progress_indeterminate_horizontal_trimmed.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ 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.
+-->
+
+<!-- Variant of vector_drawable_progress_indeterminate_horizontal in frameworks/base/core/res, which
+ draws the whole height of the progress bar instead having blank space above and below the
+ bar. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="10dp"
+ android:width="360dp"
+ android:viewportHeight="10"
+ android:viewportWidth="360" >
+ <group
+ android:name="progress_group"
+ android:translateX="180"
+ android:translateY="5" >
+ <path
+ android:name="background_track"
+ android:pathData="M -180.0,-5.0 l 360.0,0 l 0,10.0 l -360.0,0 Z"
+ android:fillColor="?android:attr/colorControlActivated"
+ android:fillAlpha="?android:attr/disabledAlpha"/>
+ <group
+ android:name="rect2_grp"
+ android:translateX="-197.60001"
+ android:scaleX="0.1" >
+ <path
+ android:name="rect2"
+ android:pathData="M -144.0,-5.0 l 288.0,0 l 0,10.0 l -288.0,0 Z"
+ android:fillColor="?android:attr/colorControlActivated" />
+ </group>
+ <group
+ android:name="rect1_grp"
+ android:translateX="-522.59998"
+ android:scaleX="0.1" >
+ <path
+ android:name="rect1"
+ android:pathData="M -144.0,-5.0 l 288.0,0 l 0,10.0 l -288.0,0 Z"
+ android:fillColor="?android:attr/colorControlActivated" />
+ </group>
+ </group>
+</vector>
diff --git a/packages/DocumentsUI/res/layout/fragment_directory.xml b/packages/DocumentsUI/res/layout/fragment_directory.xml
index f5c73d5269c2..6d8a913f74f1 100644
--- a/packages/DocumentsUI/res/layout/fragment_directory.xml
+++ b/packages/DocumentsUI/res/layout/fragment_directory.xml
@@ -41,6 +41,14 @@
android:orientation="vertical"
android:animateLayoutChanges="true">
+ <ProgressBar
+ android:id="@+id/progressbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:indeterminate="true"
+ style="@style/TrimmedHorizontalProgressBar"
+ android:visibility="gone"/>
+
<FrameLayout
android:id="@+id/container_message_bar"
android:layout_width="match_parent"
@@ -48,12 +56,12 @@
android:elevation="8dp"
android:background="@color/material_grey_50"
android:visibility="gone"/>
-
+
<!-- This FrameLayout works around b/24189541 -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
-
+
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:scrollbars="vertical"
@@ -67,9 +75,9 @@
android:scrollbarStyle="outsideOverlay"
android:drawSelectorOnTop="true"
android:background="@color/directory_background" />
-
+
</FrameLayout>
-
+
</LinearLayout>
</com.android.documentsui.DirectoryView>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
index 8301816edaea..c13f144d0717 100644
--- a/packages/DocumentsUI/res/values/styles.xml
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -77,14 +77,20 @@
<item name="android:colorPrimaryDark">@color/platform_blue_700</item>
<item name="android:colorPrimary">@color/platform_blue_500</item>
<item name="android:colorAccent">@color/platform_blue_700</item>
+ <item name="colorControlActivated">@color/platform_blue_a100</item>
<item name="android:actionModeStyle">@style/FilesActionModeStyle</item>
<item name="colorActionMode">@color/platform_blue_700</item>
-
<item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
</style>
<style name="FilesActionModeStyle" parent="@android:style/Widget.Material.Light.ActionMode">
<item name="android:background">@color/platform_blue_100</item>
</style>
-
+
+ <style name="TrimmedHorizontalProgressBar" parent="android:Widget.Material.ProgressBar.Horizontal">
+ <item name="android:indeterminateDrawable">@drawable/progress_indeterminate_horizontal_material_trimmed</item>
+ <item name="android:minHeight">3dp</item>
+ <item name="android:maxHeight">3dp</item>
+ </style>
+
</resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index c2821e13d7c3..b30cab6ccf9d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -135,6 +135,7 @@ public class DirectoryFragment extends Fragment {
private static final String EXTRA_IGNORE_STATE = "ignoreState";
private Model mModel;
+ private Model.UpdateListener mModelUpdateListener = new ModelUpdateListener();
private final Handler mHandler = new Handler(Looper.getMainLooper());
@@ -160,6 +161,7 @@ public class DirectoryFragment extends Fragment {
private int mColumnCount = 1; // This will get updated when layout changes.
private MessageBar mMessageBar;
+ private View mProgressBar;
public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
show(fm, TYPE_NORMAL, root, doc, null, anim);
@@ -223,6 +225,7 @@ public class DirectoryFragment extends Fragment {
final View view = inflater.inflate(R.layout.fragment_directory, container, false);
mMessageBar = MessageBar.create(getChildFragmentManager());
+ mProgressBar = view.findViewById(R.id.progressbar);
mEmptyView = view.findViewById(android.R.id.empty);
@@ -311,9 +314,8 @@ public class DirectoryFragment extends Fragment {
: MultiSelectManager.MODE_SINGLE);
selMgr.addCallback(new SelectionModeListener());
- mModel = new Model(context, selMgr);
- mModel.setSelectionManager(selMgr);
- mModel.addUpdateListener(mAdapter);
+ mModel = new Model(context, selMgr, mAdapter);
+ mModel.addUpdateListener(mModelUpdateListener);
mType = getArguments().getInt(EXTRA_TYPE);
mStateKey = buildStateKey(root, doc);
@@ -897,8 +899,7 @@ public class DirectoryFragment extends Fragment {
}
}
- private final class DocumentsAdapter extends RecyclerView.Adapter<DocumentHolder>
- implements Model.UpdateListener {
+ private final class DocumentsAdapter extends RecyclerView.Adapter<DocumentHolder> {
private final Context mContext;
private final LayoutInflater mInflater;
@@ -909,30 +910,6 @@ public class DirectoryFragment extends Fragment {
}
@Override
- public void onModelUpdate(Model model) {
- if (model.info != null || model.error != null) {
- mMessageBar.setInfo(model.info);
- mMessageBar.setError(model.error);
- mMessageBar.show();
- }
-
- if (model.isEmpty()) {
- mEmptyView.setVisibility(View.VISIBLE);
- } else {
- mEmptyView.setVisibility(View.GONE);
- }
-
- notifyDataSetChanged();
- }
-
- @Override
- public void onModelUpdateFailed(Exception e) {
- // TODO: deal with catastrophic update failures
- String error = getString(R.string.query_error);
- notifyDataSetChanged();
- }
-
- @Override
public DocumentHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final State state = getDisplayState(DirectoryFragment.this);
final LayoutInflater inflater = LayoutInflater.from(getContext());
@@ -1675,6 +1652,7 @@ public class DirectoryFragment extends Fragment {
@VisibleForTesting
public static final class Model implements DocumentContext {
private MultiSelectManager mSelectionManager;
+ private RecyclerView.Adapter<?> mViewAdapter;
private Context mContext;
private int mCursorCount;
private boolean mIsLoading;
@@ -1684,17 +1662,11 @@ public class DirectoryFragment extends Fragment {
@Nullable private String info;
@Nullable private String error;
- Model(Context context, MultiSelectManager selectionManager) {
+ Model(Context context, MultiSelectManager selectionManager,
+ RecyclerView.Adapter<?> viewAdapter) {
mContext = context;
mSelectionManager = selectionManager;
- }
-
- /**
- * Sets the selection manager used by the model.
- * TODO: the model should instantiate the selection manager. See onActivityCreated.
- */
- void setSelectionManager(MultiSelectManager mgr) {
- mSelectionManager = mgr;
+ mViewAdapter = viewAdapter;
}
/**
@@ -1859,7 +1831,7 @@ public class DirectoryFragment extends Fragment {
int position = selected.get(i);
if (DEBUG) Log.d(TAG, "Marked position " + position + " for deletion");
mMarkedForDeletion.append(position, true);
- mUpdateListener.notifyItemRemoved(position);
+ mViewAdapter.notifyItemRemoved(position);
}
}
@@ -1874,7 +1846,7 @@ public class DirectoryFragment extends Fragment {
for (int i = 0; i < size; ++i) {
final int position = mMarkedForDeletion.keyAt(i);
mMarkedForDeletion.put(position, false);
- mUpdateListener.notifyItemInserted(position);
+ mViewAdapter.notifyItemInserted(position);
}
// Then, clear the deletion list.
@@ -1957,26 +1929,46 @@ public class DirectoryFragment extends Fragment {
mUpdateListener = listener;
}
- interface UpdateListener {
+ static class UpdateListener {
/**
* Called when a successful update has occurred.
*/
- void onModelUpdate(Model model);
+ void onModelUpdate(Model model) {}
/**
* Called when an update has been attempted but failed.
*/
- void onModelUpdateFailed(Exception e);
+ void onModelUpdateFailed(Exception e) {}
+ }
+ }
- /**
- * Called when an item has been removed from the model.
- */
- void notifyItemRemoved(int position);
+ private class ModelUpdateListener extends Model.UpdateListener {
+ @Override
+ public void onModelUpdate(Model model) {
+ if (model.info != null || model.error != null) {
+ mMessageBar.setInfo(model.info);
+ mMessageBar.setError(model.error);
+ mMessageBar.show();
+ }
- /**
- * Called when an item has been added to the model.
- */
- void notifyItemInserted(int position);
+ mProgressBar.setVisibility(model.isLoading() ? View.VISIBLE : View.GONE);
+
+ if (model.isEmpty()) {
+ mEmptyView.setVisibility(View.VISIBLE);
+ mRecView.setVisibility(View.GONE);
+ } else {
+ mEmptyView.setVisibility(View.GONE);
+ mRecView.setVisibility(View.VISIBLE);
+ }
+
+ mAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onModelUpdateFailed(Exception e) {
+ // TODO: deal with catastrophic update failures
+ String error = getString(R.string.query_error);
+ mAdapter.notifyDataSetChanged();
}
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/MessageBar.java b/packages/DocumentsUI/src/com/android/documentsui/MessageBar.java
index a48fd5c268b4..312d53b9dc1c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/MessageBar.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/MessageBar.java
@@ -69,7 +69,7 @@ public class MessageBar extends Fragment {
* message bar layout will be adjusted accordingly.
*/
public void setError(@Nullable String error) {
- View errorView = mView.findViewById(R.id.container_message_bar);
+ View errorView = mView.findViewById(R.id.container_error);
if (error != null) {
TextView errorText = (TextView) mView.findViewById(R.id.textview_error);
errorText.setText(error);
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/DirectoryFragmentModelTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/DirectoryFragmentModelTest.java
index 5505f3546e5d..1895a6e66450 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/DirectoryFragmentModelTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/DirectoryFragmentModelTest.java
@@ -22,9 +22,12 @@ import android.content.ContextWrapper;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.provider.DocumentsContract.Document;
+import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.support.v7.widget.RecyclerView;
import android.test.AndroidTestCase;
import android.test.MoreAsserts;
import android.test.mock.MockContentResolver;
+import android.view.ViewGroup;
import com.android.documentsui.DirectoryFragment.Model;
import com.android.documentsui.MultiSelectManager.Selection;
@@ -57,7 +60,8 @@ public class DirectoryFragmentModelTest extends AndroidTestCase {
DirectoryResult r = new DirectoryResult();
r.cursor = cursor;
- model = new Model(mContext, null);
+ // Instantiate the model with a dummy view adapter and listener that (for now) do nothing.
+ model = new Model(mContext, null, new DummyAdapter());
model.addUpdateListener(new DummyListener());
model.update(r);
}
@@ -160,11 +164,16 @@ public class DirectoryFragmentModelTest extends AndroidTestCase {
return model.getDocuments(sel);
}
- private static class DummyListener implements Model.UpdateListener {
+ private static class DummyListener extends Model.UpdateListener {
public void onModelUpdate(Model model) {}
public void onModelUpdateFailed(Exception e) {}
- public void notifyItemRemoved(int position) {}
- public void notifyItemInserted(int position) {}
}
+ private static class DummyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+ public int getItemCount() { return 0; }
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {}
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ return null;
+ }
+ }
}