OSDN Git Service

Normalize toolbar management.
authorSteve McKay <smckay@google.com>
Wed, 3 Feb 2016 19:15:57 +0000 (11:15 -0800)
committerSteve McKay <smckay@google.com>
Thu, 4 Feb 2016 01:59:06 +0000 (17:59 -0800)
Since it was almost all redundant (especially the stack stuff).
Ensure "Files" title present on drawer title in Files app.
DocumentsToolBar > DocumentsToolbar to match toolkit naming.

Bug: 26193264
Change-Id: I92c82c66d936aae3ce0f792581daa12898dfadee

13 files changed:
packages/DocumentsUI/res/layout/drawer_layout.xml
packages/DocumentsUI/res/layout/fixed_layout.xml
packages/DocumentsUI/res/layout/single_pane_layout.xml
packages/DocumentsUI/res/values/layouts.xml
packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
packages/DocumentsUI/src/com/android/documentsui/DocumentsToolbar.java [moved from packages/DocumentsUI/src/com/android/documentsui/DocumentsToolBar.java with 86% similarity]
packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
packages/DocumentsUI/src/com/android/documentsui/NavigationView.java [new file with mode: 0644]
packages/DocumentsUI/src/com/android/documentsui/SearchManager.java
packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java

index 0146f14..e3def05 100644 (file)
@@ -32,7 +32,7 @@
             android:layout_height="match_parent"
             android:orientation="vertical">
 
-            <com.android.documentsui.DocumentsToolBar
+            <com.android.documentsui.DocumentsToolbar
                 android:id="@+id/toolbar"
                 android:layout_width="match_parent"
                 android:layout_height="?android:attr/actionBarSize"
@@ -48,7 +48,7 @@
                     android:layout_marginStart="4dp"
                     android:overlapAnchor="true" />
 
-            </com.android.documentsui.DocumentsToolBar>
+            </com.android.documentsui.DocumentsToolbar>
 
             <include layout="@layout/directory_cluster"/>
 
index 3135977..7724096 100644 (file)
     android:layout_height="match_parent"
     android:id="@+id/coordinator_layout">
 
-    <LinearLayout 
+    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical">
 
-        <com.android.documentsui.DocumentsToolBar
+        <com.android.documentsui.DocumentsToolbar
             android:id="@+id/toolbar"
             android:layout_width="match_parent"
             android:layout_height="?android:attr/actionBarSize"
@@ -43,7 +43,7 @@
                 android:layout_marginStart="4dp"
                 android:overlapAnchor="true" />
 
-        </com.android.documentsui.DocumentsToolBar>
+        </com.android.documentsui.DocumentsToolbar>
 
         <LinearLayout
             android:layout_width="match_parent"
index c5a5745..f53d698 100644 (file)
@@ -27,7 +27,7 @@
         android:layout_height="match_parent"
         android:orientation="vertical">
 
-        <com.android.documentsui.DocumentsToolBar
+        <com.android.documentsui.DocumentsToolbar
             android:id="@+id/toolbar"
             android:layout_width="match_parent"
             android:layout_height="?android:attr/actionBarSize"
@@ -43,7 +43,7 @@
                 android:layout_marginStart="4dp"
                 android:overlapAnchor="true" />
 
-        </com.android.documentsui.DocumentsToolBar>
+        </com.android.documentsui.DocumentsToolbar>
 
         <include layout="@layout/directory_cluster"/>
 
index 8ac1ac2..c9308a1 100644 (file)
@@ -15,7 +15,7 @@
 -->
 
 <resources>
-    <item name="docs_activity" type="layout">@layout/drawer_layout</item>
+    <item name="documents_activity" type="layout">@layout/drawer_layout</item>
     <item name="files_activity" type="layout">@layout/drawer_layout</item>
-    <item name="manage_roots_activity" type="layout">@layout/single_pane_layout</item>
+    <item name="downloads_activity" type="layout">@layout/single_pane_layout</item>
 </resources>
index 497eb0e..e021632 100644 (file)
@@ -42,16 +42,10 @@ import android.support.annotation.CallSuper;
 import android.support.annotation.LayoutRes;
 import android.support.annotation.Nullable;
 import android.util.Log;
-import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.BaseAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
+import android.widget.Spinner;
+import android.widget.Toolbar;
 
 import com.android.documentsui.RecentsProvider.ResumeColumns;
 import com.android.documentsui.SearchManager.SearchManagerListener;
@@ -72,7 +66,8 @@ import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.Executor;
 
-public abstract class BaseActivity extends Activity implements SearchManagerListener {
+public abstract class BaseActivity extends Activity
+        implements SearchManagerListener, NavigationView.Environment {
 
     static final String EXTRA_STATE = "state";
 
@@ -80,7 +75,7 @@ public abstract class BaseActivity extends Activity implements SearchManagerList
     RootsCache mRoots;
     SearchManager mSearchManager;
     DrawerController mDrawer;
-    boolean mProductivityDevice;
+    NavigationView mNavigator;
 
     private final String mTag;
     @LayoutRes
@@ -92,7 +87,6 @@ public abstract class BaseActivity extends Activity implements SearchManagerList
 
     abstract void onTaskFinished(Uri... uris);
     abstract void refreshDirectory(int anim);
-    abstract void updateActionBar();
     abstract void saveStackBlocking();
     abstract State buildState();
 
@@ -101,19 +95,21 @@ public abstract class BaseActivity extends Activity implements SearchManagerList
         mTag = tag;
     }
 
+    @CallSuper
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
+        setContentView(mLayoutId);
+
+        mDrawer = DrawerController.create(this);
         mState = (icicle != null)
                 ? icicle.<State>getParcelable(EXTRA_STATE)
                         : buildState();
-
         Metrics.logActivityLaunch(this, mState, getIntent());
 
-        setContentView(mLayoutId);
-
         mRoots = DocumentsApplication.getRootsCache(this);
+
         mRoots.setOnCacheUpdateListener(
                 new RootsCache.OnCacheUpdateListener() {
                     @Override
@@ -121,9 +117,19 @@ public abstract class BaseActivity extends Activity implements SearchManagerList
                         new HandleRootsChangedTask().execute(getCurrentRoot());
                     }
                 });
+
         mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory);
         mSearchManager = new SearchManager(this);
 
+        DocumentsToolbar toolbar = (DocumentsToolbar) findViewById(R.id.toolbar);
+        setActionBar(toolbar);
+        mNavigator = new NavigationView(
+                mDrawer,
+                toolbar,
+                (Spinner) findViewById(R.id.stack),
+                mState,
+                this);
+
         // Base classes must update result in their onCreate.
         setResult(Activity.RESULT_CANCELED);
     }
@@ -133,7 +139,7 @@ public abstract class BaseActivity extends Activity implements SearchManagerList
         boolean showMenu = super.onCreateOptionsMenu(menu);
 
         getMenuInflater().inflate(R.menu.activity, menu);
-        mSearchManager.install((DocumentsToolBar) findViewById(R.id.toolbar));
+        mSearchManager.install((DocumentsToolbar) findViewById(R.id.toolbar));
 
         return showMenu;
     }
@@ -336,7 +342,8 @@ public abstract class BaseActivity extends Activity implements SearchManagerList
      * The current directory name and selection will get updated.
      * @param anim
      */
-    final void refreshCurrentRootAndDirectory(int anim) {
+    @Override
+    public final void refreshCurrentRootAndDirectory(int anim) {
         mSearchManager.cancelSearch();
 
         mDirectoryContainer.setDrawDisappearingFirst(anim == ANIM_ENTER);
@@ -347,8 +354,7 @@ public abstract class BaseActivity extends Activity implements SearchManagerList
             roots.onCurrentRootChanged();
         }
 
-        updateActionBar();
-
+        mNavigator.update();
         invalidateOptionsMenu();
     }
 
@@ -484,6 +490,12 @@ public abstract class BaseActivity extends Activity implements SearchManagerList
         super.onRestoreInstanceState(state);
     }
 
+    @Override
+    public boolean isSearchExpanded() {
+        return mSearchManager.isExpanded();
+    }
+
+    @Override
     public RootInfo getCurrentRoot() {
         if (mState.stack.root != null) {
             return mState.stack.root;
@@ -692,92 +704,6 @@ public abstract class BaseActivity extends Activity implements SearchManagerList
         }
     }
 
-    final class ItemSelectedListener implements OnItemSelectedListener {
-
-        boolean mIgnoreNextNavigation;
-
-        @Override
-        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
-            if (mIgnoreNextNavigation) {
-                mIgnoreNextNavigation = false;
-                return;
-            }
-
-            while (mState.stack.size() > position + 1) {
-                mState.popDocument();
-            }
-            refreshCurrentRootAndDirectory(ANIM_LEAVE);
-        }
-
-        @Override
-        public void onNothingSelected(AdapterView<?> parent) {
-            // Ignored
-        }
-    }
-
-    /**
-     * Class providing toolbar with runtime access to useful activity data.
-     */
-    final class StackAdapter extends BaseAdapter {
-        @Override
-        public int getCount() {
-            return mState.stack.size();
-        }
-
-        @Override
-        public DocumentInfo getItem(int position) {
-            return mState.stack.get(mState.stack.size() - position - 1);
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                convertView = LayoutInflater.from(parent.getContext())
-                        .inflate(R.layout.item_subdir_title, parent, false);
-            }
-
-            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
-            final DocumentInfo doc = getItem(position);
-
-            if (position == 0) {
-                final RootInfo root = getCurrentRoot();
-                title.setText(root.title);
-            } else {
-                title.setText(doc.displayName);
-            }
-
-            return convertView;
-        }
-
-        @Override
-        public View getDropDownView(int position, View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                convertView = LayoutInflater.from(parent.getContext())
-                        .inflate(R.layout.item_subdir, parent, false);
-            }
-
-            final ImageView subdir = (ImageView) convertView.findViewById(R.id.subdir);
-            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
-            final DocumentInfo doc = getItem(position);
-
-            if (position == 0) {
-                final RootInfo root = getCurrentRoot();
-                title.setText(root.title);
-                subdir.setVisibility(View.GONE);
-            } else {
-                title.setText(doc.displayName);
-                subdir.setVisibility(View.VISIBLE);
-            }
-
-            return convertView;
-        }
-    }
-
     /**
      * Interface providing access to current view of documents
      * even when all documents are not homed to the same parent.
index b933d0a..815ff3d 100644 (file)
@@ -43,10 +43,6 @@ import android.support.design.widget.Snackbar;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
-import android.view.View;
-import android.widget.BaseAdapter;
-import android.widget.Spinner;
-import android.widget.Toolbar;
 
 import com.android.documentsui.RecentsProvider.RecentColumns;
 import com.android.documentsui.RecentsProvider.ResumeColumns;
@@ -63,16 +59,8 @@ public class DocumentsActivity extends BaseActivity {
     private static final int CODE_FORWARD = 42;
     private static final String TAG = "DocumentsActivity";
 
-    private Toolbar mToolbar;
-    private Spinner mToolbarStack;
-
-    private Toolbar mRootsToolbar;
-
-    private ItemSelectedListener mStackListener;
-    private BaseAdapter mStackAdapter;
-
     public DocumentsActivity() {
-        super(R.layout.docs_activity, TAG);
+        super(R.layout.documents_activity, TAG);
     }
 
     @Override
@@ -81,18 +69,6 @@ public class DocumentsActivity extends BaseActivity {
 
         final Resources res = getResources();
 
-        mDrawer = DrawerController.create(this);
-        mToolbar = (Toolbar) findViewById(R.id.toolbar);
-
-        mStackAdapter = new StackAdapter();
-        mStackListener = new ItemSelectedListener();
-        mToolbarStack = (Spinner) findViewById(R.id.stack);
-        mToolbarStack.setOnItemSelectedListener(mStackListener);
-
-        mRootsToolbar = (Toolbar) findViewById(R.id.roots_toolbar);
-
-        setActionBar(mToolbar);
-
         if (mState.action == ACTION_CREATE) {
             final String mimeType = getIntent().getType();
             final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE);
@@ -180,7 +156,7 @@ public class DocumentsActivity extends BaseActivity {
         }
 
         if (showDrawer) {
-            setRootsDrawerOpen(true);
+            mNavigator.revealRootsDrawer(true);
         }
     }
 
@@ -217,66 +193,28 @@ public class DocumentsActivity extends BaseActivity {
     @Override
     protected void onPostCreate(Bundle savedInstanceState) {
         super.onPostCreate(savedInstanceState);
-        mDrawer.syncState();
-        updateActionBar();
-    }
-
-    public void setRootsDrawerOpen(boolean open) {
-        mDrawer.setOpen(open);
+        mDrawer.update();
+        mNavigator.update();
     }
 
     @Override
-    public void updateActionBar() {
-        if (mRootsToolbar != null) {
-            final String prompt = getIntent().getStringExtra(DocumentsContract.EXTRA_PROMPT);
-            if (prompt != null) {
-                mRootsToolbar.setTitle(prompt);
+    public String getDrawerTitle() {
+        String title = getIntent().getStringExtra(DocumentsContract.EXTRA_PROMPT);
+        if (title == null) {
+            if (mState.action == ACTION_OPEN ||
+                mState.action == ACTION_GET_CONTENT ||
+                mState.action == ACTION_OPEN_TREE) {
+                title = getResources().getString(R.string.title_open);
+            } else if (mState.action == ACTION_CREATE ||
+                       mState.action == ACTION_PICK_COPY_DESTINATION) {
+                title = getResources().getString(R.string.title_save);
             } else {
-                if (mState.action == ACTION_OPEN ||
-                    mState.action == ACTION_GET_CONTENT ||
-                    mState.action == ACTION_OPEN_TREE) {
-                    mRootsToolbar.setTitle(R.string.title_open);
-                } else if (mState.action == ACTION_CREATE ||
-                           mState.action == ACTION_PICK_COPY_DESTINATION) {
-                    mRootsToolbar.setTitle(R.string.title_save);
-                }
+                // If all else fails, just call it "Files".
+                title = getResources().getString(R.string.files_label);
             }
         }
 
-        if (mDrawer.isUnlocked()) {
-            mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
-            mToolbar.setNavigationContentDescription(R.string.drawer_open);
-            mToolbar.setNavigationOnClickListener(
-                    new View.OnClickListener() {
-                        @Override
-                        public void onClick(View v) {
-                            setRootsDrawerOpen(true);
-                        }
-                    });
-        } else {
-            mToolbar.setNavigationIcon(null);
-            mToolbar.setNavigationContentDescription(R.string.drawer_open);
-            mToolbar.setNavigationOnClickListener(null);
-        }
-
-        if (mSearchManager.isExpanded()) {
-            mToolbar.setTitle(null);
-            mToolbarStack.setVisibility(View.GONE);
-            mToolbarStack.setAdapter(null);
-        } else {
-            if (mState.stack.size() <= 1) {
-                mToolbar.setTitle(getCurrentRoot().title);
-                mToolbarStack.setVisibility(View.GONE);
-                mToolbarStack.setAdapter(null);
-            } else {
-                mToolbar.setTitle(null);
-                mToolbarStack.setVisibility(View.VISIBLE);
-                mToolbarStack.setAdapter(mStackAdapter);
-
-                mStackListener.mIgnoreNextNavigation = true;
-                mToolbarStack.setSelection(mStackAdapter.getCount() - 1);
-            }
-        }
+        return title;
     }
 
     @Override
@@ -331,11 +269,6 @@ public class DocumentsActivity extends BaseActivity {
     }
 
     @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        return mDrawer.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
-    }
-
-    @Override
     void refreshDirectory(int anim) {
         final FragmentManager fm = getFragmentManager();
         final RootInfo root = getCurrentRoot();
@@ -396,7 +329,11 @@ public class DocumentsActivity extends BaseActivity {
     @Override
     void onRootPicked(RootInfo root) {
         super.onRootPicked(root);
-        setRootsDrawerOpen(false);
+        mNavigator.revealRootsDrawer(false);
+    }
+
+    public void setRootsDrawerOpen(boolean open) {
+        mNavigator.revealRootsDrawer(open);
     }
 
     @Override
@@ -24,28 +24,28 @@ import android.widget.Toolbar;
 /**
  * ToolBar of Documents UI.
  */
-public class DocumentsToolBar extends Toolbar {
+public class DocumentsToolbar extends Toolbar {
     interface OnActionViewCollapsedListener {
         void onActionViewCollapsed();
     }
 
     private OnActionViewCollapsedListener mOnActionViewCollapsedListener;
 
-    public DocumentsToolBar(Context context, AttributeSet attrs,
+    public DocumentsToolbar(Context context, AttributeSet attrs,
             int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
     }
 
-    public DocumentsToolBar(Context context, AttributeSet attrs,
+    public DocumentsToolbar(Context context, AttributeSet attrs,
             int defStyleAttr) {
         super(context, attrs, defStyleAttr);
     }
 
-    public DocumentsToolBar(Context context, AttributeSet attrs) {
+    public DocumentsToolbar(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
-    public DocumentsToolBar(Context context) {
+    public DocumentsToolbar(Context context) {
         super(context);
     }
 
index 5cc677c..89be910 100644 (file)
@@ -35,9 +35,6 @@ import android.support.design.widget.Snackbar;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
-import android.view.View;
-import android.widget.BaseAdapter;
-import android.widget.Spinner;
 import android.widget.Toolbar;
 
 import com.android.documentsui.RecentsProvider.ResumeColumns;
@@ -56,14 +53,8 @@ import java.util.List;
 public class DownloadsActivity extends BaseActivity {
     private static final String TAG = "DownloadsActivity";
 
-    private Toolbar mToolbar;
-    private Spinner mToolbarStack;
-
-    private ItemSelectedListener mStackListener;
-    private BaseAdapter mStackAdapter;
-
     public DownloadsActivity() {
-        super(R.layout.manage_roots_activity, TAG);
+        super(R.layout.downloads_activity, TAG);
     }
 
     @Override
@@ -72,19 +63,10 @@ public class DownloadsActivity extends BaseActivity {
 
         final Context context = this;
 
-        mDrawer = DrawerController.createDummy();
-
-        mToolbar = (Toolbar) findViewById(R.id.toolbar);
-        mToolbar.setTitleTextAppearance(context,
+        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+        toolbar.setTitleTextAppearance(context,
                 android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title);
 
-        mStackAdapter = new StackAdapter();
-        mStackListener = new ItemSelectedListener();
-        mToolbarStack = (Spinner) findViewById(R.id.stack);
-        mToolbarStack.setOnItemSelectedListener(mStackListener);
-
-        setActionBar(mToolbar);
-
         if (!mState.restored) {
             // In this case, we set the activity title in AsyncTask.onPostExecute(). To prevent
             // talkback from reading aloud the default title, we clear it here.
@@ -112,33 +94,12 @@ public class DownloadsActivity extends BaseActivity {
     @Override
     protected void onPostCreate(Bundle savedInstanceState) {
         super.onPostCreate(savedInstanceState);
-        updateActionBar();
+        mNavigator.update();
     }
 
     @Override
-    public void updateActionBar() {
-        // No navigation in manage root mode.
-        mToolbar.setNavigationIcon(null);
-        mToolbar.setNavigationOnClickListener(null);
-
-        if (mSearchManager.isExpanded()) {
-            mToolbar.setTitle(null);
-            mToolbarStack.setVisibility(View.GONE);
-            mToolbarStack.setAdapter(null);
-        } else {
-            if (mState.stack.size() <= 1) {
-                mToolbar.setTitle(getCurrentRoot().title);
-                mToolbarStack.setVisibility(View.GONE);
-                mToolbarStack.setAdapter(null);
-            } else {
-                mToolbar.setTitle(null);
-                mToolbarStack.setVisibility(View.VISIBLE);
-                mToolbarStack.setAdapter(mStackAdapter);
-
-                mStackListener.mIgnoreNextNavigation = true;
-                mToolbarStack.setSelection(mStackAdapter.getCount() - 1);
-            }
-        }
+    public String getDrawerTitle() {
+        return null;  // being and nothingness
     }
 
     @Override
index df3ac1b..bcf69c4 100644 (file)
@@ -22,8 +22,8 @@ import android.app.Activity;
 import android.support.v4.app.ActionBarDrawerToggle;
 import android.support.v4.widget.DrawerLayout;
 import android.support.v4.widget.DrawerLayout.DrawerListener;
-import android.view.MenuItem;
 import android.view.View;
+import android.widget.Toolbar;
 
 /**
  * A facade over the various pieces comprising "roots fragment in a Drawer".
@@ -33,13 +33,10 @@ import android.view.View;
 abstract class DrawerController implements DrawerListener {
 
     abstract void setOpen(boolean open);
-    abstract void lockOpen();
-    abstract void lockClosed();
     abstract boolean isPresent();
     abstract boolean isOpen();
-    abstract boolean isUnlocked();
-    abstract void syncState();
-    abstract boolean onOptionsItemSelected(MenuItem item);
+    abstract void setTitle(String title);
+    abstract void update();
 
     /**
      * Returns a controller suitable for {@code Layout}.
@@ -53,6 +50,8 @@ abstract class DrawerController implements DrawerListener {
         }
 
         View drawer = activity.findViewById(R.id.drawer_roots);
+        Toolbar toolbar = (Toolbar) activity.findViewById(R.id.roots_toolbar);
+
         ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                 activity,
                 layout,
@@ -60,7 +59,7 @@ abstract class DrawerController implements DrawerListener {
                 R.string.drawer_open,
                 R.string.drawer_close);
 
-        return new RuntimeDrawerController(layout, drawer, toggle);
+        return new RuntimeDrawerController(layout, drawer, toggle, toolbar);
     }
 
     /**
@@ -78,9 +77,12 @@ abstract class DrawerController implements DrawerListener {
         private final ActionBarDrawerToggle mToggle;
         private DrawerLayout mLayout;
         private View mDrawer;
+        private Toolbar mToolbar;
 
         public RuntimeDrawerController(
-                DrawerLayout layout, View drawer, ActionBarDrawerToggle toggle) {
+                DrawerLayout layout, View drawer, ActionBarDrawerToggle toggle,
+                Toolbar drawerToolbar) {
+            mToolbar = drawerToolbar;
             checkArgument(layout != null);
 
             mLayout = layout;
@@ -110,28 +112,13 @@ abstract class DrawerController implements DrawerListener {
         }
 
         @Override
-        void syncState() {
-            mToggle.syncState();
+        void setTitle(String title) {
+            mToolbar.setTitle(title);
         }
 
         @Override
-        boolean isUnlocked() {
-            return mLayout.getDrawerLockMode(mDrawer) == DrawerLayout.LOCK_MODE_UNLOCKED;
-        }
-
-        @Override
-        void lockOpen() {
-            mLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
-        }
-
-        @Override
-        void lockClosed() {
-            mLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
-        }
-
-        @Override
-        boolean onOptionsItemSelected(MenuItem item) {
-            return false;
+        void update() {
+            mToggle.syncState();
         }
 
         @Override
@@ -163,14 +150,6 @@ abstract class DrawerController implements DrawerListener {
         @Override
         void setOpen(boolean open) {}
 
-        @Override
-        void syncState() {}
-
-        @Override
-        void lockOpen() {}
-
-        @Override
-        void lockClosed() {}
 
         @Override
         boolean isOpen() {
@@ -178,19 +157,15 @@ abstract class DrawerController implements DrawerListener {
         }
 
         @Override
-        boolean isUnlocked() {
-            return true;
-        }
-
-        @Override
         boolean isPresent() {
             return false;
         }
 
         @Override
-        boolean onOptionsItemSelected(MenuItem item) {
-            return false;
-        }
+        void setTitle(String title) {}
+
+        @Override
+        void update() {}
 
         @Override
         public void onDrawerSlide(View drawerView, float slideOffset) {}
index 064535a..3aba356 100644 (file)
@@ -40,10 +40,6 @@ import android.util.Log;
 import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
-import android.view.View;
-import android.widget.BaseAdapter;
-import android.widget.Spinner;
-import android.widget.Toolbar;
 
 import com.android.documentsui.OperationDialogFragment.DialogType;
 import com.android.documentsui.RecentsProvider.ResumeColumns;
@@ -67,10 +63,6 @@ public class FilesActivity extends BaseActivity {
 
     public static final String TAG = "FilesActivity";
 
-    private Toolbar mToolbar;
-    private Spinner mToolbarStack;
-    private ItemSelectedListener mStackListener;
-    private BaseAdapter mStackAdapter;
     private DocumentClipper mClipper;
 
     public FilesActivity() {
@@ -81,17 +73,7 @@ public class FilesActivity extends BaseActivity {
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
-        mToolbar = (Toolbar) findViewById(R.id.toolbar);
-
-        mStackAdapter = new StackAdapter();
-        mStackListener = new ItemSelectedListener();
-        mToolbarStack = (Spinner) findViewById(R.id.stack);
-        mToolbarStack.setOnItemSelectedListener(mStackListener);
-
-        setActionBar(mToolbar);
-
         mClipper = new DocumentClipper(this);
-        mDrawer = DrawerController.create(this);
 
         RootsFragment.show(getFragmentManager(), null);
 
@@ -179,11 +161,11 @@ public class FilesActivity extends BaseActivity {
         // serach. Why? Because this avoid an early (undesired) load of
         // the recents root...which is the default root in other activities.
         // In Files app "Home" is the default, but it is loaded async.
-        // updateActionBar will be called once Home root is loaded.
+        // update will be called once Home root is loaded.
         // Except while searching we need this call to ensure the
         // search bits get layed out correctly.
         if (mSearchManager.isSearching()) {
-            updateActionBar();
+            mNavigator.update();
         }
     }
 
@@ -203,44 +185,8 @@ public class FilesActivity extends BaseActivity {
     }
 
     @Override
-    public void updateActionBar() {
-        final RootInfo root = getCurrentRoot();
-
-        if (mDrawer.isPresent()) {
-            mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
-            mToolbar.setNavigationContentDescription(R.string.drawer_open);
-            mToolbar.setNavigationOnClickListener(
-                    new View.OnClickListener() {
-                        @Override
-                        public void onClick(View v) {
-                            mDrawer.setOpen(true);
-                        }
-                    });
-        } else {
-            mToolbar.setNavigationIcon(
-                    root != null ? root.loadToolbarIcon(mToolbar.getContext()) : null);
-            mToolbar.setNavigationContentDescription(R.string.drawer_open);
-            mToolbar.setNavigationOnClickListener(null);
-        }
-
-        if (mSearchManager.isExpanded()) {
-            mToolbar.setTitle(null);
-            mToolbarStack.setVisibility(View.GONE);
-            mToolbarStack.setAdapter(null);
-        } else {
-            if (mState.stack.size() <= 1) {
-                mToolbar.setTitle(root.title);
-                mToolbarStack.setVisibility(View.GONE);
-                mToolbarStack.setAdapter(null);
-            } else {
-                mToolbar.setTitle(null);
-                mToolbarStack.setVisibility(View.VISIBLE);
-                mToolbarStack.setAdapter(mStackAdapter);
-
-                mStackListener.mIgnoreNextNavigation = true;
-                mToolbarStack.setSelection(mStackAdapter.getCount() - 1);
-            }
-        }
+    public String getDrawerTitle() {
+        return getResources().getString(R.string.files_label);
     }
 
     @Override
diff --git a/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java b/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java
new file mode 100644 (file)
index 0000000..ff1940a
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package com.android.documentsui;
+
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+import static com.android.documentsui.Shared.DEBUG;
+import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_LEAVE;
+
+import android.annotation.Nullable;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.RootInfo;
+
+/**
+ * A facade over the portions of the app and drawer toolbars.
+ */
+class NavigationView {
+
+    private static final String TAG = "NavigationView";
+
+    private final DrawerController mDrawer;
+    private final DocumentsToolbar mToolbar;
+    private final Spinner mBreadcrumb;
+    private final State mState;
+    private final NavigationView.Environment mEnv;
+    private final BreadcrumbAdapter mBreadcrumbAdapter;
+
+    private boolean mIgnoreNextNavigation;
+
+    public NavigationView(
+            DrawerController drawer,
+            DocumentsToolbar toolbar,
+            Spinner breadcrumb,
+            State state,
+            NavigationView.Environment env) {
+
+        mToolbar = toolbar;
+        mBreadcrumb = breadcrumb;
+        mDrawer = drawer;
+        mState = state;
+        mEnv = env;
+
+        mBreadcrumbAdapter = new BreadcrumbAdapter(mState, mEnv);
+        mToolbar.setNavigationOnClickListener(
+                new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        onNavigationIconClicked();
+                    }
+
+                });
+
+        mBreadcrumb.setOnItemSelectedListener(
+                new OnItemSelectedListener() {
+                    @Override
+                    public void onItemSelected(
+                            AdapterView<?> parent, View view, int position, long id) {
+                        onBreadcrumbItemSelected(position);
+                    }
+
+                    @Override
+                    public void onNothingSelected(AdapterView<?> parent) {}
+                });
+
+    }
+
+    private void onNavigationIconClicked() {
+        if (mDrawer.isPresent()) {
+            mDrawer.setOpen(true);
+        }
+    }
+
+    private void onBreadcrumbItemSelected(int position) {
+        if (mIgnoreNextNavigation) {
+            mIgnoreNextNavigation = false;
+            return;
+        }
+
+        while (mState.stack.size() > position + 1) {
+            mState.popDocument();
+        }
+        mEnv.refreshCurrentRootAndDirectory(ANIM_LEAVE);
+    }
+
+    void update() {
+
+        // TODO: Looks to me like this block is never getting hit.
+        if (mEnv.isSearchExpanded()) {
+            mToolbar.setTitle(null);
+            mBreadcrumb.setVisibility(View.GONE);
+            mBreadcrumb.setAdapter(null);
+            return;
+        }
+
+        mDrawer.setTitle(mEnv.getDrawerTitle());
+
+        mToolbar.setNavigationIcon(getActionBarIcon());
+        mToolbar.setNavigationContentDescription(R.string.drawer_open);
+
+        if (mState.stack.size() <= 1) {
+            showBreadcrumb(false);
+            String title = mEnv.getCurrentRoot().title;
+            if (DEBUG) Log.d(TAG, "New toolbar title is: " + title);
+            mToolbar.setTitle(title);
+        } else {
+            showBreadcrumb(true);
+            mToolbar.setTitle(null);
+            mIgnoreNextNavigation = true;
+            mBreadcrumb.setSelection(mBreadcrumbAdapter.getCount() - 1);
+        }
+
+        if (DEBUG) Log.d(TAG, "Final toolbar title is: " + mToolbar.getTitle());
+    }
+
+    private void showBreadcrumb(boolean visibility) {
+        if (visibility) {
+            mBreadcrumb.setVisibility(VISIBLE);
+            mBreadcrumb.setAdapter(mBreadcrumbAdapter);
+        } else {
+            mBreadcrumb.setVisibility(GONE);
+            mBreadcrumb.setAdapter(null);
+        }
+    }
+
+    // Hamburger if drawer is present, else root icon, or sad nullness.
+    private @Nullable Drawable getActionBarIcon() {
+        if (mDrawer.isPresent()) {
+            return mToolbar.getContext().getDrawable(R.drawable.ic_hamburger);
+        } else {
+            RootInfo root = mEnv.getCurrentRoot();
+            if (root != null) {
+                return root.loadToolbarIcon(mToolbar.getContext());
+            }
+        }
+        return null;
+    }
+
+    void revealRootsDrawer(boolean open) {
+        mDrawer.setOpen(open);
+    }
+
+    /**
+     * Class providing toolbar with runtime access to useful activity data.
+     */
+    static final class BreadcrumbAdapter extends BaseAdapter {
+
+        private Environment mEnv;
+        private State mState;
+
+        public BreadcrumbAdapter(State state, Environment env) {
+            mState = state;
+            mEnv = env;
+        }
+
+        @Override
+        public int getCount() {
+            return mState.stack.size();
+        }
+
+        @Override
+        public DocumentInfo getItem(int position) {
+            return mState.stack.get(mState.stack.size() - position - 1);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = LayoutInflater.from(parent.getContext())
+                        .inflate(R.layout.item_subdir_title, parent, false);
+            }
+
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            final DocumentInfo doc = getItem(position);
+
+            if (position == 0) {
+                final RootInfo root = mEnv.getCurrentRoot();
+                title.setText(root.title);
+            } else {
+                title.setText(doc.displayName);
+            }
+
+            return convertView;
+        }
+
+        @Override
+        public View getDropDownView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = LayoutInflater.from(parent.getContext())
+                        .inflate(R.layout.item_subdir, parent, false);
+            }
+
+            final ImageView subdir = (ImageView) convertView.findViewById(R.id.subdir);
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            final DocumentInfo doc = getItem(position);
+
+            if (position == 0) {
+                final RootInfo root = mEnv.getCurrentRoot();
+                title.setText(root.title);
+                subdir.setVisibility(View.GONE);
+            } else {
+                title.setText(doc.displayName);
+                subdir.setVisibility(View.VISIBLE);
+            }
+
+            return convertView;
+        }
+    }
+
+    interface Environment {
+        RootInfo getCurrentRoot();
+        String getDrawerTitle();
+        void refreshCurrentRootAndDirectory(int animation);
+        boolean isSearchExpanded();
+    }
+}
index fb585a6..69f54c7 100644 (file)
@@ -47,7 +47,7 @@ final class SearchManager implements
     private boolean mSearchExpanded;
     private boolean mIgnoreNextClose;
 
-    private DocumentsToolBar mActionBar;
+    private DocumentsToolbar mActionBar;
     private MenuItem mMenu;
     private SearchView mView;
 
@@ -59,7 +59,7 @@ final class SearchManager implements
         mListener = listener;
     }
 
-    public void install(DocumentsToolBar actionBar) {
+    public void install(DocumentsToolbar actionBar) {
         assert (mActionBar == null);
         mActionBar = actionBar;
         mMenu = actionBar.getSearchMenu();
index 5f04eac..1e3da6b 100644 (file)
@@ -100,6 +100,7 @@ import com.android.documentsui.model.DocumentStack;
 import com.android.documentsui.model.RootInfo;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperations;
+
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
@@ -151,7 +152,6 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi
     private String mStateKey;
 
     private int mLastSortOrder = SORT_ORDER_UNKNOWN;
-    private boolean mLastShowSize;
     private DocumentsAdapter mAdapter;
     private LoaderCallbacks<DirectoryResult> mCallbacks;
     private FragmentTuner mTuner;
@@ -428,7 +428,6 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi
 
     private void updateDisplayState() {
         State state = getDisplayState();
-        mLastShowSize = state.showSize;
         updateLayout(state.derivedMode);
         mRecView.setAdapter(mAdapter);
     }