23

一周前发布BottomNavigationView时我真的很高兴,但我遇到了一些让我无法解决的问题,比如在 BottomNavigationView 上看到阴影,就像 Google Photos Android App 向我们展示的那样:

底部导航栏上的阴影

如果我们点击 Google Photos 菜单项,我们可以看到像图标和文本颜色一样的蓝色波纹效果(选中时)。

design:itemBackground="..."仅实现谷歌提供的解决方案,会显示灰色的波纹效果颜色,更糟糕的是,当我们更改底部导航视图( )的背景颜色时,它不会显示。

有人知道如何解决吗?

4

10 回答 10

54

这是我所取得的成就:

涟漪效应 + 高程 gif

在 GitHub 上创建了一个演示来帮助你。

首先使用最新的支持库compile "com.android.support:design:$SUPPORT_VERSION"

仅当您设置白色背景颜色时才有效android:background="@android:color/white"

请注意,如果您使用app:itemBackgroundproperty 或在您的情况下它是,则涟漪效应将消失design:itemBackground="...",因此只需将其删除。

<android.support.design.widget.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:background="@android:color/white"
    app:elevation="16dp"
    app:itemIconTint="@drawable/nav_item_color_state"
    app:itemTextColor="@drawable/nav_item_color_state"
    app:menu="@menu/bottom_navigation_main" />

处理启用/禁用状态:

您需要创建选择器文件:

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

如果要更改colorControlHighlightAppTheme 中的标准灰色波纹效果更改属性,则如下所示:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="colorControlHighlight">@color/colorPrimaryRipple</item>
</style>

对彩色波纹使用 26% 的 alpha。

<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryRipple">#423F51B5</color>
于 2016-12-03T15:33:37.333 回答
23
  1. 对于 BottomNavigationView 中的阴影使用海拔高度app:elevation="8dp"
  2. 而对于涟漪效果,您只需要像这样删除app:itemBackground并设置android:background为白色android:background="@android:color/white"

完整示例如下:

<android.support.design.widget.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_alignParentBottom="true"
        android:background="@android:color/white"
        android:clickable="true"
        app:elevation="8dp"
        app:itemIconTint="@drawable/nav_item_color_state"
        app:itemTextColor="@drawable/nav_item_color_state"
        app:menu="@menu/my_navigation_items" />
于 2017-01-25T14:12:12.090 回答
3

这是设计库中的一个问题,已在此处报告。

这个问题的影子部分已经解决了,所以你应该将你的 Gradle 依赖更新到 25.0.1 以获取 Support and Design 库。

谷歌工程师坚持认为涟漪效应问题也已修复,但我无法让它正常工作。

BottomNavigationView可以在此处查看有关 XML 的外观的示例:

<android.support.design.widget.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:background="@android:color/black"
    app:itemBackground="@android:color/white"
    app:itemIconTint="@drawable/bottom_navigation_selector"
    app:itemTextColor="@drawable/bottom_navigation_selector"
    app:menu="@menu/bottom_navigation_menu" />

为问题加注星标以增加对它的认识。

于 2016-11-20T23:16:00.367 回答
3

在最新的材料设计库中,在底部导航视图中更改项目单击的波纹颜色非常容易。只需在您的 BottomNavigationView 中添加 app:itemRippleColor="@color/your_color"。这是完整的代码

在 build.gradle 中添加依赖

build.gradle

implementation "com.google.android.material:material:$materialDesignVersion"

activity_main.xml

<com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/_5sdp"
        android:background="@drawable/bottom_navigation_background"
        app:itemRippleColor="@color/red"
        app:labelVisibilityMode="labeled"
        app:itemIconTint="@color/bottom_navigation_menu_item_tint"
        app:itemTextColor="@color/bottom_navigation_menu_item_tint"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:menu="@menu/home_bottom_navigation_menu" />
于 2020-06-23T11:41:25.057 回答
1

拿这个FrameLayout绘制阴影和这个渐变可绘制 xml

public class DrawShadowFrameLayout extends FrameLayout {
    private Drawable mShadowDrawable;
    private final int mShadowElevation = 8;
    private int mWidth;
    private int mHeight;
    private boolean mShadowVisible = true;

    public DrawShadowFrameLayout(Context context) {
        this(context, null, 0);
    }

    public DrawShadowFrameLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DrawShadowFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mShadowDrawable = ContextCompat.getDrawable(getContext(), R.drawable.shadow);
        if (mShadowDrawable != null) {
            mShadowDrawable.setCallback(this);
        }
        setWillNotDraw(!mShadowVisible);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
        updateShadowBounds();
    }


    private void updateShadowBounds() {
        if (mShadowDrawable != null) {
            mShadowDrawable.setBounds(0, 0, mWidth, mShadowElevation);
        }
        ViewCompat.postInvalidateOnAnimation(this);
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        if (mShadowDrawable != null && mShadowVisible) {
            getBackground().setBounds(0, mShadowDrawable.getBounds().bottom, mWidth, mHeight);
            mShadowDrawable.draw(canvas);
        }
    }

    public void setShadowVisible(boolean shadowVisible) {
        setWillNotDraw(!mShadowVisible);
        updateShadowBounds();
    }

    int getShadowElevation() {
        return mShadowVisible ? mShadowElevation : 0;
    }

}

把你包裹BottomNavigationView在这个布局里面,比如:

<DrawShadowFrameLayout>
  <BottomNavigationView />
</DrawShadowFrameLayout>

不幸的是,原生阴影是在视图下绘制的,我们必须自己模仿这个向上的阴影。

不要忘记添加android:elevation="8dp"DrawShadowFrameLayout

另一种方法是扩展 BottomNavigationView和覆盖draw()来做同样的事情。这将帮助您FrameLayout在视图层次结构中放松一个。

在此处输入图像描述 放大

于 2016-11-01T09:59:24.293 回答
1

我找到了涟漪效应问题的解决方案。

1) 由于android:backgroundapp:itemBackground不能正常工作,从 BottomNavigationView 中删除它们。

2)创建一个新的FrameLayout并将您的BottomNavigationView放入FrameLayout

3) 更改 FrameLayout 的这些属性:

android:layout_width="match_parent"
android:layout_height="wrap_content"

4)最后将ButtonNavigationView所需的颜色添加到FrameLayout中作为android:background

例子:

<FrameLayout
 android:id="@+id/buttomnavigation_container"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="@color/blue"><!--Background color for BNV-->
 <android.support.design.widget.BottomNavigationView
    android:id="@+id/nav_view"
    android:layout_width="match_parent"
    android:layout_height="56dp"
    app:itemIconTint="@color/bottom_navigation_colors"
    app:itemTextColor="@color/bottom_navigation_colors"
    app:labelVisibilityMode="labeled"
    app:menu="@menu/bottom_nav_menu"/>
</FrameLayout>

bottom_navigation_colors.xml

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

图片

于 2019-06-17T01:58:53.100 回答
1

您可能希望向按钮添加选择器,例如:

android:background="@drawable/my_selector"

/res/drawable/my_selector.xml:

<ripple android:color="@color/my_favourite_color"
    xmlns:android="http://schemas.android.com/apk/res/android" />

阅读更多:RippleDrawable

于 2016-10-29T06:47:35.693 回答
0

你能做的就是把你的包裹BottomNavigationView进去AppBarLayout以获得同样的效果。

像这样

<com.google.android.material.appbar.AppBarLayout
            app:layout_constraintBottom_toBottomOf="parent"
            android:layout_width="match_parent"
            android:background="@android:color/white"
            android:layout_height="wrap_content">

        <com.google.android.material.bottomnavigation.BottomNavigationView
                android:id="@+id/bottomNav"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>

</com.google.android.material.appbar.AppBarLayout>
于 2019-07-31T16:40:18.153 回答
0

只需将此属性添加到:app:itemRippleColor="@color/orange"

<FrameLayout
    android:id="@+id/frameLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:layout_gravity="bottom"
        android:id="@+id/bottomNavigation"
        android:background="@color/dark"
        app:itemRippleColor="@color/orange"
        android:layout_width="match_parent"
        app:menu="@menu/bottom_nav_menu"
        app:itemIconTint="@color/bottom_nav_color"
        app:itemTextColor="@color/bottom_nav_color"
        android:layout_height="wrap_content"/>

</FrameLayout>
于 2021-03-23T12:40:19.243 回答
0

如何将涟漪效果添加到 BottomNavigationView?

  1. 如果您没有为 BottomNavigationView 属性app:itemBackground设置自定义可绘制对象,则仅在下方添加会添加涟漪效果。

    android:background="@android:color/white"
    
  2. 如果您已经在使用自定义可绘制选择器

    app:itemBackground="@drawable/tab_selector"
    

然后将波纹标签添加到自定义可绘制对象。

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

        </item>
于 2021-03-09T20:22:42.613 回答