CoordinatorLayout
为什么我们会在最后讲解该布局呢?,就是因为它是一个布局而非组件,如果我们单独放置CoordinatorLayout是看不到人和效果的,随意前面讲解了Material Design风格的其它控件,这样方便我们结合展示。
- 官方解释
CoordinatorLayout扩展了完成许多Google Material Design 滚动效果的能力。目前,在这个框架中提供了几种方法,它允许它在不需要编写自己的自定义动画代码的情况下工作。
那么CoordinatorLayout用法有哪些呢?
Floating Action Button和SnackBar同时存在
当Floating Action Button和SnackBar都要存在时,就会有SnackBar向上弹出时Floating Action Button占有空间的问题,所以需要CoordinatorLayout来控制它们之间的关联和行为。
首先创建activity_button_snack.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvToDoList"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
android:src="@mipmap/ic_launcher"
app:layout_anchor="@id/rvToDoList"
app:layout_anchorGravity="bottom|right|end"/>
</android.support.design.widget.CoordinatorLayout>
那么我们看看FloatingButtonAndSnackSimple.class的代码
recyclerAdapter = new RecyclerAdapter(this,mlist);
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(recyclerAdapter);
recyclerAdapter.setOnItemClickLitener(new RecyclerAdapter.OnItemClickLitener() {
@Override
public void onItemClick(View view, int position) {
Snackbar.make(main_content, mlist.get(position), Snackbar.LENGTH_LONG)
.setAction(R.string.snackbar_action, null)
.setActionTextColor(getResources().getColor(R.color.colorAccent))
.setDuration(3000).show();
}
});
可以看到这里我们没有处理任何有关Floating Action Button的事,那么它到底是哪里设置了Floating Action Button的上滑事件?
app:layout_anchor="@id/rvToDoList"
app:layout_anchorGravity="bottom|right|end"
没错就是这么两句话,无需我们再写任何的动画就达到效果,运行结果如下:
ToolBar和RecyclerView同时存在
这里我不再新建页面,主要是刚好嗯能进行整合。
布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"/>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/rvToDoList"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
android:src="@mipmap/ic_launcher"
app:layout_anchor="@id/rvToDoList"
app:layout_anchorGravity="bottom|right|end"/>
</android.support.design.widget.CoordinatorLayout>
我们再看下FloatingButtonAndSnackSimple.class
/**
* Created by 泅渡者
* Created on 2017/10/19.
*/
public class FloatingButtonAndSnackSimple extends AppCompatActivity {
private RecyclerView recyclerView;
private RecyclerAdapter recyclerAdapter;
private List<String> mlist;
private CoordinatorLayout main_content;
private Toolbar toolbar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_button_snack);
initView();
}
private void initView() {
toolbar = (Toolbar)findViewById(R.id.toolbar);
toolbar.setTitle("FloatingButtonAndSnackSimple");
setSupportActionBar(toolbar);
mlist = new ArrayList<>();
for (int i = 1; i < 100; i++) {
mlist.add("第" + i + "行");
}
recyclerView = (RecyclerView) findViewById(R.id.rvToDoList);
main_content = (CoordinatorLayout) findViewById(R.id.main_content);
recyclerAdapter = new RecyclerAdapter(this,mlist);
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(recyclerAdapter);
recyclerAdapter.setOnItemClickLitener(new RecyclerAdapter.OnItemClickLitener() {
@Override
public void onItemClick(View view, int position) {
Snackbar.make(main_content, mlist.get(position), Snackbar.LENGTH_LONG)
.setAction(R.string.snackbar_action, null)
.setActionTextColor(getResources().getColor(R.color.colorAccent))
.setDuration(3000).show();
}
});
}
}
效果显示,视图滚动时,Toolbar会隐藏,这个效果是Android Support Library里面,新增的CoordinatorLayout, AppBarLayout实现的。通过AppBarLayout的子视图的属性控制。观察AppBarLayout的子布局,Toobar有app:layout_scrollFlags属性,这就是控制滑动时视图效果的属性。app:layout_scrollFlags有四个值:
- scroll: 所有想滚动出屏幕的view都需要设置这个flag, 没有设置这个flag的view将被固定在屏幕顶部。例如,TabLayout 没有设置这个值,将会停留在屏幕顶部。
- enterAlways: 设置这个flag时,向下的滚动都会导致该view变为可见,启用快速“返回模式”。
- enterAlwaysCollapsed: 当你的视图已经设置minHeight属性又使用此标志时,你的视图只能已最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。
- exitUntilCollapsed: 滚动退出屏幕,最后折叠在顶端。
注:AppBarLayout必须作为CoordinatorLayout的直接子View,否则它的大部分功能将不会生效,如layout_scrollFlags等,记住,要把带有scroll flag的view放在前面,这样收回的view才能让正常退出,而固定的view继续留在顶部。
为了使得Toolbar有滑动效果,必须做到如下三点:
- CoordinatorLayout作为布局的父布局容器。
- 给需要滑动的组件设置 app:layout_scrollFlags=”scroll|enterAlways” 属性。
- 给滑动的组件设置app:layout_behavior属性(如RecyclerView)
AppBarLayout嵌套CollapsingToolbarLayout
布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="256dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
android:src="@drawable/header"
app:layout_collapseMode="parallax"
/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin"
app:navigationIcon="@drawable/back"
/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/rvToDoList"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<android.support.design.widget.FloatingActionButton
android:layout_width="179dp"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
android:src="@mipmap/ic_launcher"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="clip_vertical|right"/>
</android.support.design.widget.CoordinatorLayout>
这里主要看AppBarLayout、CollapsingToolbarLayout、Toolbar、FloatingActionButton的布局属性以及放置位置。
CollapsingToolbarLayout 。
CollapsingToolbarLayout可实现Toolbar的折叠效果。CollapsingToolbarLayout的子视图类似与LinearLayout垂直方向排放。
CollapsingToolbarLayout 提供以下属性和方法是用:
- Collapsing title:ToolBar的标题,当CollapsingToolbarLayout全屏没有折叠时,title显示的是大字体,在折叠的过程中,title不断变小到一定大小的效果。你可以调用setTitle(CharSequence)方法设置title。
- Content scrim:ToolBar被折叠到顶部固定时候的背景,你可以调用setContentScrim(Drawable)方法改变背景或者 在属性中使用 app:contentScrim=”?attr/colorPrimary”来改变背景。
- Status bar scrim:状态栏的背景,调用方法setStatusBarScrim(Drawable)。还没研究明白,不过这个只能在Android5.0以上系统有效果。
- Parallax scrolling children:CollapsingToolbarLayout滑动时,子视图的视觉差,可以通过属性app:layout_collapseParallaxMultiplier=”0.6”改变。值de的范围[0.0,1.0],值越大视察越大。
- CollapseMode :子视图的折叠模式,在子视图设置,有两种“pin”:固定模式,在折叠的时候最后固定在顶端;“parallax”:视差模式,在折叠的时候会有个视差折叠的效果。我们可以在布局中使用属性app:layout_collapseMode=”parallax”来改变。
CoordinatorLayout 还提供了一个 layout_anchor 的属性,连同 layout_anchorGravity 一起,可以用来放置与其他视图关联在一起的悬浮视图(如 FloatingActionButton)。本例中使用FloatingActionButton。
通过下面的参数设置了FloatingActionButton的位置,两个属性共同作用使得FAB 浮动按钮也能折叠消失,展现。
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"
使用CollapsingToolbarLayout实现折叠效果,需要注意3点
- AppBarLayout的高度固定
- CollapsingToolbarLayout的子视图设置layout_collapseMode属性
-
关联悬浮视图设置app:layout_anchor,app:layout_anchorGravity属性