【问题标题】:Bottom Navigation changing selected icon color底部导航更改所选图标颜色
【发布时间】:2018-09-24 00:06:03
【问题描述】:

我正在尝试在 android 中制作自定义底部导航。 我想禁用转变并为图标提供自定义颜色。 图标最初为灰色,选中的图标变为蓝色。 问题是所有图像即使被选中也保持灰色。

我试图弄乱其中的一些,但没有什么能让按钮在选择时改变颜色。

下面是我试过的代码。

这是java的主要活动

public class admin extends AppCompatActivity {


BottomNavigationView bottomNavigationView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_admin);

    bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation);
    BottomNavigationViewHelper.disableShiftMode((bottomNavigationView));
    bottomNavigationView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    bottomNavigationView.setItemIconTintList(null);

    urgent urgentfragment = urgent.newInstance();
    setFragment(urgentfragment,false);

}



private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        = new BottomNavigationView.OnNavigationItemSelectedListener() {

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.bottom_urgent:
                urgent urgentfragment = urgent.newInstance();
                setFragment(urgentfragment,false);
                return true;
            case R.id.bottom_all:
                all allfragment = all.newInstance();
                setFragment(allfragment,false);
                item.setChecked(true);
                return true;
            case R.id.bottom_attendedto:
                attendedto attendedtofragment = attendedto.newInstance();
                setFragment(attendedtofragment,false);
                item.setChecked(true);
                return true;

        }
        return false;
    }
};

public void setFragment(Fragment fragment, boolean addtobackstack) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.event_framelayout, fragment);

    if(!addtobackstack)
    {
        for(int i=0;i< fragmentManager.getBackStackEntryCount();++i)
            fragmentManager.popBackStack();
    }
    else
    {
        fragmentTransaction.addToBackStack(null);

    }

    fragmentTransaction.commit();

}

}

这是主要的活动xml

  <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".admin">

    <FrameLayout
        android:id="@+id/event_framelayout"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toTopOf="@+id/navigation"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0" />

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/navigation"
        app:itemIconTint="@color/colors_bottom_navigation"
        app:itemTextColor="@color/colors_bottom_navigation"
        app:itemBackground="@color/colorPrimaryDark"/>



</android.support.constraint.ConstraintLayout>

这是帮助禁用班次的辅助类

   package com.prototypeapp.healer.healer.customviews;

import android.annotation.SuppressLint;
import android.support.design.internal.BottomNavigationItemView;
import android.support.design.internal.BottomNavigationMenuView;
import android.support.design.widget.BottomNavigationView;
import android.util.Log;

import java.lang.reflect.Field;

public class BottomNavigationViewHelper {

    @SuppressLint("RestrictedApi")
    public static void disableShiftMode(BottomNavigationView view) {
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
        try {
            Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
            shiftingMode.setAccessible(true);
            shiftingMode.setBoolean(menuView, false);
            shiftingMode.setAccessible(false);
            for (int i = 0; i < menuView.getChildCount(); i++) {
                BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
                //noinspection RestrictedApi
                item.setShiftingMode(false);
                // set once again checked value, so view will be updated
                //noinspection RestrictedApi
                item.setChecked(item.getItemData().isChecked());
            }
        } catch (NoSuchFieldException e) {
            Log.e("BNVHelper", "Unable to get shift mode field", e);
        } catch (IllegalAccessException e) {
            Log.e("BNVHelper", "Unable to change value of shift mode", e);
        }
    }
}

【问题讨论】:

    标签: android bottomnavigationview


    【解决方案1】:

    您可以通过将 Vector Drawable 与 Color State List resource 组合来实现此目的。

    第一步是创建颜色状态列表资源,当底部导航项被选中时,使用你想要的颜色的选中状态。这是一个使用蓝色和灰色的:

    • res/color/share_color.xml
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item android:color="#0000ff" android:state_checked="true" />
        <item android:color="#1b1b1b" />
    
    </selector>
    

    有了它,你可以使用这个颜色状态列表作为你的矢量可绘制对象的颜色:

    • res/drawable/ic_share.xml
    <vector
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportHeight="24.0"
        android:viewportWidth="24.0">
    
        <path
            android:fillColor="@color/share_color"
            android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z" />
    
    </vector>
    

    现在,当您在BottomNavigationView 的菜单中使用ic_share 作为菜单项的图标时,您会看到颜色发生了变化。

    请注意,这要求您使用 Support Library for vector drawables(与生成时生成 PNG 不同)。

    【讨论】:

    • 感谢您的回答。但是我确实需要添加自定义 png 图像。最让我发疯的是,我在另一个项目中编写了相同的代码并且它有效,但这次不行。顺便说一句,它也在预览布局......
    • @SaraKat 我添加了另一个答案来覆盖使用自定义 PNG 图像而不是矢量可绘制对象
    【解决方案2】:

    您可以通过使用带有 PNG 图像的 State List Drawable resource 来获得变色图标的外观。假设您有两个不同颜色的 PNG:

    • res/drawable-mdpi/ic_share_black_24dp.png

    • res/drawable-mdpi/ic_share_blue_24dp.png

    然后,您将创建 State List Drawable,使用蓝色图标的 checked 状态:

    • res/drawable/ic_share.xml
    <selector
        xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item
            android:state_checked="true"
            android:drawable="@drawable/ic_share_blue_24dp"/>
    
        <item
            android:drawable="@drawable/ic_share_black_24dp"/>
    
    </selector>
    

    现在,当您在BottomNavigationView 的菜单中使用ic_share 作为菜单项的图标时,您会看到颜色发生了变化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-09
      • 1970-01-01
      相关资源
      最近更新 更多