如果我们点击 Google Photos 菜单项,可以看到一个水波纹效果,其颜色像图标和文本颜色(选中时)一样为蓝色。
实现 Google 提供的解决方案后,只会显示灰色的涟漪效果颜色,更糟糕的是,当我们更改 bottomnavigationview 的背景颜色 (design:itemBackground="..."
) 时,不会显示效果。
有人知道怎么解决吗?
如果我们点击 Google Photos 菜单项,可以看到一个水波纹效果,其颜色像图标和文本颜色(选中时)一样为蓝色。
实现 Google 提供的解决方案后,只会显示灰色的涟漪效果颜色,更糟糕的是,当我们更改 bottomnavigationview 的背景颜色 (design:itemBackground="..."
) 时,不会显示效果。
有人知道怎么解决吗?
这是我所取得的进展:
我在 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_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>
如果你想要改变标准的灰色涟漪效果,请在App主题中更改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%的透明度来呈现有颜色的涟漪效果。
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryRipple">#423F51B5</color>
app:elevation="8dp"
来设置阴影。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" />
在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" />
这是设计库中的问题,并已在此处报告。
该问题的影子部分已经得到解决,因此您应该将Gradle依赖项更新为25.0.1,以使用Support和Design库。
Google工程师坚称水波纹效果问题也已经解决,但我还没有成功地实现它。
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" />
Star这个问题以增加其知名度。
<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>
您可能需要为按钮添加选择器,例如:
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
使用这个FrameLayout
,可以绘制阴影和这个渐变的 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"
。
另一种方法是扩展 BottomNavigationView
并重写 draw()
来完成相同的工作。这将帮助您减少视图层次结构中的一个 FrameLayout
。
android:layout_width="match_parent"
android:layout_height="wrap_content"
4)最后将所需的颜色添加到FrameLayout中作为ButtomNavigationView的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>
你可以将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>
如果您没有为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>