diff --git a/packages/DocumentsUI/res/layout/drawer_layout.xml b/packages/DocumentsUI/res/layout/drawer_layout.xml index 0146f142114f3..e3def054fa0d7 100644 --- a/packages/DocumentsUI/res/layout/drawer_layout.xml +++ b/packages/DocumentsUI/res/layout/drawer_layout.xml @@ -32,7 +32,7 @@ android:layout_height="match_parent" android:orientation="vertical"> - - + diff --git a/packages/DocumentsUI/res/layout/fixed_layout.xml b/packages/DocumentsUI/res/layout/fixed_layout.xml index 0dd4a332dd6ba..8414febfb7ca4 100644 --- a/packages/DocumentsUI/res/layout/fixed_layout.xml +++ b/packages/DocumentsUI/res/layout/fixed_layout.xml @@ -27,7 +27,7 @@ android:layout_height="match_parent" android:orientation="vertical"> - - + - - + diff --git a/packages/DocumentsUI/res/values/layouts.xml b/packages/DocumentsUI/res/values/layouts.xml index 8ac1ac2bbbfc5..c9308a19ebd82 100644 --- a/packages/DocumentsUI/res/values/layouts.xml +++ b/packages/DocumentsUI/res/values/layouts.xml @@ -15,7 +15,7 @@ --> - @layout/drawer_layout + @layout/drawer_layout @layout/drawer_layout - @layout/single_pane_layout + @layout/single_pane_layout diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java index d77fc14fa1120..e72343e9a9baf 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java @@ -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.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; } @@ -341,7 +347,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); @@ -352,8 +359,7 @@ public abstract class BaseActivity extends Activity implements SearchManagerList roots.onCurrentRootChanged(); } - updateActionBar(); - + mNavigator.update(); invalidateOptionsMenu(); } @@ -489,6 +495,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; @@ -697,92 +709,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. diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java index b933d0a8744cb..815ff3db95175 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java @@ -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 @@ -330,11 +268,6 @@ public class DocumentsActivity extends BaseActivity { return true; } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return mDrawer.onOptionsItemSelected(item) || super.onOptionsItemSelected(item); - } - @Override void refreshDirectory(int anim) { final FragmentManager fm = getFragmentManager(); @@ -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 diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsToolBar.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsToolbar.java similarity index 86% rename from packages/DocumentsUI/src/com/android/documentsui/DocumentsToolBar.java rename to packages/DocumentsUI/src/com/android/documentsui/DocumentsToolbar.java index 36b764659c05d..7742cbf226e8b 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsToolBar.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsToolbar.java @@ -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); } diff --git a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java index 5cc677c4f0088..89be9107e0778 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java @@ -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 diff --git a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java index df3ac1b0e7efe..bcf69c44070a8 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java @@ -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,30 +112,15 @@ abstract class DrawerController implements DrawerListener { } @Override - void syncState() { + void setTitle(String title) { + mToolbar.setTitle(title); + } + + @Override + void update() { mToggle.syncState(); } - @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; - } - @Override public void onDrawerSlide(View drawerView, float slideOffset) { mToggle.onDrawerSlide(drawerView, slideOffset); @@ -163,34 +150,22 @@ abstract class DrawerController implements DrawerListener { @Override void setOpen(boolean open) {} - @Override - void syncState() {} - - @Override - void lockOpen() {} - - @Override - void lockClosed() {} @Override boolean isOpen() { return false; } - @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) {} diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java index 064535a6a5cba..3aba356793dfa 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java @@ -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 index 0000000000000..ff1940aea94d2 --- /dev/null +++ b/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java @@ -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(); + } +} diff --git a/packages/DocumentsUI/src/com/android/documentsui/SearchManager.java b/packages/DocumentsUI/src/com/android/documentsui/SearchManager.java index fb585a618c476..69f54c77fe8b1 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/SearchManager.java +++ b/packages/DocumentsUI/src/com/android/documentsui/SearchManager.java @@ -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(); diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java index 5f04eacc086f7..1e3da6b1ac8a4 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java @@ -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 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); }