Add MenuItem.setVisible(boolean)
It's a very common operation, but I had worked around it by calling
setMenuItems() repeatedly before. Now it's being requested for MediaCenter.
Fixes: 141574504
Test: Manually
Change-Id: Id58a041f8305932dcfea0bac0f6d87aaf3292f41
diff --git a/car-ui-lib/src/com/android/car/ui/toolbar/MenuItem.java b/car-ui-lib/src/com/android/car/ui/toolbar/MenuItem.java
index 7a57e36..4d0c1da 100644
--- a/car-ui-lib/src/com/android/car/ui/toolbar/MenuItem.java
+++ b/car-ui-lib/src/com/android/car/ui/toolbar/MenuItem.java
@@ -67,6 +67,7 @@
private DisplayBehavior mDisplayBehavior;
private boolean mIsEnabled;
private boolean mIsChecked;
+ private boolean mIsVisible;
private View mView;
@@ -80,6 +81,7 @@
mDisplayBehavior = builder.mDisplayBehavior;
mIsEnabled = builder.mIsEnabled;
mIsChecked = builder.mIsChecked;
+ mIsVisible = builder.mIsVisible;
mId = builder.mId;
}
@@ -129,6 +131,21 @@
}
}
+ /** Returns whether or not the MenuItem is visible */
+ public boolean isVisible() {
+ return mIsVisible;
+ }
+
+ /** Sets whether or not the MenuItem is visible */
+ public void setVisible(boolean visible) {
+ mIsVisible = visible;
+
+ // The toolbar will change the visibility of the view
+ if (mListener != null) {
+ mListener.onMenuItemChanged(this);
+ }
+ }
+
/** Gets the title of this MenuItem. */
public CharSequence getTitle() {
return mTitle;
@@ -146,7 +163,7 @@
}
if (mListener != null) {
- mListener.onMenuItemTitleChanged(this, mTitle);
+ mListener.onMenuItemChanged(this);
}
}
@@ -211,6 +228,7 @@
private boolean mIsEnabled = true;
private boolean mIsCheckable = false;
private boolean mIsChecked = false;
+ private boolean mIsVisible = true;
private int mCustomLayoutId;
private int mId;
@@ -241,6 +259,12 @@
return this;
}
+ /** Sets whether the MenuItem is visible or not. Default true. */
+ public Builder setVisible(boolean visible) {
+ mIsVisible = visible;
+ return this;
+ }
+
/**
* Sets a custom layout to use for this MenuItem.
*
@@ -367,8 +391,8 @@
/** Listener for {@link Toolbar} to update when this MenuItem changes */
interface Listener {
- /** Called when the MenuItem's title is changed. For use only by {@link Toolbar} */
- void onMenuItemTitleChanged(MenuItem item, CharSequence title);
+ /** Called when the MenuItem is changed. For use only by {@link Toolbar} */
+ void onMenuItemChanged(MenuItem item);
}
void setListener(Listener listener) {
@@ -404,6 +428,10 @@
mView.setId(getId());
}
+ if (!mIsVisible) {
+ mView.setVisibility(View.GONE);
+ }
+
recursiveSetEnabled(mView, isEnabled());
mView.setOnClickListener(mViewOnClickListener);
return mView;
diff --git a/car-ui-lib/src/com/android/car/ui/toolbar/Toolbar.java b/car-ui-lib/src/com/android/car/ui/toolbar/Toolbar.java
index 1659f36..e656aa0 100644
--- a/car-ui-lib/src/com/android/car/ui/toolbar/Toolbar.java
+++ b/car-ui-lib/src/com/android/car/ui/toolbar/Toolbar.java
@@ -134,16 +134,27 @@
private SearchView mSearchView;
private boolean mHasLogo = false;
private boolean mShowMenuItemsWhileSearching;
- private View mSearchButton;
+ private MenuItem mSearchMenuItem;
private State mState = State.HOME;
private NavButtonMode mNavButtonMode = NavButtonMode.BACK;
@NonNull
private List<MenuItem> mMenuItems = Collections.emptyList();
private List<MenuItem> mOverflowItems = new ArrayList<>();
- private MenuItem.Listener mMenuItemListener = (item, title) -> {
+ private MenuItem.Listener mMenuItemListener = (item) -> {
if (item.getDisplayBehavior() == MenuItem.DisplayBehavior.NEVER) {
createOverflowDialog();
+ } else {
+ View view = item.getView();
+ if (view != null) {
+ if (item.getId() == R.id.search) {
+ view.setVisibility(mState != State.SEARCH && item.isVisible() ? VISIBLE : GONE);
+ } else {
+ view.setVisibility(item.isVisible() ? VISIBLE : GONE);
+ }
+ }
}
+
+ setState(getState());
};
private AlertDialog mOverflowDialog;
@@ -488,6 +499,7 @@
mOverflowItems.clear();
mMenuItemsContainer.removeAllViews();
+ mSearchMenuItem = null;
for (MenuItem item : items) {
item.setListener(mMenuItemListener);
@@ -498,13 +510,15 @@
// Add views with index 0 so that they are added right-to-left
mMenuItemsContainer.addView(menuItemView, 0);
+
+ if (item.getId() == R.id.search) {
+ mSearchMenuItem = item;
+ }
}
}
createOverflowDialog();
- mSearchButton = mMenuItemsContainer.findViewById(R.id.search);
-
setState(mState);
}
@@ -514,13 +528,26 @@
return mMenuItems;
}
+ private int countVisibleOverflowItems() {
+ int numVisibleItems = 0;
+ for (MenuItem item : mOverflowItems) {
+ if (item.isVisible()) {
+ numVisibleItems++;
+ }
+ }
+ return numVisibleItems;
+ }
+
private void createOverflowDialog() {
// TODO(b/140564530) Use a carui alert with a (paged)recyclerview here
// TODO(b/140563930) Support enabled/disabled overflow items
- CharSequence[] itemTitles = new CharSequence[mOverflowItems.size()];
- for (int i = 0; i < mOverflowItems.size(); i++) {
- itemTitles[i] = mOverflowItems.get(i).getTitle();
+ CharSequence[] itemTitles = new CharSequence[countVisibleOverflowItems()];
+ int i = 0;
+ for (MenuItem item : mOverflowItems) {
+ if (item.isVisible()) {
+ itemTitles[i++] = item.getTitle();
+ }
}
mOverflowDialog = new AlertDialog.Builder(getContext())
@@ -622,9 +649,14 @@
mSearchView.setVisibility(state == State.SEARCH ? VISIBLE : GONE);
boolean showButtons = state != State.SEARCH || mShowMenuItemsWhileSearching;
mMenuItemsContainer.setVisibility(showButtons ? VISIBLE : GONE);
- mOverflowButton.setVisibility(showButtons && mOverflowItems.size() > 0 ? VISIBLE : GONE);
- if (mSearchButton != null) {
- mSearchButton.setVisibility(state != State.SEARCH ? VISIBLE : GONE);
+ mOverflowButton.setVisibility(showButtons && countVisibleOverflowItems() > 0
+ ? VISIBLE : GONE);
+ if (mSearchMenuItem != null) {
+ View searchView = mSearchMenuItem.getView();
+ if (searchView != null) {
+ searchView.setVisibility(mState != State.SEARCH && mSearchMenuItem.isVisible()
+ ? VISIBLE : GONE);
+ }
}
mCustomViewContainer.setVisibility(state == State.SUBPAGE_CUSTOM ? VISIBLE : GONE);
if (state != State.SUBPAGE_CUSTOM) {
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/toolbar/ToolbarActivity.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/toolbar/ToolbarActivity.java
index a39dc89..531c3a8 100644
--- a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/toolbar/ToolbarActivity.java
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/toolbar/ToolbarActivity.java
@@ -16,11 +16,14 @@
package com.android.car.ui.paintbooth.toolbar;
import android.app.Activity;
+import android.app.AlertDialog;
import android.os.Bundle;
+import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
+import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -70,6 +73,39 @@
toolbar.setMenuItems(mMenuItems);
}));
+ Mutable<Integer> overflowCounter = new Mutable<>(1);
+ mButtons.add(Pair.create("Add overflow menu item", v -> {
+ mMenuItems.add(new MenuItem.Builder(this)
+ .setTitle("Foo " + overflowCounter.value)
+ .setOnClickListener(i ->
+ Toast.makeText(this, "Clicked", Toast.LENGTH_SHORT).show())
+ .setDisplayBehavior(MenuItem.DisplayBehavior.NEVER)
+ .build());
+ toolbar.setMenuItems(mMenuItems);
+ overflowCounter.value++;
+ }));
+
+ mButtons.add(Pair.create("Toggle menu item visibility", v -> {
+ EditText textBox = new EditText(this);
+ textBox.setInputType(InputType.TYPE_CLASS_NUMBER);
+ new AlertDialog.Builder(this)
+ .setView(textBox)
+ .setTitle("Enter the index of the MenuItem to toggle")
+ .setPositiveButton("Ok", ((dialog, which) -> {
+ try {
+ MenuItem item = mMenuItems.get(
+ Integer.parseInt(textBox.getText().toString()));
+ item.setVisible(!item.isVisible());
+ } catch (NumberFormatException | IndexOutOfBoundsException e) {
+ Toast.makeText(this, "Invalid index \""
+ + textBox.getText().toString()
+ + "\", valid range is 0 to " + (mMenuItems.size() - 1),
+ Toast.LENGTH_LONG).show();
+ }
+ }))
+ .show();
+ }));
+
mButtons.add(Pair.create("Toggle nav button mode", v -> {
if (toolbar.getNavButtonMode() == Toolbar.NavButtonMode.BACK) {
toolbar.setNavButtonMode(Toolbar.NavButtonMode.CLOSE);
@@ -143,4 +179,17 @@
((ViewHolder) holder).bind(pair.first, pair.second);
}
};
+
+ /** For changing values from lambdas */
+ public static final class Mutable<E> {
+ public E value;
+
+ public Mutable() {
+ value = null;
+ }
+
+ public Mutable(E value) {
+ this.value = value;
+ }
+ }
}