Gezinme çekmecesinde işaretlenmiş bir menü öğesinin rengini değiştirme


104

Uygulamamda bir gezinme çekmecesi uygulamak için yeni Android Tasarım Desteği kitaplığını kullanıyorum.

Seçili bir öğenin rengini nasıl değiştireceğimi çözemiyorum!

İşte menünün xml'si:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
    <item
        android:id="@+id/navigation_item_1"
        android:icon="@drawable/ic_1"
        android:title="@string/navigation_item_1"/>

    <item
        android:id="@+id/navigation_item_2"
        android:icon="@drawable/ic_2"
        android:title="@string/navigation_item_2"/>
</group>

Ve burada, a'nın içine yerleştirilmiş olan gezinti görünümü xml'si android.support.v4.widget.DrawerLayout:

<android.support.design.widget.NavigationView
    android:id="@+id/activity_main_navigationview"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:headerLayout="@layout/drawer_header"
    app:itemIconTint="@color/black"
    app:itemTextColor="@color/primary_text"
    app:menu="@menu/menu_drawer">

    <TextView
        android:id="@+id/main_activity_version"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:layout_marginLeft="@dimen/activity_horizontal_margin"
        android:textColor="@color/primary_text" />

</android.support.design.widget.NavigationView>

Yardımın için teşekkürler !

[DÜZENLE] Bunun gibi çözümlere zaten baktım: Android menüsünün arka plan rengini değiştir .

Oldukça zor gibi görünüyor ve yeni Tasarım Destek Kitaplığı ile daha temiz bir şey tanıtılacağını düşündüm.


Yanıtlar:


246

Bunu Color State Resource kullanarak başarabilirsiniz . İçinde NavigationViewkullandığını fark edersen

app:itemIconTint="@color/black"
app:itemTextColor="@color/primary_text"

Burada @color/blackveya @color/primary_testkullanmak yerine bir Color State List Resource. Bunun için, önce yeni bir dizin oluşturun xml(örn. Drawer_item.xml) colordizin içinde (dizinin içinde olmalıdır res.) colorÖnceden adlandırılmış bir dizininiz yoksa, bir tane oluşturun.

Şimdi içeride bunun drawer_item.xmlgibi bir şey yap

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="checked state color" android:state_checked="true" />
    <item android:color="your default color" />
</selector>

Son adım, NavigationView

<android.support.design.widget.NavigationView
    android:id="@+id/activity_main_navigationview"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:headerLayout="@layout/drawer_header"
    app:itemIconTint="@color/drawer_item"  // notice here
    app:itemTextColor="@color/drawer_item" // and here
    app:itemBackground="@android:color/transparent"// and here for setting the background color to tranparent
    app:menu="@menu/menu_drawer">

Bunun gibi Kendileri için ayrı Renk Devlet Liste Kaynakları kullanabilirsiniz IconTint, ItemTextColor, ItemBackground.

Artık bir öğeyi işaretli olarak ayarladığınızda (içinde xmlveya programlı olarak), belirli öğenin rengi işaretlenmemiş olanlardan farklı olacaktır.


Çalışmak için basıldığında bunu android: state_checked'den android: state_pressed'e değiştirmeniz gerektiğini unutmayın.
Programista

33
ItemBackground için renk yerine bir çizilebilirlik kullanmanız gerekir çünkü bir renk kaynağı kullanarak bir arka plan tanımlayamazsınız.
sirFunkenstine

@sash, seçili gezinme öğesinde simge görüntüsünü değiştirmek istersek, bunu nasıl yapacağız?
mohit

@sirFunkenstine Renk seçici kullanıyorsanız, res klasörünüzdeki renk klasörüne koyabilirsiniz.
Kishan Vaghela

@KishanVaghela önerdiğiniz şeyi yapmak şu hatayı üretir: Binary XML dosya satırı # 3: <item> etiketi, bir çekilebilir tanımlayan bir 'çekilebilir' öznitelik veya alt etiket gerektirir
iOSAndroidWindowsMobileAppsDev

67

app:itemBackgroundBir çekilebilir beklediğine inanıyorum . Bu yüzden aşağıdaki adımları izleyin:

highlight_color.xmlAşağıdaki içeriğe sahip bir çekilebilir dosya oluşturun:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
     <solid android:color="YOUR HIGHLIGHT COLOR"/>
</shape>

nav_item_drawable.xmlAşağıdaki içeriklerle başka bir çekilebilir dosya yapın :

<selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/highlight_color" android:state_checked="true"/>
</selector>

Son olarak app:itemBackgroundNavView'a etiket ekleyin :

<android.support.design.widget.NavigationView
android:id="@+id/activity_main_navigationview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/drawer_header"
app:itemIconTint="@color/black"
app:itemTextColor="@color/primary_text"
app:itemBackground="@drawable/nav_item_drawable"
app:menu="@menu/menu_drawer">

burada, vurgu_renk.xml dosyası, arka plan için düz bir renk çizilebilir tanımlar. Daha sonra bu renk çizilebilir, nav_item_drawable.xml seçicisine atanır.

Bu benim için çalıştı. Umarım bu yardımcı olur.

********************************************** GÜNCELLENDİ *** *******************************************

Yukarıda belirtilen cevap size bazı özellikler üzerinde tam kontrol sağlasa da açıklamak üzere olduğum yol daha KATI ve biraz SOĞUTUCU .

Ne yapabilirim olduğunu Yani, bir tanımlayabilirsiniz ThemeOverlay içinde styles.xmlböyle NavigationView için:

    <style name="ThemeOverlay.AppCompat.navTheme">

        <!-- Color of text and icon when SELECTED -->
        <item name="colorPrimary">@color/color_of_your_choice</item> 

        <!-- Background color when SELECTED -->
        <item name="colorControlHighlight">@color/color_of_your_choice</item> 

    </style>

şimdi bu ThemeOverlay'i app:themeNavigationView özniteliğine uygulayın , örneğin:

<android.support.design.widget.NavigationView
android:id="@+id/activity_main_navigationview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:theme="@style/ThemeOverlay.AppCompat.navTheme"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/menu_drawer">

Umarım bu yardımcı olacak.


1
Ayrıca, bu yöntem android:background="@drawable/nav_item_drawable"RadioButton, Checkbox, Button vb. Gibi diğer widget'larda olduğu gibi kullanılabilir setOnCheckedChangeListener. Yalnızca renk vurgulama için işlem için bloatware programlamasını azaltır .
rupinderjeet

@Ankush bu çalışıyor ancak metin ve simge kayboluyor, öğenin renk tonunu da ayarladım ama çalışmıyor. lütfen bana nasıl yapılabileceğini önerebilir misin
Kullanıcı

1
@User Kodunuzda neyin yanlış gittiğini bilmiyorum ama yanıta ekledim. Aynı şeyi daha az çabayla elde etmenin tamamen farklı bir yolu. Bunu kontrol edebilirsiniz.
Ankush

1
Bu bir cevap olarak kabul edilmelidir! Çok teşekkür ederim, çok yardımcı !!!
Svetlana Rozhkova

ARKA PLANIN DÜZGÜN ŞEKİLDE ÇALIŞMASI İÇİN MENÜ XML'İNİZDE "KONTROL EDİLEBİLİR = DOĞRU" UYGULAMAYI UNUTMAYIN
Ankit

4

Sete Bir ihtiyaç NavigateItemöğesi içinde zaman gerçek kontrol NavigateViewtıklandığında

//listen for navigation events
NavigationView navigationView = (NavigationView)findViewById(R.id.navigation);
navigationView.setNavigationItemSelectedListener(this);
// select the correct nav menu item
navigationView.getMenu().findItem(mNavItemId).setChecked(true);

ekle NavigationItemSelectedListenerüzerindeNavigationView

  @Override
  public boolean onNavigationItemSelected(final MenuItem menuItem) {
    // update highlighted item in the navigation menu
    menuItem.setChecked(true);
    mNavItemId = menuItem.getItemId();

    // allow some time after closing the drawer before performing real navigation
    // so the user can see what is happening
    mDrawerLayout.closeDrawer(GravityCompat.START);
    mDrawerActionHandler.postDelayed(new Runnable() {
      @Override
      public void run() {
        navigate(menuItem.getItemId());
      }
    }, DRAWER_CLOSE_DELAY_MS);
    return true;
  }

Yardımın için teşekkürler Vikalp, ama bunu zaten yapıyorum ( setChecked(true)). Kontrol edilen öğenin renginin değiştiğini görebiliyorum, ancak kendim değiştiremiyorum, renk her zaman gezinme görüntüleme arka planının daha açık bir sürümüdür.
Greg

@Greg Varsayılan setChecked(true)olarak Viewarka plan rengini kullandığınız cihaza göre değiştirir. Öğenin arka planını başka bir renge değiştirirseniz, mizanpajınızı şişirmeniz DrawerLayoutveya NavigationViewkendi başınıza halletmeniz gerekir.
Vikalp Patel

Tekrar teşekkürler, bana söylediklerini yapmaya çalıştım ama başarılı olamadan nasıl olacağını açıklayan bir linkiniz olur mu?
Greg

2

İşte bunu başarmanın başka bir yolu:

public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem item) {
            item.setEnabled(true);
            item.setTitle(Html.fromHtml("<font color='#ff3824'>Settings</font>"));
            return false;
            }
        });


    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

}


Benim dobut'um, açılır menünün seçili öğesinin rengini değiştirmek istersem ilgiliydi, ancak sizin sayenizde, bu çözümünüzden seçilen menü öğesinin rengini değiştirmek için harika bir fikrim var ... bu yüzden size oy veriyorum !!! Ve çalışma şu şekildedir :: item.setTitle (Html.fromHtml ("<font color = '# ff3824'> Ayarlar </font>"));
Tarit Ray

1

Aktivitenizin onCreate yönteminde bunu şu şekilde yapabilirsiniz:

NavigationView navigationView = findViewById(R.id.nav_view);
ColorStateList csl = new ColorStateList(
    new int[][] {
        new int[] {-android.R.attr.state_checked}, // unchecked
        new int[] { android.R.attr.state_checked}  // checked
    },
    new int[] {
        Color.BLACK,
        Color.RED
    }
);
navigationView.setItemTextColor(csl);
navigationView.setItemIconTintList(csl);

1

Adım 1: İşaretli / kontrol edilmemiş bir seçici oluşturun:

selector.xml

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

Adım 2: Metin rengini seçmek için widget app:itemTextColoriçindeki xml niteliğini kullanın NavigationView.

<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:headerLayout="@layout/navigation_header_layout"
    app:itemTextColor="@drawable/selector"
    app:menu="@menu/navigation_menu" />

3. Adım:
Bazı nedenlerden dolayı NavigationViewmenüden bir öğeye bastığınızda , bunu bir düğme kontrolü olarak kabul etmez. Bu nedenle, seçilen öğeyi manuel olarak kontrol ettirmeniz ve önceden seçilen öğeyi temizlemeniz gerekir. Bunu yapmak için aşağıdaki dinleyiciyi kullanın

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {

    int id = item.getItemId();

    // remove all colors of the items to the `unchecked` state of the selector
    removeColor(mNavigationView);

    // check the selected item to change its color set by the `checked` state of the selector
    item.setChecked(true);

    switch (item.getItemId()) {
      case R.id.dashboard:
          ...
    }

    drawerLayout.closeDrawer(GravityCompat.START);
    return true;
}

private void removeColor(NavigationView view) {
    for (int i = 0; i < view.getMenu().size(); i++) {
        MenuItem item = view.getMenu().getItem(i);
        item.setChecked(false);
    }
}

Adım 4:
Simge rengini değiştirmek app:iconTintiçin NavigationViewmenü öğelerindeki özelliği kullanın ve aynı seçiciye ayarlayın.

<?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">
    <item
        android:id="@+id/nav_account"
        android:checked="true"
        android:icon="@drawable/ic_person_black_24dp"
        android:title="My Account"
        app:iconTint="@drawable/selector" />
    <item
        android:id="@+id/nav_settings"
        android:icon="@drawable/ic_settings_black_24dp"
        android:title="Settings"
        app:iconTint="@drawable/selector" />

    <item
        android:id="@+id/nav_logout"
        android:icon="@drawable/logout"
        android:title="Log Out"
        app:iconTint="@drawable/selector" />
</menu>

Sonuç:

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.