文章目录
- 一、前言
- 二、添加依赖:
- 三、一个简单的示例
- 四、AppBarLayout
- 五、CoordinatorLayout
- 六、子控件相对于父控件的位置
- 六、滑动效果的配置
- 七、layout_scrollFlags属性
- 八、CollapsingToolbarLayout
- 1、简单示例
- 2、Collapsing title 的状态
- 3、contentScrim
- 4、statusBarScrim
- 5、layout_collapseMode
- 6、监听滑动状态
- 九、Behavior
- 十、FloatingActionButton
- 十一、SwipeDismissBehavior
- 十二、BottomSheetBehavior
- 十三、参考链接
一、前言
官方有一些组件AppbarLayout
,CollapsingToolbarLayout
和CoordinatorLayout
。这些组件需要配套使用来完成。无法单独进行使用。其中CollapsingToolbarLayout
是可选的。通常整个布局结构如下:
<CoordinatorLayout>
<AppbarLayout/>
<scrollableView/>
<FloatingActionButton/>
</CoordinatorLayout>
二、添加依赖:
使用需要添加以下依赖:
implementation ':material:1.5.0'
三、一个简单的示例
这里用一个简单的效果作为开篇示例。比如通过滑动可以使title随着滑动显示隐藏。
<?xml version="1.0" encoding="utf-8"?>
< xmlns:android="/apk/res/android"
xmlns:app="/apk/res-auto"
xmlns:tools="/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/black"
android:minHeight="?attr/actionBarSize"
android:paddingEnd="20dp"
app:layout_scrollFlags="scroll|enterAlways"
app:title="少数的"
app:titleTextColor="@android:color/white" />
</>
<
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="1500dp"
android:background="#d7e8d2"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="500dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="500dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第二届" />
</FrameLayout>
</LinearLayout>
</>
</>
四、AppBarLayout
AppBarLayout
是LinearLayout
的子类。里面可以写多种布局,一般来说里面是写Toolbar
。通过滑动控制显示隐藏,源码的示例代码如下:
<
xmlns:android="/apk/res/android"
xmlns:app="/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<!-- Your scrolling content -->
</>
<
android:layout_height="wrap_content"
android:layout_width="match_parent">
<
...
app:layout_scrollFlags="scroll|enterAlways"/>
<
...
app:layout_scrollFlags="scroll|enterAlways"/>
</>
</>
五、CoordinatorLayout
CoordinatorLayout
是一个ViewGroup
的子类。想要布局进行滑动,其父布局需要使用这个组件作为容器。需要注意的是想要布局能够滑动,不止是NestedScrollView
。只要是NestedScrollingChild
接口的子类都可以,随着版本不同,其中内容不一样,这里列举下常用的几个,分别是:NavigationMenuView
、NestedScrollView
、RecyclerView
、ViewPager2
等。
六、子控件相对于父控件的位置
使用app:layout_anchor
和app:layout_anchorGravity
属性,指定子视图相对于其它子视图的位置。其中app:layout_anchor
表示当前以哪个视图做为参照物,app:layout_anchorGravity
表示本视图相对于参照物的对齐方式。
示例代码如下:
<?xml version="1.0" encoding="utf-8"?>
<
xmlns:android="/apk/res/android"
xmlns:app="/apk/res-auto"
xmlns:tools="/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
>
<
android:id="@+id/"
android:layout_width="match_parent"
android:layout_height="300dp"
android:theme="@style/"
>
...
</>
...
<
...
app:layout_anchor="@id/"
app:layout_anchorGravity="bottom|right|end"
/>
</>
六、滑动效果的配置
需要滑动的话还需要做两个配置
- 将
ScrollView
和AppBarLayout
关联起来,这里需要使用behavior,进行关联。不过自定义比较麻烦,官方提供了简单的方式,如下
<
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
</>
- 在
AppBarLayout
的子类中编写layout_scrollFlags
属性,例如:
<
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<
...
app:layout_scrollFlags="scroll|enterAlways"
...
/>
</>
七、layout_scrollFlags属性
这个属性比较复杂,这里简单记录下,在日常工作中多多使用来进行理解
可配置属性有以下几种
scroll
enterAlways
enterAlwaysCollapsed
exitUntilCollapsed
snap
其中 scroll
是必选的,如果使用其它属性需要与它一起使用,中间用|
隔开,如下
app:layout_scrollFlags="scroll|enterAlways"
这里解释下这几个参数的含义:scroll
:跟随View的滚动事件一起滚动enterAlways
:当ScrollView向下移动时则向下滚动,不关心ScrollView是否滚动。所以在使用这个标识的时候,可以发现当ToolBar
移动出来后,NestedScrollView
可以继续向下滑动,把剩余的内容拉出来,但是scroll
标识不行。
exitUntilCollapsed:向上滑动时,首先是ScrollView跟随Toolbar向上滑动,直到Toolbar达到最小宽度ScrollView开始滚动。这个需要和minHeight
配合使用,如下:
<
...
android:layout_height="200dp"
android:minHeight="100dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
...
/>
enterAlwaysCollapsed
:向下滑动时,首先是enterAlways
效果,当ScrollView
的高度达到最小高度时,Toolbar
停止滑动,直到ScrollView
不再滑动时,Toolbar
继续滑动直到结束。这里需要用到三个标识,示例如下:
<
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@color/black"
android:minHeight="100dp"
android:paddingEnd="20dp"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
app:title="少数的"
app:titleTextColor="@android:color/white" />
snap:
这个效果和ViewPage
的滑动效果类似,当到达一个边界的时候,如果停止滑动,会根据边界来决定是滑动回来,还是滑动过去。这个边界值暂时不知道怎么修改。示例代码如下:
<
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@color/black"
android:paddingEnd="20dp"
app:layout_scrollFlags="scroll|snap"
app:title="少数的"
app:titleTextColor="@android:color/white" />
这里可以根据不同情况单独定制上下滑动效果, 例如:
<
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@color/black"
android:minHeight="50dp"
android:paddingEnd="20dp"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed|exitUntilCollapsed"
app:title="少数的"
app:titleTextColor="@android:color/white" />
这里引用以下内容:
layout_scrollFlags 之间的配合使用
滑动方向可以分为 enter 和 exit 两种。
而按照每个方向上的行为类别划分,又有不同的行为。
其它行为可以*搭配,比如定制一个 enter 时enterAlwaysCollapsed
,exit 时exitUntilCollapsed
的行为。
<
android:id="@+id/appbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/">
<.
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="250dp"
android:minHeight="100dp"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed|exitUntilCollapsed" />
</>
八、CollapsingToolbarLayout
CollapsingToolbarLayout
可以使AppBarLayout
中的布局内容效果能加炫丽。主要有以下几个特性:
- Collapsing Title 可折叠的标题
- Content Scrim 内容纱布
- Status bar scrim 状态栏纱布
- Parallax scrolling children 子 View 的视差滚动行为
- Pinned position children 子类的位置固定行为
1、简单示例
将上述代码简单修改为以下代码:
<
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="250dp">
<
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/background_light"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:paddingEnd="20dp"
android:background="?attr/colorPrimary"
app:title="少数的"
app:titleTextColor="@android:color/white" />
</>
</>
进行滑动则会发现Toolbar里面的文字会随上下移动而变大缩小。同时需要注意的是Toolbar
因为设置了颜色,会很明显的发现Toolbar
中的文字没有在Toolbar
里面显示。如果在CollapsingToolbarLayout
中设置 app:title="啦啦啦"
属性,会发现CollapsingToolbarLayout
中的标题覆盖了Toolbar
中的标题。
因为CollapsingToolbarLayout
和Toolbar
都设置了颜色,会发现这两个布局重叠了一起,这是因为CollapsingToolbarLayout
是FrameLayout
子类的原因。
这里还有一个注意的点。CollapsingToolbarLayout
高度需要大于其内容的高度,否则内容无法显示。例如以下布局,虽然内容也能显示,但是显示会有问题,所以为了便于控制,一般都是AppBarLayout
写固定高度,CollapsingToolbarLayout
使用match_parent
。Toolbar
使用android:layout_height="?attr/actionBarSize"
。
<
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="250dp">
<
android:layout_width="match_parent"
android:layout_height="200dp"
app:title="啦啦啦"
android:background="@android:color/background_light"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="150dp"
android:paddingEnd="20dp"
android:background="?attr/colorPrimary"
app:title="少数的"
app:titleTextColor="@android:color/white" />
</>
</>
2、Collapsing title 的状态
这里主要参考其它人的帖子,引用如下:
需要注意的是 Collapsing title 有两种状态,分别是 展开(Expanded) 和 折叠(Collapsed)。
可以运用代码对 Collapsing title 进行如下操作
setTitle(CharSequence title)
setTitleEnabled(boolean enabled)
setCollapsedTitleGravity(int gravity)
setCollapsedTitleTextAppearance(int resId)
setCollapsedTitleTextColor(int color)
setCollapsedTitleTypeface(Typeface typeface)
setExpandedTitleColor(int color)
setExpandedTitleGravity(int gravity)
setExpandedTitleMargin(int start, int top, int end, int bottom)
setExpandedTitleMarginBottom(int margin)
setExpandedTitleMarginEnd(int margin)
setExpandedTitleMarginStart(int margin)
setExpandedTitleMarginTop(int margin)
setExpandedTitleTextAppearance(int resId)
setExpandedTitleTextColor(ColorStateList colors)
setExpandedTitleTypeface(Typeface typeface)
同时,在 xml 布局文件中也可以通过相应的属性操作 Collapsing title 的行为。
app:title
app:titleEnabled
app:titleCollapseMode="fade"<!--设置文字切换的样式,可选为fade/scale。默认为scale-->
app:collapsedTitleGravity
app:collapsedTitleTextAppearance<!--设置上拉收缩完成后,ToolBar标题文字的样式-->
app:collapsedTitleTextColor <!--设置上拉收缩完成后,ToolBar标题文字的颜色-->
app:expandedTitleGravity
app:expandedTitleMargin
app:expandedTitleMarginBottom
app:expandedTitleMarginEnd <!--设置下拉展开完成后,ToolBar标题文字右边的margin距离-->
app:expandedTitleMarginStart <!--设置下拉展开完成后,ToolBar标题文字左边的margin距离-->
app:expandedTitleMarginTop
app:expandedTitleTextAppearance<!--设置下拉展开完成后,ToolBar标题文字的样式-->
app:expandedTitleTextColor <!--设置下拉展开完成后,ToolBar标题文字的颜色-->
更多属性参考官方文档
3、contentScrim
在CollapsingToolbarLayout
有一个属性app:contentScrim="#ec0"
可以使内容折叠起来的时候,改变其遮盖颜色或者图片。具体示例如下:
<
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="250dp">
<
android:layout_width="match_parent"
android:layout_height="match_parent"
app:title="啦啦啦"
app:contentScrim="#ec0"
android:background="@android:color/background_light"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/material_flat"
android:scaleType="centerCrop"/>
<
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:paddingEnd="20dp"
app:title="少数的"
app:titleTextColor="@android:color/white" />
</>
这个解释还是引用其他博主的,
AppBarLayout 和 CollapsingToolbarLayout 已经提供给 Toolbar 很炫丽的动作效果,但是,如果你认为这还不够,如果你想一种更直接的视觉反馈,这种反馈标志 CollapsingToolbarLayout 中折叠状态的变化时,你可以运用 Content scrim 这个概念。
指定 Contetn scrim 后,CollapsingToolbarLayout 会在折叠状态显示指定的颜色或者是图片,它就像是一块纱布一样遮住 title 下面的内容,所以被称为内容纱布。
注意我的措辞,我说的是 Content scrim 会遮住 title 下方的内容部分。如果一个 CollapsingToolbarLayout 中只有 Toolbar 的话,那么它就不起作用。CollapsingToolbarLayout 本质上是一个 FrameLayout,所以需要在 Toolbar 的前面位置加入其它的 View 作为内容,Content scrim 才会起作用。
代码可配置选项有
void setContentScrimColor (int color)
void setContentScrimResource (int resId)
void setContentScrim (Drawable drawable)
4、statusBarScrim
statusBarScrim
与contentScrim
功能类似,不过作用范围是状态栏,如果想启用该标识,还需要设置AppBarLayout
的fitsSystemWindows
为 true。相关代码如下:
<style name="" parent="">
...
<!-- Customize your theme here. -->
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowTranslucentStatus">true</item><!--设置沉浸式状态栏-->
</style>
<?xml version="1.0" encoding="utf-8"?>
< xmlns:android="/apk/res/android"
...
android:fitsSystemWindows="true" <!--设置沉浸式状态栏-->
tools:context=".MainActivity">
<
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="250dp">
<
android:layout_width="match_parent"
android:layout_height="match_parent"
app:title="啦啦啦"
app:statusBarScrim="#f00" <!---设置状态栏颜色-->
app:contentScrim="#ec0"
android:background="@android:color/background_light"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
...
</>
</>
...
</>
5、layout_collapseMode
该值可以设置子控件的视差行为,有以下三个值:
-
off
:默认属性,布局将正常显示,无折叠行为。 -
pin
:CollapsingToolbarLayout
折叠后,此布局将固定在顶部。 -
parallax
:CollapsingToolbarLayout
折叠时,此布局也会有视差折叠效果。
该值需要设置在子控件上面。
这里讲述下parallax
的场景
关于该值的解释引用如下
如何理解视差?就是滚动的速度不同,造成的视觉差异效果。也就是说 CollapsingToolbarLayout 中有的 view 滚动的快一些,其它的滚动的慢一些。
它滚动的快慢受 Parallax multiplier 这个因子的影响,默认值为 DEFAULT_PARALLAX_MULTIPLIER。也就是 0.5f。也就是正常速度的一半。
可以通过 setParallaxMultiplier(float) 方法来设置滚动的速度因子。
也可以通过app:layout_collapseParallaxMultiplier="0.7"
来设置,相关代码如下:
<
android:layout_width="match_parent"
android:layout_height="match_parent"
app:title="啦啦啦"
app:statusBarScrim="#f00"
app:contentScrim="#ec0"
android:background="@android:color/background_light"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/material_flat"
android:scaleType="centerCrop"/>
<
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:paddingEnd="20dp"
android:background="@color/white"
app:layout_collapseMode="parallax" <!-- 设置视差模式-->
app:layout_collapseParallaxMultiplier="3"<!--设置视差因数,值越大,值为正常速度的倍数,0.5相当于正常速度的一半 -->
app:title="少数的"
app:titleTextColor="@android:color/white" />
</>
这里讲述下pin
的场景。将刚才的值进行修改,会发现无论怎么滑动,子控件的位置都不会改变,如下
app:layout_collapseMode="pin"
6、监听滑动状态
可以通过监听滑动的状态来进行更多操作,比如,滑动过程中改变透明度。这里是监听AppBarLayout
的void onOffsetChanged (AppBarLayout appBarLayout, int verticalOffset)
接口,
verticalOffset 是 AppBarLayout 相对于完全展开时没有滑动的距离。它在初始位置为 0,其它时候都为负数。它绝对值的最大值为 AppBarLayout 的 TotalScollRange。
示例代码如下:
final ImageView circleIcon = (ImageView) findViewById(R.id.circle_icon);
AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.app_bar);
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
int newalpha = 255 + verticalOffset;
newalpha = newalpha < 0 ? 0 : newalpha;
circleIcon.setAlpha(newalpha);
}
});
九、Behavior
在CoordinatorLayout
是多个控件进行联动的方式是通过类来进行的。之前的操作都是使用系统默认的
Behavior
来进行的。这里,使用探索下自定义的方式.Behavior
是一个抽象类,由于源码过多,这里就不贴出源码,感兴趣可以自行查看。Behavior
需要考虑两个核心元素,child和dependency。child是表示用来我们想要进行变化的子控件,dependency是我们想要根据哪些控件进行变化。
明白的需求,那么开始编码时候需要继承类,并拓展两个函数:
-
layoutDependsOn
相关源码定义如下:
public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull V child,
@NonNull View dependency) {
return false;
}
-
onDependentViewChanged
相关源码定义如下:
public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent, @NonNull V child,
@NonNull View dependency) {
return false;
}
layoutDependsOn
每次布局中发生某些事情时都会调用,true一旦我们识别出依赖关系,我们必须做什么才能返回,在示例中,当用户滚动时(因为Toolbar将移动),该方法会自动触发,以这种方式我们可以让孩子的视力做出相应的反应。
示例如下:
@Override
public boolean layoutDependsOn(
CoordinatorLayout parent,
ImageView, child,
View dependency) {
return dependency instanceof Toolbar;
}
倘若layoutDependsOn
返回true,就会调用onDependentViewChanged
函数,所以需要在这里做一些操作,示例如下:
public boolean onDependentViewChanged(
CoordinatorLayout parent,
ImageView avatar,
View dependency) {
modifyAvatarDependingDependencyState(avatar, dependency);
}
private void modifyAvatarDependingDependencyState(
ImageView avatar, View dependency) {
// (());
// ( / blah);
}
完整代码如下:
public static class AvatarImageBehavior
extends
CoordinatorLayout.Behavior<ImageView> {
@Override
public boolean layoutDependsOn(
CoordinatorLayout parent,
ImageView, child,
View dependency) {
return dependency instanceof Toolbar;
}
public boolean onDependentViewChanged(
CoordinatorLayout parent,
ImageView avatar,
View dependency) {
modifyAvatarDependingDependencyState(avatar, dependency);
}
private void modifyAvatarDependingDependencyState(
ImageView avatar, View dependency) {
// (());
// ( / blah);
}
}
定义完后如何使用,需要在xml中使用:
<ImageView
android:layout_width="@dimen/image_width"
android:layout_height="@dimen/image_width"
android:layout_gravity="center_horizontal"
android:src="@drawable/quila"
app:layout_behavior=""
app:startHeight="2dp"
app:startToolbarPosition="2dp"
app:startXPosition="2dp"
/>
参考代码链接:
CoordinatorBehaviorExample
十、FloatingActionButton
如果使用FloatingActionButton
会发现,虽然不进行额外设置,这个控件会随着滑动而进行改变,这里可以参考源码。
@Override
@NonNull
public CoordinatorLayout.Behavior<FloatingActionButton> getBehavior() {
return new FloatingActionButton.Behavior();
}
这个控件自己实现了Behavior
的滑动效果。
十一、SwipeDismissBehavior
在CoordinatorLayout
中可以很方便使用滑动关闭的功能,示例代码如下:
<?xml version="1.0" encoding="utf-8"?>
<
xmlns:android="/apk/res/android"
xmlns:app="/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<
xmlns:card_view="/apk/res-auto"
android:id="@+id/"
android:layout_width="match_parent"
android:layout_height="200dp"
card_view:cardCornerRadius="4dp"
card_view:contentPadding="8dp"
android:layout_margin="16dp"
app:layout_anchorGravity="bottom"
>
...
</>
</>
val mCardView = findViewById<CardView>(R.id.swype_card)
val swipe: SwipeDismissBehavior<CardView?> = SwipeDismissBehavior()
swipe.setSwipeDirection(
SwipeDismissBehavior.SWIPE_DIRECTION_ANY
)
swipe.listener = object : SwipeDismissBehavior.OnDismissListener {
override fun onDismiss(view: View?) {
Toast.makeText(
this@MainActivity,
"Card swiped !!", Toast.LENGTH_SHORT
).show()
}
override fun onDragStateChanged(state: Int) {}
}
val coordinatorParams: CoordinatorLayout.LayoutParams = mCardView.layoutParams as CoordinatorLayout.LayoutParams
coordinatorParams.behavior = swipe
十二、BottomSheetBehavior
有一种需求就是从底部弹出一个对话框,类似于Snackbar
,或者BottomSheetDialog
。使用官方提供的BottomSheetBehavior
也可以做到相应的需求。
这里引用其它博主的内容
app:behavior_hideable : 指定弹窗是否允许隐藏。
app:behavior_peekHeight : 指定弹窗的预览高度。
app:elevation : 指定弹窗的高程。
app:layout_behavior : 指定弹窗的行为,像底部弹窗固定取值"@string/bottom_sheet_behavior"。
BottomSheetBehavior在代码中使用的方法如下所示:
from : 从指定视图获取底部弹窗行为。
getState : 获取该行为的状态。
setState : 设置该行为的状态。取值STATE_EXPANDED表示完全展开;取值STATE_COLLAPSED表示折叠;取值STATE_HIDDEN表示隐藏。
setPeekHeight : 设置弹窗的预览高度,即setState取值STATE_COLLAPSED时设定的折叠高度。
setHideable : 设置弹窗是否允许隐藏。
相关代码如下:
<?xml version="1.0" encoding="utf-8"?>
< xmlns:android="/apk/res/android"
xmlns:app="/apk/res-auto"
xmlns:tools="/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondActivity">
<
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:text="点击"/>
<LinearLayout
android:id="@+id/ll_bottom"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#ffaaaa"
app:behavior_hideable="true"
app:behavior_peekHeight="50dp"
app:elevation="5dp"
app:layout_behavior="@string/bottom_sheet_behavior">
<TextView
android:id="@+id/tv_popup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="底部弹窗菜单"
android:textColor="#000000"
android:textSize="17sp"/>
</LinearLayout>
</>
class SecondActivity : AppCompatActivity() {
private var behavior: BottomSheetBehavior<View> ?= null
private val handler = Handler(Looper.getMainLooper())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
findViewById<View>(R.id.btn).setOnClickListener {
if (behavior?.state == BottomSheetBehavior.STATE_HIDDEN) {
behavior?.setState(BottomSheetBehavior.STATE_COLLAPSED)
} else {
behavior?.setState(BottomSheetBehavior.STATE_HIDDEN)
}
}
val ll_bottom = findViewById<View>(R.id.ll_bottom);
behavior = BottomSheetBehavior.from(ll_bottom);
//如果立即setState,会报错
handler.postDelayed({
behavior?.setState(BottomSheetBehavior.STATE_HIDDEN);
},500)
}
}
十三、参考链接
- 掌握协调器布局
- CoordinatorExamples
- 细说 AppbarLayout,如何理解可折叠 Toolbar 的定制
- CollapsingToolbarLayout
- CoordinatorBehaviorExample
- Android-CoordainatorLayout和AppBarLayout
- Android开发笔记(一百三十四)协调布局CoordinatorLayout