BottomNavigationView - 阴影和波纹效果
Posted
技术标签:
【中文标题】BottomNavigationView - 阴影和波纹效果【英文标题】:BottomNavigationView - Shadow and Ripple Effect 【发布时间】:2017-03-12 00:21:44 【问题描述】:当BottomNavigationView 一周前发布时,我真的很高兴,但我遇到了一些让我无法解决的问题,比如在底部导航视图上看到阴影,就像谷歌照片 android 应用程序向我们展示的那样:
如果我们点击 Google 照片菜单项,我们可以看到像图标和文本颜色一样的蓝色波纹效果(选中时)。
仅实现谷歌提供的解决方案,显示灰色的波纹效果颜色,更糟糕的是,当我们更改底部导航视图的背景颜色时,它不显示(design:itemBackground="..."
)。
有人知道怎么解决吗?
【问题讨论】:
只需将 BottomNavigationView 的 itemBackground 属性设置为白色对我有用,如下所示:app:itemBackground="@color/colorWhite" 【参考方案1】:这是我取得的成就:
我创建了一个demo on GitHub 来帮助你。
首先使用最新的支持库compile "com.android.support:design:$SUPPORT_VERSION"
只有设置白色背景色android:background="@android:color/white"
才有效
注意如果您使用app:itemBackground
属性或在您的情况下为design:itemBackground="..."
,则涟漪效应将消失,因此只需将其删除。
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_
android:layout_
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>
如果你想在 AppTheme 中更改标准的灰色波纹效果更改 colorControlHighlight
属性,如下所示:
<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>
【讨论】:
确实只有在背景为白色时才会出现阴影。那是愚蠢的。知道为什么吗? 我同意这很沮丧,不知道为什么。 嗨@luksha 我完全按照你说的做,但我仍然没有工作:(令人惊讶的是,如果我将 BottomNavigationBar 放在屏幕顶部,它会提升导航视图的底部边框。但是,当我把它放在屏幕底部,海拔停止工作 你是我的救星!谢谢你。无法弄清楚那个影子去了哪里以及为什么。【参考方案2】:-
要在您的 BottomNavigationView
app:elevation="8dp"
中使用阴影高度。
对于涟漪效果,您只需删除app:itemBackground
并将android:background
设置为类似android:background="@android:color/white"
的白色
下面的完整示例:
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_
android:layout_
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" />
【讨论】:
【参考方案3】:这是设计库中的一个问题,已报告here。
这个问题的阴影部分已经解决了,所以你应该将你的 Gradle 依赖更新到 25.0.1 以获取支持和设计库。
Google 工程师坚持认为涟漪效应问题也已修复,但我无法让它正常工作。
可以在此处查看有关BottomNavigationView
的 XML 外观的示例:
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_
android:layout_
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" />
为问题加注星标以增加对它的认识。
【讨论】:
【参考方案4】:在最新的Material design library中,改变BottomNavigationView中item点击的波纹颜色超级简单。只需在您的 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_
android:layout_
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" />
【讨论】:
【参考方案5】:您可能希望在按钮中添加一个选择器,例如:
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
【讨论】:
【参考方案6】:拿这个画阴影的FrameLayout
和this gradient drawable 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>
不幸的是,原生阴影是在视图下绘制的,我们必须自己模仿这个向上的阴影。
不要忘记为DrawShadowFrameLayout
添加android:elevation="8dp"
。
Another approach is extending BottomNavigationView
并覆盖 draw()
来做同样的事情。这将帮助您在视图层次结构中释放一个FrameLayout
。
【讨论】:
【参考方案7】:我找到了解决涟漪效应问题的方法。
1) 由于 android:background 和 app:itemBackground 无法正常工作,请将它们从 BottomNavigationView 中删除。
2) 创建一个新的 FrameLayout 并将您的 BottomNavigationView 放入 FrameLayout。
3) 更改 FrameLayout 的这些属性:
android:layout_
android:layout_
4)最后将ButtonNavigationView所需的颜色添加到FrameLayout中作为android:background。
例子:
<FrameLayout
android:id="@+id/buttomnavigation_container"
android:layout_
android:layout_
android:background="@color/blue"><!--Background color for BNV-->
<android.support.design.widget.BottomNavigationView
android:id="@+id/nav_view"
android:layout_
android:layout_
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>
【讨论】:
【参考方案8】:您可以做的只是将您的BottomNavigationView
包裹在AppBarLayout
中以获得相同的效果。
这样
<com.google.android.material.appbar.AppBarLayout
app:layout_constraintBottom_toBottomOf="parent"
android:layout_
android:background="@android:color/white"
android:layout_>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNav"
android:layout_
android:layout_/>
</com.google.android.material.appbar.AppBarLayout>
【讨论】:
【参考方案9】:如何给BottomNavigationView添加波纹效果?
如果您没有为 BottomNavigationView 属性 app:itemBackground 设置自定义可绘制对象,则仅在下方添加会添加涟漪效果。
android:background="@android:color/white"
如果您已经在使用自定义可绘制选择器
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>
【讨论】:
此解决方案不会产生涟漪效果,只是在单击菜单项时将整个“正方形”的颜色设置为@color/red【参考方案10】:只需将此属性添加到:app:itemRippleColor="@color/orange"
<FrameLayout
android:id="@+id/frameLayout"
android:layout_
android:layout_>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_gravity="bottom"
android:id="@+id/bottomNavigation"
android:background="@color/dark"
app:itemRippleColor="@color/orange"
android:layout_
app:menu="@menu/bottom_nav_menu"
app:itemIconTint="@color/bottom_nav_color"
app:itemTextColor="@color/bottom_nav_color"
android:layout_/>
</FrameLayout>
【讨论】:
请添加一些链接以展示代码是否有效。以上是关于BottomNavigationView - 阴影和波纹效果的主要内容,如果未能解决你的问题,请参考以下文章
BottomNavigationView - 如何获取选定的菜单项?
安卓。具有单一活动方法的 BottomNavigationView