Android 如何将BottomAppBar和#x2B组合在一起;带BottomNavigationView的FAB
我想使用Android 如何将BottomAppBar和#x2B组合在一起;带BottomNavigationView的FAB,android,android-layout,android-xml,bottomnavigationview,android-bottomappbar,Android,Android Layout,Android Xml,Bottomnavigationview,Android Bottomappbar,我想使用FloatingActionButton,以及它在BottomNavigationView顶部的BottomAppBar上定位时的行为 我想出了一个相当“黑客”的把戏,只将BottomNavigationView放在BottomAppBar的顶部,而不提供背景,从而使其透明 乍一看,这似乎效果不错,但我发现只有在触摸按钮的上半部分时才能单击fab按钮(因此顶部没有透明的BottomNavigationView) 有没有什么方法可以实现这个想法,让我可以完全点击FloatingAct
FloatingActionButton
,以及它在BottomNavigationView顶部的BottomAppBar上定位时的行为
我想出了一个相当“黑客”的把戏,只将BottomNavigationView
放在BottomAppBar的顶部,而不提供背景,从而使其透明
乍一看,这似乎效果不错,但我发现只有在触摸按钮的上半部分时才能单击fab按钮(因此顶部没有透明的BottomNavigationView
)
有没有什么方法可以实现这个想法,让我可以完全点击FloatingActionButton
第一条路
尝试此操作,您可以创建一个CustomBottomNavigationView
这是一篇关于CustomBottomNavigationView
示例代码
import android.content.Context;
import android.graphics.*;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
public class CustomBottomNavigationView extends BottomNavigationView {
private Path mPath;
private Paint mPaint;
/** the CURVE_CIRCLE_RADIUS represent the radius of the fab button */
private final int CURVE_CIRCLE_RADIUS = 128 / 2;
// the coordinates of the first curve
private Point mFirstCurveStartPoint = new Point();
private Point mFirstCurveEndPoint = new Point();
private Point mFirstCurveControlPoint1 = new Point();
private Point mFirstCurveControlPoint2 = new Point();
//the coordinates of the second curve
@SuppressWarnings("FieldCanBeLocal")
private Point mSecondCurveStartPoint = new Point();
private Point mSecondCurveEndPoint = new Point();
private Point mSecondCurveControlPoint1 = new Point();
private Point mSecondCurveControlPoint2 = new Point();
private int mNavigationBarWidth;
private int mNavigationBarHeight;
public CustomBottomNavigationView(Context context) {
super(context);
init();
}
public CustomBottomNavigationView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomBottomNavigationView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPath = new Path();
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setColor(ContextCompat.getColor(getContext(),R.color.colorAccent));
setBackgroundColor(Color.TRANSPARENT);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// get width and height of navigation bar
// Navigation bar bounds (width & height)
mNavigationBarWidth = getWidth();
mNavigationBarHeight = getHeight();
// the coordinates (x,y) of the start point before curve
mFirstCurveStartPoint.set((mNavigationBarWidth / 2) - (CURVE_CIRCLE_RADIUS * 2) - (CURVE_CIRCLE_RADIUS / 3), 0);
// the coordinates (x,y) of the end point after curve
mFirstCurveEndPoint.set(mNavigationBarWidth / 2, CURVE_CIRCLE_RADIUS + (CURVE_CIRCLE_RADIUS / 4));
// same thing for the second curve
mSecondCurveStartPoint = mFirstCurveEndPoint;
mSecondCurveEndPoint.set((mNavigationBarWidth / 2) + (CURVE_CIRCLE_RADIUS * 2) + (CURVE_CIRCLE_RADIUS / 3), 0);
// the coordinates (x,y) of the 1st control point on a cubic curve
mFirstCurveControlPoint1.set(mFirstCurveStartPoint.x + CURVE_CIRCLE_RADIUS + (CURVE_CIRCLE_RADIUS / 4), mFirstCurveStartPoint.y);
// the coordinates (x,y) of the 2nd control point on a cubic curve
mFirstCurveControlPoint2.set(mFirstCurveEndPoint.x - (CURVE_CIRCLE_RADIUS * 2) + CURVE_CIRCLE_RADIUS, mFirstCurveEndPoint.y);
mSecondCurveControlPoint1.set(mSecondCurveStartPoint.x + (CURVE_CIRCLE_RADIUS * 2) - CURVE_CIRCLE_RADIUS, mSecondCurveStartPoint.y);
mSecondCurveControlPoint2.set(mSecondCurveEndPoint.x - (CURVE_CIRCLE_RADIUS + (CURVE_CIRCLE_RADIUS / 4)), mSecondCurveEndPoint.y);
mPath.reset();
mPath.moveTo(0, 0);
mPath.lineTo(mFirstCurveStartPoint.x, mFirstCurveStartPoint.y);
mPath.cubicTo(mFirstCurveControlPoint1.x, mFirstCurveControlPoint1.y,
mFirstCurveControlPoint2.x, mFirstCurveControlPoint2.y,
mFirstCurveEndPoint.x, mFirstCurveEndPoint.y);
mPath.cubicTo(mSecondCurveControlPoint1.x, mSecondCurveControlPoint1.y,
mSecondCurveControlPoint2.x, mSecondCurveControlPoint2.y,
mSecondCurveEndPoint.x, mSecondCurveEndPoint.y);
mPath.lineTo(mNavigationBarWidth, 0);
mPath.lineTo(mNavigationBarWidth, mNavigationBarHeight);
mPath.lineTo(0, mNavigationBarHeight);
mPath.close();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(mPath, mPaint);
}
}
现在像这样使用
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinatorlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:layout_marginBottom="30dp"
android:clickable="true"
android:focusable="true" />
<neel.com.demo.CustomBottomNavigationView
android:id="@+id/customBottomBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/colorAccent"
app:labelVisibilityMode="labeled" />
</RelativeLayout>
输出
第二条路
我找到了一个更快的解决方案。我在frameLayout中包装了bottomnavigationview,一切都按预期工作。试试这个:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/lt_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:fitsSystemWindows="false">
<ViewPager
android:id="@+id/main_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/bottom_navigation"
android:layout_alignParentStart="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottom_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:clickable="false"
app:fabAlignmentMode="center" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
style="@style/BottomNavigationStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
app:menu="@menu/bottom_menu" />
</FrameLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="@id/bottom_bar" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
我尝试了几天,最后我用一个空的BottomAppBar
制作了一个FAB,上面叠加了一个透明背景的BottomNavigationView
在我的例子中,代码如下所示:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottom_app_bar"
style="@style/Widget.MaterialComponents.BottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="@color/colorGray"
app:fabAlignmentMode="center" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="bottom"
android:background="#80FFFFFF"
android:icon="@drawable/bottom_nav_ic_assignment"
app:itemIconTint="@color/bottom_nav_item_color"
app:itemTextColor="@color/bottom_nav_item_color"
app:labelVisibilityMode="selected"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" />
</FrameLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/addFab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:onClick="onFabClicked"
android:src="@drawable/ic_add_white"
app:backgroundTint="@color/colorBlue"
app:fabSize="auto"
app:layout_anchor="@+id/bottom_app_bar"
app:layout_anchorGravity="center|top" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
您可以将BottomAppBar视为工具栏,这意味着该类扩展了ViewGroup,以便您可以在BottomAppBar标记中添加相对布局、约束布局等。下面是一段代码,它将显示BottomAppBar中的2个按钮
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bar"
style="@style/Widget.MaterialComponents.BottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="@color/cardview_dark_background"
app:fabAlignmentMode="center">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/leftbutton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginRight="32dp"
android:text="LEFT"
android:textColor="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/rightbutton"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/rightbutton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="32dp"
android:layout_marginRight="16dp"
android:text="RIGHT"
android:textColor="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/leftbutton"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.bottomappbar.BottomAppBar>
对于所有使用第二种方法并希望在第一个文本视图之前删除意外空格的用户:
只需设置app:contentInsetStart=“0dp”
对于BottomAppBar
有一种更简单的方法来组合这三个小部件。我们可以有类似于:
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="?attr/actionBarSize" />
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottomBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="?attr/colorPrimary"
app:contentInsetEnd="0dp"
app:contentInsetStart="0dp"
app:fabAlignmentMode="end">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigation"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:backgroundTint="@android:color/transparent"
app:elevation="0dp"
android:layout_marginEnd="100dp"
app:itemIconTint="@android:color/white"
app:itemRippleColor="@android:color/white"
app:itemTextColor="@android:color/white"
app:menu="@menu/menu_activity_home_bottom_navigation" />
</com.google.android.material.bottomappbar.BottomAppBar>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:src="@drawable/ic_add_white_24dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="@id/bottomBar" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
如果你认为有更好的方法,请随意编辑/评论,这样我就可以修改帖子:)为什么不在单击fab图标时调用中底导航视图按钮时调用相同的函数呢?因为中间导航项是不可见的,所以我也想到了一个可能的解决方案。晶圆厂是可点击/可聚焦的,因此在完美的场景中,我不希望在按钮下方点击时产生连锁反应。BottomAppBar
只是一个专用的工具栏。您是否考虑过尝试将您自己的标签按钮直接添加到该按钮中?与覆盖BottomNavigationView
相比,似乎没有那么黑客。这种黑客方法的原因是将FAB的行为保持在BottomAppBar中。(例如动画)。也许有人对我有一个有用的解决方案,否则我应该使用我自己的按钮。不,我的意思是,保留BottomAppBar
(以及它的FloatingActionButton
),并向其添加按钮,而不是覆盖BottomNavigationView
。这不应该影响工厂。@caspargerlings欢迎告诉我是否有任何帮助required@NileshRathod我发现“第二条路”可能是最接近我所希望的。再次感谢大家!我尝试了第一种工作方式,我只想在晶圆厂的两边有一个项目,我该怎么做that@NileshRathod在第二种方法中,在BottomAppBar中的第一个textView之前还有一些空间,请您帮助删除它好吗?对于第二种解决方案,有人知道如何设置textview的样式,以便在单击时显示为活动吗?这非常有效,尤其是在使用BottomAppBar添加FAB时。在过去的几个小时里,我一直在努力解决这个问题,谢谢!您在BottomNavigationStyle=“@style/BottomNavigationStyle”中定义了什么样的样式?您如何像处理底部导航上的其他项目一样处理晶圆厂操作?晶圆厂定位在中心时,它不起作用。@Shefchenko中心模式可以很好地工作。只需使用<代码>应用程序:FabCenter模式=“Center”< /C> > Shefchenko在中间工作,只需添加<代码>应用程序:FabCenter模式=“Center”<代码>,如GrafOrlov所说,并删除<代码> Android:LayOut.MangiNeNe=“100DP”这似乎不适用于API 21,在我的手机上运行最新版本的Android WorksPrimes,但是在API 21上的模拟器中运行它会显示两倍大的BottomAppBar,并且BottomNavigationView保持固定在顶部,就像它有一个边距一样。您如何像底部导航上的其他项目一样处理FAB操作?
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottom_app_bar"
style="@style/Widget.MaterialComponents.BottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="@color/colorGray"
app:fabAlignmentMode="center" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="bottom"
android:background="#80FFFFFF"
android:icon="@drawable/bottom_nav_ic_assignment"
app:itemIconTint="@color/bottom_nav_item_color"
app:itemTextColor="@color/bottom_nav_item_color"
app:labelVisibilityMode="selected"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" />
</FrameLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/addFab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:onClick="onFabClicked"
android:src="@drawable/ic_add_white"
app:backgroundTint="@color/colorBlue"
app:fabSize="auto"
app:layout_anchor="@+id/bottom_app_bar"
app:layout_anchorGravity="center|top" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bar"
style="@style/Widget.MaterialComponents.BottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="@color/cardview_dark_background"
app:fabAlignmentMode="center">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/leftbutton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginRight="32dp"
android:text="LEFT"
android:textColor="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/rightbutton"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/rightbutton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="32dp"
android:layout_marginRight="16dp"
android:text="RIGHT"
android:textColor="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/leftbutton"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.bottomappbar.BottomAppBar>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="?attr/actionBarSize" />
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottomBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="?attr/colorPrimary"
app:contentInsetEnd="0dp"
app:contentInsetStart="0dp"
app:fabAlignmentMode="end">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigation"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:backgroundTint="@android:color/transparent"
app:elevation="0dp"
android:layout_marginEnd="100dp"
app:itemIconTint="@android:color/white"
app:itemRippleColor="@android:color/white"
app:itemTextColor="@android:color/white"
app:menu="@menu/menu_activity_home_bottom_navigation" />
</com.google.android.material.bottomappbar.BottomAppBar>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:src="@drawable/ic_add_white_24dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="@id/bottomBar" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>