BottomNavigationView – 阴影和涟漪效应

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

底部导航栏上的阴影

如果我们点击Google相册菜单项,我们就会看到一个涟漪效果,就像图标和文字颜色(选中时)一样呈蓝色。

仅实施Google提供的解决方案会显示灰色波纹效果颜色,更糟糕的是,当我们更改bottomnavigationview的背景颜色( design:itemBackground="..." )时,它不会显示。

有人知道怎么解决吗?

这是我取得的成就:

涟漪效应+海拔gif

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

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

它只适用于你设置白色背景颜色android:background="@android:color/white"

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

  

处理启用/禁用状态:

您需要创建选择器文件:

 < ?xml version="1.0" encoding="utf-8"?>     

如果你想在AppTheme中改变标准的灰色波纹效果改变colorControlHighlight proproperty,那么它看起来如下:

  

使用26%alpha的彩色涟漪。

 #3F51B5 #423F51B5 
  1. 对于BottomNavigationView app:elevation="8dp"阴影使用高程app:elevation="8dp"
  2. 而对于涟漪效果你只需要删除app:itemBackground并将android:background设置为白色,如android:background="@android:color/white"

完整示例如下:

  

拿这个绘制阴影的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在此布局中,如:

    

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

别忘了为android:elevation="8dp"添加android:elevation="8dp"

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

在此处输入图像描述 放大

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

 android:background="@drawable/my_selector" 

/res/drawable/my_selector.xml:

  

阅读更多: RippleDrawable

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

此问题的阴影部分已经解决,因此您应该将Gradle依赖关系更新为25.0.1以获取支持和设计库。

谷歌工程师坚持认为涟漪效应问题也得到了修复,但我无法使其正常工作。

可以在此处看到有关BottomNavigationView的XML如何的示例:

  

明确问题以增加对它的认识。