簡體   English   中英

如何在 NavigationView 中自定義項目背景和項目文本顏色?

[英]How to customize item background and item text color inside NavigationView?

我想實現Material Design Docs 中顯示的類似內容。

colorControlHighlight用於選中項目的背景。

我需要自定義:

  • 背景未選中
  • 文字顏色檢查
  • 未選中文本顏色

itemBackgrounditemIconTintitemTextColor是可以設置的簡單 xml 屬性,但您必須使用自定義前綴而不是android: one。

例子

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!-- Other layout views -->

    <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:itemBackground="@drawable/my_ripple"
        app:itemIconTint="#2196f3"
        app:itemTextColor="#009688"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/drawer_view" />

</android.support.v4.widget.DrawerLayout>

注意:在這種情況下,文本顏色、圖標色調和背景是靜態的。 如果要更改文本的顏色(例如,未選中時為粉紅色,選中時為藍綠色),則應使用ColorStateList

例子

/res/color創建一個新的 *.xml 文件 - 讓我們將其命名為state_list.xml - 具有以下內容:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- This is used when the Navigation Item is checked -->
    <item android:color="#009688" android:state_checked="true" />
    <!-- This is the default text color -->
    <item android:color="#E91E63" />
</selector>

然后像這樣簡單地引用它: app:itemTextColor="@color/state_list"

itemIconTint itemBackground需要一個資源 ID。 請參閱文檔

NavigationDrawer (NavigationView) 有三個選項用於配置選中/選中項。

app:itemIconTint="@color/menu_text_color" //icon color
app:itemTextColor="@color/menu_text_color" //text color
app:itemBackground="@drawable/menu_background_color" //background

圖標和文字顏色

前兩個選項(圖標和文本)需要顏色狀態列表資源- https://developer.android.com/guide/topics/resources/color-list-resource.html

這樣的menu_text_color資源需要在res/color 中創建。 此文件內容應類似於:

<!-- res/color/menu_text_color.xml -->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="@color/colorWhite" android:state_checked="true" />
  <item android:color="@color/colorBlack" android:state_checked="false"/>
</selector>
  • @color/colorWhite - 用於選中項的顏色資源

  • @color/colorBlack - 用於未選中項的顏色資源

我為兩者創建了一個資源,但可以創建兩個單獨的文件 - 一個用於文本,一個用於圖標。

背景(項目背景)

背景選項需要可繪制資源而不是顏色,每次嘗試設置顏色都會以異常結束。 Drawable 資源需要在res/drawable 中創建,其內容應類似於:

<!-- res/drawable/menu_background_color.xml -->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@android:color/transparent"  android:state_checked="false"/>
  <item android:drawable="@color/colorPrimary" android:state_checked="true"/>
</selector>

不需要創建任何模擬顏色的可繪制對象(在其他解決方案中我看到了這樣的命題 - 也許對於較舊的 sdk 版本),顏色可以直接在這個文件中使用。 在這個示例文件中,我對未選中的項目使用透明顏色,對選中的項目使用colorPrimary

故障排除和重要說明

  • 在后台資源中始終使用state_checked="false"而不是默認值,默認顏色將不起作用
  • 對於動態/以編程方式創建的菜單,請記住將項目設置為可檢查

代碼示例(動態菜單項添加):

  menu.add(group_id, item_id, Menu.NONE, item_name).setCheckable(true).setChecked(false);

如果項目不會設置為可檢查,則背景將不起作用(文本和圖標顏色令人驚訝將按預期工作)。

使用 colorControlHighlight 對我來說是一個很好的解決方案。 請注意,使用最新的支持庫,您可以為每個小部件定義一個主題(不僅僅是樣式); 例如,您可以將 colorControlHighlight 定義到 NavigationView 主題中,這不會應用於其余小部件。

如果您只想根據事件從您的活動中更改一種菜單項顏色,請參閱 HANIHASHEMI 的此博客:

https://hanihashemi.com/2017/05/06/change-text-color-of-menuitem-in-navigation-drawer/

private void setTextColorForMenuItem(MenuItem menuItem, @ColorRes int color) {
  SpannableString spanString = new SpannableString(menuItem.getTitle().toString());
  spanString.setSpan(new ForegroundColorSpan(ContextCompat.getColor(this, color)), 0, spanString.length(), 0);
  menuItem.setTitle(spanString);
}

調用方法

setTextColorForMenuItem(item, R.color.colorPrimary);

如果您使用 Xamarin Android,請嘗試以下操作:

private void SetTextColorForMenuItem(IMenuItem menuItem, Android.Graphics.Color color)
        {
            SpannableString spanString = new SpannableString(menuItem.TitleFormatted.ToString());
            spanString.SetSpan(new ForegroundColorSpan(color), 0, spanString.Length(), 0);
            menuItem.SetTitle(spanString);
        }

調用方式:

SetTextColorForMenuItem(navigationView.Menu.GetItem(0), Android.Graphics.Color.OrangeRed);

您可以以編程方式使用此代碼:

int[][] states = new int[][] {
    new int[] { android.R.attr.state_enabled}, // enabled
    new int[] {-android.R.attr.state_enabled}, // disabled
    new int[] {-android.R.attr.state_checked}, // unchecked
    new int[] { android.R.attr.state_pressed}  // pressed
};

int[] colors = new int[] {
    Color.BLACK,
    Color.RED,
    Color.GREEN,
    Color.BLUE
};

ColorStateList myList = new ColorStateList(states, colors);

  nav_view.setItemIconTintList(myList);

通過MaterialComponents 庫,您可以使用這些屬性:

  • app:itemShapeFillColor : 背景項目顏色
  • app:itemIconTint : 圖標色調
  • app:itemTextColor : 文字顏色

在布局中:

<com.google.android.material.navigation.NavigationView
    app:itemShapeFillColor="@color/shape_selector"
    app:itemIconTint="@color/icon_tint_selector"
    app:itemTextColor="@color/text_color_selector"
    ../>

在自定義樣式中:

<style name="..." parent="Widget.MaterialComponents.NavigationView" >
   <item name="itemShapeFillColor">@color/shape_selector</item>
   <item name="itemIconTint">@color/icon_tint_selector</item>
   <item name="itemTextColor">@color/text_color_selector</item>
</style>

對於itemIconTintitemTextColor您可以使用這樣的選擇器:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="?attr/colorPrimary" android:state_checked="true"/>
  <item android:alpha="0.38" android:color="?attr/colorOnSurface" android:state_enabled="false"/>
  <item android:color="?attr/colorOnSurface"/>
</selector>

對於itemShapeFillColor您可以使用如下選擇器:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:alpha="0.12" android:color="?attr/colorPrimary" android:state_activated="true"/>
  <item android:alpha="0.12" android:color="?attr/colorPrimary" android:state_checked="true"/>
  <item android:color="@android:color/transparent"/>
</selector>

只是最后一點 注意使用itemBackground
當設置itemShapeAppearance和/或itemShapeAppearanceOverlay時,它被設置為@null以使用由NavigationView編程方式生成的形狀背景(默認行為)。
此背景使用itemShape*屬性設置樣式。
設置itemBackground將覆蓋編程背景並導致在 itemShape* 屬性中設置的值被忽略。

在此處輸入圖片說明

現在,在導航視圖中,您還可以提供自己的項目視圖。 使用新的appcompat-v7:23.1.0您可以

通過 app:actionLayout 或使用 MenuItemCompat.setActionView() 為項目設置自定義視圖。

View view = View.inflate(context, R.layout.your_custom_nav_layout_item, null);
MenuItemCompat.setActionView(menuItem, view); 

通過這種方式,您可以使用 TextView 創建自己的布局,並根據需要更改backgrounds/colors/fonts 希望這有幫助:) 來源

如果您想以編程方式執行此操作:

基於約翰的回答:

您可以像這樣使用 Kotlin 擴展:

fun NavigationView.setTextColorForMenuItems(@ColorInt color: Int) {
    for (i: Int in 0 until menu.size()) {
        val menuItem = menu.getItem(i)
        val spanString = SpannableString(menuItem.title.toString())
        spanString.setSpan(ForegroundColorSpan(color), 0, spanString.length, 0)
        menuItem.title = spanString
    }
}

然后打電話

nav_view.setTextColorForMenuItems(Color.BLACK)

您可以使用以下語句執行此操作:

navigationView.setItemBackground(ContextCompat.getDrawable(CustomerHomeActivity.this, R.color.transparent));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM