为什么可检查的菜单项不显示复选框
Why do checkable menu items not display checkboxes
NavigationView
菜单:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group android:checkableBehavior="all">
<item
android:id="@+id/itemFoo1"
android:checkable="true"
android:title="Foo1" />
<item
android:id="@+id/itemFoo2"
android:checkable="true"
android:title="Foo2" />
</group>
</menu>
Android Studio 中的设计师显示复选框:
但是,该应用程序不显示复选框:
任何人都可以提供这方面的线索吗?
使用菜单的布局:
<com.google.android.material.navigation.NavigationView
android:id="@+id/navigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
app:menu="@menu/activity_foo_view"/>
NavigationView
的默认行为是一次 select 一个项目;例如,这通常会在抽屉布局中选择一个片段。
正如 Mike M 在评论中指出的那样;使项目可检查并不意味着它是 CheckBox
.
因此,您必须向菜单项添加 CheckBox
,有两个选项可以做到这一点:
选项 1: 使用 CheckBox
作为 app:actionViewClass
选项 2: 使用带有 app:actionLayout
的自定义布局:检查
使用 CheckBox
作为 app:actionViewClass
:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group android:checkableBehavior="all">
<item
android:id="@+id/itemFoo1"
android:checkable="true"
app:actionViewClass="android.widget.CheckBox"
android:title="Foo1" />
<item
android:id="@+id/itemFoo2"
android:checkable="true"
app:actionViewClass="android.widget.CheckBox"
android:title="Foo2" />
</group>
</menu>
点击复选框会切换其状态,但点击项目文本不会;这可以通过获取 menuItem ActionView
并使用 setChecked()
:
切换 CheckBox
以编程方式解决
private final NavigationView.OnNavigationItemSelectedListener navViewlistener = new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.itemFoo1 || id == R.id.itemFoo2) {
CheckBox actionView = (CheckBox) item.getActionView();
actionView.setChecked(!actionView.isChecked()); // Toggle the CheckBox
}
return true;
}
};
navView.setNavigationItemSelectedListener(navViewlistener);
更新
I used app:actionViewClass="android.widget.CheckBox
" for a while. The main issue is the the checkbox is independent of the item. Clicking it does not trigger NavigationItemSelectedListener
. That is the main reason I am seeking a new way.
这是对的;我们可以通过在持有 CheckBox
为 checked/unchecked.
时触发 MenuItem
单击事件来以编程方式解决此问题
但最主要的问题是,它会导致无限循环;因为我们 check/uncheck onNavigationItemSelected
中的 CheckBox
;这将触发另一个 MenuItem
点击等等。
所以,这里是一个 mIsCheckBoxClick
布尔值,并且在调用 setChecked()
之前停止 CheckBox
监听器,然后重新附加它们;所有这些都是为了避免循环:
private boolean mIsCheckBoxClick;
@Override
protected void onCreate(Bundle savedInstanceState) {
// ....... add your code
// Enable CheckBox listeners at the NavView menu items by default
addFooListeners(navView, true);
}
private void addFooListeners(final NavigationView navView, boolean enabled) {
adjustNavViewItemListener(navView.getMenu().findItem(R.id.itemFoo1), navView, enabled);
adjustNavViewItemListener(navView.getMenu().findItem(R.id.itemFoo2), navView, enabled);
}
private void adjustNavViewItemListener(final MenuItem item, final NavigationView navView, boolean enabled) {
final CheckBox fooChBox = (CheckBox) item.getActionView();
CompoundButton.OnCheckedChangeListener listener = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mIsCheckBoxClick = true;
navView.getMenu().performIdentifierAction(item.getItemId(), 0); // perform a click on MenuItem to trigger OnNavigationItemSelectedListener
}
};
fooChBox.setOnCheckedChangeListener(enabled ? listener : null);
}
private final NavigationView.OnNavigationItemSelectedListener navViewlistener = new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.itemFoo1 || id == R.id.itemFoo2) {
// Loop prevention check
if (!mIsCheckBoxClick) {
CheckBox actionView = (CheckBox) item.getActionView();
// Stop the CheckBox listeners
addFooListeners(navView, false);
actionView.setChecked(!actionView.isChecked());
// Reattach the CheckBox listeners
addFooListeners(navView, true);
}
mIsCheckBoxClick = false;
}
return true;
}
};
NavigationView
菜单:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group android:checkableBehavior="all">
<item
android:id="@+id/itemFoo1"
android:checkable="true"
android:title="Foo1" />
<item
android:id="@+id/itemFoo2"
android:checkable="true"
android:title="Foo2" />
</group>
</menu>
Android Studio 中的设计师显示复选框:
但是,该应用程序不显示复选框:
任何人都可以提供这方面的线索吗?
使用菜单的布局:
<com.google.android.material.navigation.NavigationView
android:id="@+id/navigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
app:menu="@menu/activity_foo_view"/>
NavigationView
的默认行为是一次 select 一个项目;例如,这通常会在抽屉布局中选择一个片段。
正如 Mike M 在评论中指出的那样;使项目可检查并不意味着它是 CheckBox
.
因此,您必须向菜单项添加 CheckBox
,有两个选项可以做到这一点:
选项 1: 使用
CheckBox
作为app:actionViewClass
选项 2: 使用带有
app:actionLayout
的自定义布局:检查
使用 CheckBox
作为 app:actionViewClass
:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group android:checkableBehavior="all">
<item
android:id="@+id/itemFoo1"
android:checkable="true"
app:actionViewClass="android.widget.CheckBox"
android:title="Foo1" />
<item
android:id="@+id/itemFoo2"
android:checkable="true"
app:actionViewClass="android.widget.CheckBox"
android:title="Foo2" />
</group>
</menu>
点击复选框会切换其状态,但点击项目文本不会;这可以通过获取 menuItem ActionView
并使用 setChecked()
:
CheckBox
以编程方式解决
private final NavigationView.OnNavigationItemSelectedListener navViewlistener = new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.itemFoo1 || id == R.id.itemFoo2) {
CheckBox actionView = (CheckBox) item.getActionView();
actionView.setChecked(!actionView.isChecked()); // Toggle the CheckBox
}
return true;
}
};
navView.setNavigationItemSelectedListener(navViewlistener);
更新
I used app:actionViewClass="
android.widget.CheckBox
" for a while. The main issue is the the checkbox is independent of the item. Clicking it does not triggerNavigationItemSelectedListener
. That is the main reason I am seeking a new way.
这是对的;我们可以通过在持有 CheckBox
为 checked/unchecked.
MenuItem
单击事件来以编程方式解决此问题
但最主要的问题是,它会导致无限循环;因为我们 check/uncheck onNavigationItemSelected
中的 CheckBox
;这将触发另一个 MenuItem
点击等等。
所以,这里是一个 mIsCheckBoxClick
布尔值,并且在调用 setChecked()
之前停止 CheckBox
监听器,然后重新附加它们;所有这些都是为了避免循环:
private boolean mIsCheckBoxClick;
@Override
protected void onCreate(Bundle savedInstanceState) {
// ....... add your code
// Enable CheckBox listeners at the NavView menu items by default
addFooListeners(navView, true);
}
private void addFooListeners(final NavigationView navView, boolean enabled) {
adjustNavViewItemListener(navView.getMenu().findItem(R.id.itemFoo1), navView, enabled);
adjustNavViewItemListener(navView.getMenu().findItem(R.id.itemFoo2), navView, enabled);
}
private void adjustNavViewItemListener(final MenuItem item, final NavigationView navView, boolean enabled) {
final CheckBox fooChBox = (CheckBox) item.getActionView();
CompoundButton.OnCheckedChangeListener listener = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mIsCheckBoxClick = true;
navView.getMenu().performIdentifierAction(item.getItemId(), 0); // perform a click on MenuItem to trigger OnNavigationItemSelectedListener
}
};
fooChBox.setOnCheckedChangeListener(enabled ? listener : null);
}
private final NavigationView.OnNavigationItemSelectedListener navViewlistener = new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.itemFoo1 || id == R.id.itemFoo2) {
// Loop prevention check
if (!mIsCheckBoxClick) {
CheckBox actionView = (CheckBox) item.getActionView();
// Stop the CheckBox listeners
addFooListeners(navView, false);
actionView.setChecked(!actionView.isChecked());
// Reattach the CheckBox listeners
addFooListeners(navView, true);
}
mIsCheckBoxClick = false;
}
return true;
}
};