Merge "Normalize toolbar management."

This commit is contained in:
Steve McKay
2016-02-04 04:20:55 +00:00
committed by Android (Google) Code Review
13 changed files with 344 additions and 354 deletions

View 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"/>

View 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>
<LinearLayout
android:layout_width="match_parent"

View 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"/>

View 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>

View 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;
}
@@ -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.

View 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
@@ -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

View File

@@ -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);
}

View 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

View 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,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) {}

View 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

View File

@@ -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();
}
}

View 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();

View 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);
}