Android 所选项目的导航抽屉项目背景颜色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22374660/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:54:10  来源:igfitidea点击:

Navigation Drawer item background colour for selected item

androidandroid-listviewandroid-navigation

提问by RyanJohnstone

I used Android Studio to implement the Navigation Drawer and I can't get the blue colour that is used to show which section we're currently in to change.

我使用 Android Studio 实现了 Navigation Drawer,但无法获得用于显示我们当前要更改的部分的蓝色。

I've tried numerous things, I'm currently using a listSelector which looks like:

我已经尝试了很多东西,我目前正在使用一个 listSelector ,它看起来像:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_activated="true" android:drawable="@color/selected" />
    <item android:state_pressed="true" android:drawable="@color/highlight" />


</selector>

I've also tried state_checked. state_pressedworks in this situation but the currently selected item is still blue.

我也试过了state_checkedstate_pressed在这种情况下有效,但当前选定的项目仍然是蓝色的。

EDIT: I've been examining this more and when the adapter is created the context that is passed is getActionBar().getThemedContext()so I'm thinking if I can find the right attribute to assign to my actionbar style I can change it from there. I've tried a few different attributes with no luck. Does anyone know the exact attribute?

编辑:我一直在研究这个,当创建适配器时,传递的上下文是getActionBar().getThemedContext()这样的,所以我在想是否可以找到正确的属性来分配给我的操作栏样式,我可以从那里更改它。我尝试了一些不同的属性,但没有运气。有谁知道确切的属性吗?

I've also realised if I put

我也意识到如果我把

<item name="android:activatedBackgroundIndicator">@drawable/nav_listview_selector</item>

<item name="android:activatedBackgroundIndicator">@drawable/nav_listview_selector</item>

in the main part of my theme and change getActionBar().getThemedContext()for getActivity.getBaseContextthen I can change the color but I don't think this is the correct way. I think the themed context should be used. So if anyone knows where the activatedBackgroundIndicatorcould be put so that it would be used in getActionBar.getThemedContext()

在我的主题和变化的主要部分getActionBar().getThemedContext()getActivity.getBaseContext话,我可以改变颜色,但我不认为这是正确的方式。我认为应该使用主题上下文。因此,如果有人知道activatedBackgroundIndicator可以将其放在何处以便将其用于getActionBar.getThemedContext()

EDIT2:

编辑2:

So the text view used for the listview is one within the SDK it looks like this:

所以用于列表视图的文本视图是 SDK 中的一个,它看起来像这样:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
    android:background="?android:attr/activatedBackgroundIndicator"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"
/>

So I tried modifying the "?android:attr/activatedBackgroundIndicator"at the theme level but it has no effect for checked/selected/activated but it does for pressed. Does anyone know why this is? And how I can change it?

所以我尝试"?android:attr/activatedBackgroundIndicator"在主题级别修改 ,但它对选中/选择/激活没有影响,但它对按下有影响。有人知道为什么是这样吗?我该如何改变它?

采纳答案by RyanJohnstone

Still not sure why it is that it doesn't work. But the way I found around it is to use my own simple_list_item_activatedlayout to be passed to the ArrayAdapter which was basically the same except for setting the text colour to white. I then replaced getActionBar().getThemedContext()with getActivity().getBaseContext()and it now has an effect.

仍然不确定为什么它不起作用。但是我发现它的方法是使用我自己的simple_list_item_activated布局传递给 ArrayAdapter ,除了将文本颜色设置为白色之外,它基本上是相同的。然后我替换getActionBar().getThemedContext()getActivity().getBaseContext()它现在有效果。

This may not be the correct way and may have repercussions in the future, but for now I have it working the way I want it to.

这可能不是正确的方法,并且可能在未来产生影响,但现在我让它按照我想要的方式工作。

回答by Ashraf Alshahawy

To solve this problem:

要解决这个问题:

1- You don't need android:listSelector under your ListView.

1- 您的 ListView 下不需要 android:listSelector。

2- Open (or Create) styles.xmlunder (res/values).

2-在 (res/values) 下打开(或创建)styles.xml

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="android:activatedBackgroundIndicator">@drawable/drawer_list_selector</item>
</style>

3- Under res/drawable folder create drawer_list_selector.xmlfile

3- 在 res/drawable 文件夹下创建drawer_list_selector.xml文件

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/light_gray_color" />
    <item android:state_activated="true" android:drawable="@drawable/red_color" />
    <item android:drawable="@android:color/transparent" />
</selector>

4- Under res/drawable create red_color.xml/ light_gray_color.xml(or any other name) and add your desired Hex color:

4- 在 res/drawable 下创建red_color.xml/ light_gray_color.xml(或任何其他名称)并添加所需的十六进制颜色:

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#C8FF0000"/>
</shape>

5- Open your project AndroidManifest.xmland add android:theme tag (if not exist)

5- 打开您的项目AndroidManifest.xml并添加 android:theme 标签(如果不存在)

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

Reference / Credit: Changing Navigation Drawer Selected Item Color from default blue

参考/信用:更改导航抽屉所选项目颜色从默认蓝色

回答by user3570407

To change the "Navigation Drawer item background colour for selected item" you could do it with the attribut:

要更改“所选项目的导航抽屉项目背景颜色”,您可以使用以下属性:

colorControlHighlight

颜色控制高亮

In your "styles.xml" it could look like this:

在您的“ styles.xml”中,它可能如下所示:

<style name="YourStyleNameFor.NavigationDrawer" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorControlHighlight">@color/your_highlight_color</item>
</style>

Don't forget to apply your Stylein the tag:

不要忘记 在标签中应用您的样式

android.support.design.widget.NavigationView

android.support.design.widget.NavigationView

For example in your activity_main.xmlit could look like this:

例如,在您的activity_main.xml 中,它可能如下所示:

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/navigationdrawer_header"

    <!-- the following line referes to your style  -->
    app:theme="@style/YourThemeNameFor.NavigationDrawer"

    <!-- the following two lines are maybe also interesting for you -->
    app:itemIconTint="@color/gray3"
    app:itemTextColor="@color/gray3"

    app:menu="@menu/navigationdrawer_main" />

回答by Mithun Biswas

This is working for me:

这对我有用:

  1. First define a drawable item_bg.xmlas:

    <?xml version="1.0" encoding="utf-8"?>
        <selector xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:state_checked="true" android:drawable="@drawable/nav_menu_bg" />
        </selector>
    
  2. Then use this drawable in navigation_main_layout.xmlas:

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:itemBackground="@drawable/item_bg"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_navigation"
        app:menu="@menu/navigation_main_layout_drawer" />
    
  1. 首先定义一个drawable item_bg.xml

    <?xml version="1.0" encoding="utf-8"?>
        <selector xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:state_checked="true" android:drawable="@drawable/nav_menu_bg" />
        </selector>
    
  2. 然后将此drawablenavigation_main_layout.xml用作:

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:itemBackground="@drawable/item_bg"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_navigation"
        app:menu="@menu/navigation_main_layout_drawer" />
    

回答by Syed Raza Mehdi

here is how i have done and it is working, the brief conceptis maintain the positionof selected item in adapterand call notifyDataSetChangedon calling notifyDatasetChangedthe getViewmethod is called again and in get view check the position on the selected position change the background view. Here is the code :

这是我如何完成并且它正在工作,简短的概念是在适配器中保持所选项目的位置,并再次调用调用该方法,并在获取视图中检查所选位置上的位置更改背景视图。这是代码:notifyDataSetChangednotifyDatasetChangedgetView

Adapter of NavigationDrawer List View

NavigationDrawer 列表视图的适配器

public class MenuAdapter extends BaseAdapter {

private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private Context mContext;
private String name;
private int profile;
private int mIcons[];
private int selectedPosition = 0;
private String mNavTitles[];
private LayoutInflater mInflater;

public MenuAdapter(String titles[], int icon[], String Name, int profile) {
    mNavTitles = titles;
    mIcons = icon;
    name = Name;
    this.profile = profile;
}

public MenuAdapter(String Titles[], int Icons[], Context mContext) {
    mNavTitles = Titles;
    mIcons = Icons;
    this.mContext = mContext;
    mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
    return mNavTitles.length;
}

@Override
public Object getItem(int position) {
    return position;
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    convertView = mInflater.inflate(R.layout.item_row, parent, false);

    TextView textView = (TextView) convertView.findViewById(R.id.rowText);
    ImageView imageView = (ImageView) convertView.findViewById(R.id.rowIcon);
    final LinearLayout layout = (LinearLayout) convertView.findViewById(R.id.outerLayout);

    imageView.setImageResource(mIcons[position]);
    textView.setText(mNavTitles[position]);

    if (position == selectedPosition)
        layout.setBackgroundColor(mContext.getResources().getColor(R.color.app_bg));
    else  
      layout.setBackgroundColor(mContext.getResources().getColor(R.color.normal_bg));

    return convertView;
}

public void setSelectedPosition(int position) {

    this.selectedPosition = position;

}


}

in your activity do this

在你的活动中这样做

 private class DrawerItemClickListener implements ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView parent, View view, int position, long id) { 
        mMenuAdapter.setSelectedPosition(position - 1);
        mMenuAdapter.notifyDataSetChanged();
    }
}

if anyone still face any difficulty, feel free to ask.

如果有人仍然面临任何困难,请随时提出。

回答by Bhavin Chauhan

I have implement drawer menu with custom adapter class. May be it will help someone Drawer List

我已经使用自定义适配器类实现了抽屉菜单。可能会帮助某人抽屉列表

<ListView
    android:id="@+id/listview_drawer"
    android:layout_width="260dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="@color/menu_item_color"
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"
    android:dividerHeight="0dp"
    android:fadingEdge="none"
    />

drawer_list_item.xml

drawer_list_item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" 
android:background="@drawable/menu_selector"
>

<ImageView
    android:id="@+id/imgIcon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_marginLeft="12dp"
    android:layout_marginRight="12dp"
    android:src="@drawable/ic_menu_home" />

<TextView
    android:id="@+id/lblName"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_centerVertical="true"
    android:gravity="center_vertical"
    android:layout_toRightOf="@+id/imgIcon"
    android:minHeight="48dp"
    android:textColor="@color/menu_txt_color" />

menu_selector.xml

menu_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<!-- selected -->
<item android:drawable="@color/menu_item_active_color" android:state_focused="true" android:state_pressed="false"/>
<item android:drawable="@color/menu_item_active_color" android:state_pressed="true"/>
<item android:drawable="@color/menu_item_active_color" android:state_activated="true"/>
<item android:drawable="@color/menu_item_active_color" android:state_checked="true"/>
<item android:drawable="@color/menu_item_active_color" android:state_selected="true"/>

<item android:drawable="@color/menu_item_color" android:state_activated="false"/>

Add this on item click listner of listview yourlistview.setItemChecked(position, true);

在 listview yourlistview.setItemChecked(position, true);

回答by Query

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:drawable="@color/list_item_back_pressed" android:state_pressed="true" />
    <item  android:state_activated="true"><color android:color="@color/primary_blue"/></item>
   <item android:drawable="@color/list_item_back_normal"/>

</selector>

回答by Prabaharan Rajendran

I know its too late but I have solved this issue in my app.

我知道为时已晚,但我已经在我的应用程序中解决了这个问题。

Pls dont think it is silly, just simply change the position of "state_pressed" to top.

请不要认为这很傻,只需将“state_pressed”的位置更改为顶部即可。

<item android:drawable="@drawable/list_item_bg_pressed" android:state_pressed="true"/>
<item android:drawable="@drawable/list_item_bg_normal" android:state_activated="false"/>
<item android:drawable="@drawable/list_item_bg_selected" android:state_activated="true"/>

回答by stan0

In addition to providing a custom selector drawable for the listSelector, you should also set the background resource of the list item to a similar selector drawable that has different drawables for the different states.

除了为 listSelector 提供自定义选择器 drawable 之外,您还应该将列表项的背景资源设置为类似的选择器 drawable,该选择器 drawable 针对不同状态具有不同的 drawable。

回答by Ripityom

I usually use my custom adapter that has an int selection field, and a setSelection(int) function. And in the getView function I set the background of the view according to position == selection.

我通常使用具有 int 选择字段和 setSelection(int) 函数的自定义适配器。在 getView 函数中,我根据位置 == 选择设置了视图的背景。