summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt1
-rw-r--r--api/system-current.txt1
-rw-r--r--api/test-current.txt1
-rw-r--r--core/java/android/view/Menu.java7
-rw-r--r--core/java/com/android/internal/view/menu/ListMenuItemView.java92
-rw-r--r--core/java/com/android/internal/view/menu/MenuAdapter.java8
-rw-r--r--core/java/com/android/internal/view/menu/MenuBuilder.java16
-rw-r--r--core/java/com/android/internal/view/menu/SubMenuBuilder.java10
-rw-r--r--core/res/res/layout/popup_menu_item_layout.xml104
-rw-r--r--core/res/res/values/symbols.xml1
10 files changed, 167 insertions, 74 deletions
diff --git a/api/current.txt b/api/current.txt
index c147254494dd..7ced6a05643b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -44968,6 +44968,7 @@ package android.view {
method public abstract void removeGroup(int);
method public abstract void removeItem(int);
method public abstract void setGroupCheckable(int, boolean, boolean);
+ method public default void setGroupDividerEnabled(boolean);
method public abstract void setGroupEnabled(int, boolean);
method public abstract void setGroupVisible(int, boolean);
method public abstract void setQwertyMode(boolean);
diff --git a/api/system-current.txt b/api/system-current.txt
index ef12bfb4be1a..8f98e856391b 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -48575,6 +48575,7 @@ package android.view {
method public abstract void removeGroup(int);
method public abstract void removeItem(int);
method public abstract void setGroupCheckable(int, boolean, boolean);
+ method public default void setGroupDividerEnabled(boolean);
method public abstract void setGroupEnabled(int, boolean);
method public abstract void setGroupVisible(int, boolean);
method public abstract void setQwertyMode(boolean);
diff --git a/api/test-current.txt b/api/test-current.txt
index 7203cad1cf32..7aac902c3d36 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -45414,6 +45414,7 @@ package android.view {
method public abstract void removeGroup(int);
method public abstract void removeItem(int);
method public abstract void setGroupCheckable(int, boolean, boolean);
+ method public default void setGroupDividerEnabled(boolean);
method public abstract void setGroupEnabled(int, boolean);
method public abstract void setGroupVisible(int, boolean);
method public abstract void setQwertyMode(boolean);
diff --git a/core/java/android/view/Menu.java b/core/java/android/view/Menu.java
index a8ea4dc1b8a0..6d1f740ad1da 100644
--- a/core/java/android/view/Menu.java
+++ b/core/java/android/view/Menu.java
@@ -451,5 +451,10 @@ public interface Menu {
* will use numeric shortcuts.
*/
public void setQwertyMode(boolean isQwerty);
-}
+ /**
+ * Enable or disable the group dividers.
+ */
+ default void setGroupDividerEnabled(boolean groupDividerEnabled) {
+ }
+} \ No newline at end of file
diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java
index 83a2838be07e..f76c7247aba9 100644
--- a/core/java/com/android/internal/view/menu/ListMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java
@@ -16,14 +16,18 @@
package com.android.internal.view.menu;
+import com.android.internal.R;
+
import android.content.Context;
import android.content.res.TypedArray;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.AbsListView;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
@@ -34,25 +38,28 @@ import android.widget.TextView;
/**
* The item view for each item in the ListView-based MenuViews.
*/
-public class ListMenuItemView extends LinearLayout implements MenuView.ItemView {
+public class ListMenuItemView extends LinearLayout
+ implements MenuView.ItemView, AbsListView.SelectionBoundsAdjuster {
private static final String TAG = "ListMenuItemView";
- private MenuItemImpl mItemData;
-
+ private MenuItemImpl mItemData;
+
private ImageView mIconView;
private RadioButton mRadioButton;
private TextView mTitleView;
private CheckBox mCheckBox;
private TextView mShortcutView;
private ImageView mSubMenuArrowView;
-
+ private ImageView mGroupDivider;
+
private Drawable mBackground;
private int mTextAppearance;
private Context mTextAppearanceContext;
private boolean mPreserveIconSpacing;
private Drawable mSubMenuArrow;
-
+ private boolean mHasListDivider;
+
private int mMenuType;
-
+
private LayoutInflater mInflater;
private boolean mForceShowIcon;
@@ -71,8 +78,14 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
com.android.internal.R.styleable.MenuView_preserveIconSpacing, false);
mTextAppearanceContext = context;
mSubMenuArrow = a.getDrawable(com.android.internal.R.styleable.MenuView_subMenuArrow);
-
+
+ final TypedArray b = context.getTheme()
+ .obtainStyledAttributes(null, new int[] { com.android.internal.R.attr.divider },
+ com.android.internal.R.attr.dropDownListViewStyle, 0);
+ mHasListDivider = b.hasValue(0);
+
a.recycle();
+ b.recycle();
}
public ListMenuItemView(Context context, AttributeSet attrs, int defStyleAttr) {
@@ -86,20 +99,21 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
@Override
protected void onFinishInflate() {
super.onFinishInflate();
-
+
setBackgroundDrawable(mBackground);
-
+
mTitleView = findViewById(com.android.internal.R.id.title);
if (mTextAppearance != -1) {
mTitleView.setTextAppearance(mTextAppearanceContext,
mTextAppearance);
}
-
+
mShortcutView = findViewById(com.android.internal.R.id.shortcut);
mSubMenuArrowView = findViewById(com.android.internal.R.id.submenuarrow);
if (mSubMenuArrowView != null) {
mSubMenuArrowView.setImageDrawable(mSubMenuArrow);
}
+ mGroupDivider = findViewById(com.android.internal.R.id.group_divider);
}
public void initialize(MenuItemImpl itemData, int menuType) {
@@ -124,13 +138,13 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
public void setTitle(CharSequence title) {
if (title != null) {
mTitleView.setText(title);
-
+
if (mTitleView.getVisibility() != VISIBLE) mTitleView.setVisibility(VISIBLE);
} else {
if (mTitleView.getVisibility() != GONE) mTitleView.setVisibility(GONE);
}
}
-
+
public MenuItemImpl getItemData() {
return mItemData;
}
@@ -139,11 +153,11 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
if (!checkable && mRadioButton == null && mCheckBox == null) {
return;
}
-
+
// Depending on whether its exclusive check or not, the checkbox or
// radio button will be the one in use (and the other will be otherCompoundButton)
final CompoundButton compoundButton;
- final CompoundButton otherCompoundButton;
+ final CompoundButton otherCompoundButton;
if (mItemData.isExclusiveCheckable()) {
if (mRadioButton == null) {
@@ -158,15 +172,15 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
compoundButton = mCheckBox;
otherCompoundButton = mRadioButton;
}
-
+
if (checkable) {
compoundButton.setChecked(mItemData.isChecked());
-
+
final int newVisibility = checkable ? VISIBLE : GONE;
if (compoundButton.getVisibility() != newVisibility) {
compoundButton.setVisibility(newVisibility);
}
-
+
// Make sure the other compound button isn't visible
if (otherCompoundButton != null && otherCompoundButton.getVisibility() != GONE) {
otherCompoundButton.setVisibility(GONE);
@@ -176,10 +190,10 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
if (mRadioButton != null) mRadioButton.setVisibility(GONE);
}
}
-
+
public void setChecked(boolean checked) {
CompoundButton compoundButton;
-
+
if (mItemData.isExclusiveCheckable()) {
if (mRadioButton == null) {
insertRadioButton();
@@ -191,7 +205,7 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
}
compoundButton = mCheckBox;
}
-
+
compoundButton.setChecked(checked);
}
@@ -213,21 +227,21 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
mShortcutView.setVisibility(newVisibility);
}
}
-
+
public void setIcon(Drawable icon) {
final boolean showIcon = mItemData.shouldShowIcon() || mForceShowIcon;
if (!showIcon && !mPreserveIconSpacing) {
return;
}
-
+
if (mIconView == null && icon == null && !mPreserveIconSpacing) {
return;
}
-
+
if (mIconView == null) {
insertIconView();
}
-
+
if (icon != null || mPreserveIconSpacing) {
mIconView.setImageDrawable(showIcon ? icon : null);
@@ -238,7 +252,7 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
mIconView.setVisibility(GONE);
}
}
-
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mIconView != null && mPreserveIconSpacing) {
@@ -258,7 +272,7 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
this, false);
addView(mIconView, 0);
}
-
+
private void insertRadioButton() {
LayoutInflater inflater = getInflater();
mRadioButton =
@@ -266,7 +280,7 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
this, false);
addView(mRadioButton);
}
-
+
private void insertCheckBox() {
LayoutInflater inflater = getInflater();
mCheckBox =
@@ -282,7 +296,7 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
public boolean showsIcon() {
return mForceShowIcon;
}
-
+
private LayoutInflater getInflater() {
if (mInflater == null) {
mInflater = LayoutInflater.from(mContext);
@@ -298,4 +312,26 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
info.setCanOpenPopup(true);
}
}
+
+ /**
+ * Enable or disable group dividers for this view.
+ */
+ public void setGroupDividerEnabled(boolean groupDividerEnabled) {
+ // If mHasListDivider is true, disabling the groupDivider.
+ // Otherwise, checking enbling it according to groupDividerEnabled flag.
+ mGroupDivider.setVisibility(!mHasListDivider
+ && groupDividerEnabled ? View.VISIBLE : View.GONE);
+ }
+
+ @Override
+ public void adjustListItemSelectionBounds(Rect rect) {
+ if (mGroupDivider.getVisibility() == View.VISIBLE) {
+ // groupDivider is a part of MenuItemListView.
+ // If ListMenuItem with divider enabled is hovered/clicked, divider also gets selected.
+ // Clipping the selector bounds from the top divider portion when divider is enabled,
+ // so that divider does not get selected on hover or click.
+ final LayoutParams lp = (LayoutParams) mGroupDivider.getLayoutParams();
+ rect.top += mGroupDivider.getHeight() + lp.topMargin + lp.bottomMargin;
+ }
+ }
}
diff --git a/core/java/com/android/internal/view/menu/MenuAdapter.java b/core/java/com/android/internal/view/menu/MenuAdapter.java
index 673cfd12d878..2834d39a4f98 100644
--- a/core/java/com/android/internal/view/menu/MenuAdapter.java
+++ b/core/java/com/android/internal/view/menu/MenuAdapter.java
@@ -81,6 +81,14 @@ public class MenuAdapter extends BaseAdapter {
convertView = mInflater.inflate(ITEM_LAYOUT, parent, false);
}
+ final int currGroupId = getItem(position).getGroupId();
+ final int prevGroupId =
+ position - 1 >= 0 ? getItem(position - 1).getGroupId() : currGroupId;
+ // Show a divider if adjacent items are in different groups.
+ ((ListMenuItemView) convertView)
+ .setGroupDividerEnabled(mAdapterMenu.isGroupDividerEnabled()
+ && (currGroupId != prevGroupId));
+
MenuView.ItemView itemView = (MenuView.ItemView) convertView;
if (mForceShowIcon) {
((ListMenuItemView) convertView).setForceShowIcon(true);
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index 7eb0f4dbddc7..b53459e072d4 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -156,7 +156,12 @@ public class MenuBuilder implements Menu {
* Currently expanded menu item; must be collapsed when we clear.
*/
private MenuItemImpl mExpandedItem;
-
+
+ /**
+ * Whether group dividers are enabled.
+ */
+ private boolean mGroupDividerEnabled = false;
+
/**
* Called by menu to notify of close and selection changes.
*/
@@ -462,6 +467,15 @@ public class MenuBuilder implements Menu {
return addSubMenu(group, id, categoryOrder, mResources.getString(title));
}
+ @Override
+ public void setGroupDividerEnabled(boolean groupDividerEnabled) {
+ mGroupDividerEnabled = groupDividerEnabled;
+ }
+
+ public boolean isGroupDividerEnabled() {
+ return mGroupDividerEnabled;
+ }
+
public int addIntentOptions(int group, int id, int categoryOrder, ComponentName caller,
Intent[] specifics, Intent intent, int flags, MenuItem[] outSpecificItems) {
PackageManager pm = mContext.getPackageManager();
diff --git a/core/java/com/android/internal/view/menu/SubMenuBuilder.java b/core/java/com/android/internal/view/menu/SubMenuBuilder.java
index cf741bf5bb02..897440ebf893 100644
--- a/core/java/com/android/internal/view/menu/SubMenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/SubMenuBuilder.java
@@ -130,4 +130,14 @@ public class SubMenuBuilder extends MenuBuilder implements SubMenu {
}
return super.getActionViewStatesKey() + ":" + itemId;
}
+
+ @Override
+ public void setGroupDividerEnabled(boolean groupDividerEnabled) {
+ mParentMenu.setGroupDividerEnabled(groupDividerEnabled);
+ }
+
+ @Override
+ public boolean isGroupDividerEnabled() {
+ return mParentMenu.isGroupDividerEnabled();
+ }
}
diff --git a/core/res/res/layout/popup_menu_item_layout.xml b/core/res/res/layout/popup_menu_item_layout.xml
index 8b8c93afffbd..3eecb36f0ea6 100644
--- a/core/res/res/layout/popup_menu_item_layout.xml
+++ b/core/res/res/layout/popup_menu_item_layout.xml
@@ -16,56 +16,72 @@
<com.android.internal.view.menu.ListMenuItemView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="?attr/dropdownListPreferredItemHeight"
+ android:layout_height="wrap_content"
android:minWidth="196dip"
- android:paddingEnd="16dip">
-
+ android:orientation="vertical" >
+
+ <ImageView
+ android:id="@+id/group_divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:layout_marginTop="4dip"
+ android:layout_marginBottom="4dip"
+ android:background="@drawable/list_divider_material" />
+
<!-- Icon will be inserted here. -->
-
- <!-- The title and summary have some gap between them, and this 'group' should be centered vertically. -->
- <RelativeLayout
- android:layout_width="0dip"
- android:layout_weight="1"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginStart="16dip"
- android:duplicateParentState="true">
-
- <TextView
- android:id="@+id/title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:layout_alignParentStart="true"
- android:textAppearance="?attr/textAppearanceLargePopupMenu"
- android:singleLine="true"
- android:duplicateParentState="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- android:textAlignment="viewStart" />
- <TextView
- android:id="@+id/shortcut"
- android:layout_width="wrap_content"
+ <!-- The title and summary have some gap between them,
+ and this 'group' should be centered vertically. -->
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="?attr/dropdownListPreferredItemHeight"
+ android:paddingEnd="16dip"
+ android:duplicateParentState="true" >
+
+ <LinearLayout
+ android:layout_width="0dip"
+ android:layout_weight="1"
android:layout_height="wrap_content"
- android:layout_below="@id/title"
- android:layout_alignParentStart="true"
- android:textAppearance="?attr/textAppearanceSmallPopupMenu"
- android:singleLine="true"
- android:duplicateParentState="true"
- android:textAlignment="viewStart" />
+ android:layout_gravity="center_vertical"
+ android:layout_marginStart="16dip"
+ android:duplicateParentState="true">
- </RelativeLayout>
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentStart="true"
+ android:textAppearance="?attr/textAppearanceLargePopupMenu"
+ android:singleLine="true"
+ android:duplicateParentState="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:textAlignment="viewStart" />
- <ImageView
- android:id="@+id/submenuarrow"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginStart="8dp"
- android:scaleType="center"
- android:visibility="gone" />
+ <TextView
+ android:id="@+id/shortcut"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/title"
+ android:layout_alignParentStart="true"
+ android:textAppearance="?attr/textAppearanceSmallPopupMenu"
+ android:singleLine="true"
+ android:duplicateParentState="true"
+ android:textAlignment="viewStart" />
+
+ </LinearLayout>
+
+ <ImageView
+ android:id="@+id/submenuarrow"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginStart="8dp"
+ android:scaleType="center"
+ android:visibility="gone" />
+ </LinearLayout>
<!-- Checkbox, and/or radio button will be inserted here. -->
-
+
</com.android.internal.view.menu.ListMenuItemView>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c80d2473625b..eb314399e822 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -74,6 +74,7 @@
<java-symbol type="id" name="fillInIntent" />
<java-symbol type="id" name="find" />
<java-symbol type="id" name="fullscreenArea" />
+ <java-symbol type="id" name="group_divider" />
<java-symbol type="id" name="hard_keyboard_section" />
<java-symbol type="id" name="hard_keyboard_switch" />
<java-symbol type="id" name="headers" />