我有一个NavigationView,里面有很多项目。
我试图更改所选(已选中)项目的背景。我有一个选择器,可以更改itemTextColor,并且工作正常。
我有一个可绘制的资源:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@color/selected_item_accent"/>
</shape>
我的选择器:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/nav_view_background" android:state_checked="true" />
<item android:drawable="@drawable/nav_view_background" android:state_pressed="true" />
<item android:drawable="@android:color/transparent" />
</selector>
最后是NavigationView
<android.support.design.widget.NavigationView
android:id="@+id/navView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@color/window_background"
app:itemTextColor="@drawable/selector_nav_view_text"
app:itemBackground="@drawable/selector_nav_view_background"
app:headerLayout="@layout/app_nav_header" />
按下状态按预期工作,但所选项目背景不会改变。
我想知道我在这里做错了什么。感谢。
答案 0 :(得分:2)
Change the color of a checked menu item in a navigation drawer
但我不认为它会起作用,因为在源代码中,它从未设置RecyclerView的真实项目(不是菜单项)。这意味着当您单击该项目时,仅选中菜单项。所以当然背景不会改变。
看起来NavigationView不是为你想要的而设计的。设计人员可能会认为,当用户点击NavigationView中的项目时,它应该关闭,应用程序会将用户导航到另一个页面。因此不需要setChecked()
;
但是使用反射有一种解决方法。 核心代码就像
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_menu_item_1:
// find out the position of the menu item in Adapter
// in my test demo, positionInAdapter = positionInMenu + 2
int positionInAdapter = NUMBER;
try {
Field presenterField = mNavigationSpan.getClass().getDeclaredField("mPresenter");
presenterField.setAccessible(true);
// get NavigationMenuPresenter from your NavigationView
NavigationMenuPresenter presenter = (NavigationMenuPresenter) presenterField.get(mNavigationSpan);
Field menuViewField = presenter.getClass().getDeclaredField("mMenuView");
menuViewField.setAccessible(true);
// get NavigationMenuView from NavigationMenuPresenter, it is a RecyclerView which contains the real items user seen
NavigationMenuView menuView = (NavigationMenuView) menuViewField.get(presenter);
// using RecyclerView.findViewHolderForAdapterPosition() to get the ViewHolder, then you can get the itemView
menuView.findViewHolderForAdapterPosition(positionInAdapter).itemView.setSelected(true);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
break;
}
return false;
}
});
setChecked
方法的视图,所以我们使用选中而不是选中;所以你需要更改你的background drawable xml,只需将android:state_checked
更改为android:state_selected