1、简介
今天来讲一下Android Design Support里面一个非常重要的组件:CoordinatorLayout。
在Material Design当中存在很多组件之间的交互,一般是以动画的形式呈现。在Design library当中引入了组件CoordinatorLayout,它是一个布局,继承自FrameLayout,通过协调调度子视图布局的形式来产生动画效果,来达到子控件之间的交互效果。
2、使用
(1)CoordinatorLayout和FloatingActionButton
这个我们在之前讲Snackbar的时候讲过,当我们把Snackbar依附于CoordinatorLayout的时候,当点击FloatingActionButton弹出Snackbar的时候,FloatingActionButton会自动上移,然后隔一段时间Snackbar消失后,FloatingActionButton就会自动归位。
1、布局文件
2、MainActivity代码:
package com.easyliu.coordinatorlayoutdemos;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
public class FloatingActionButtonActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_floating_action_button);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(FloatingActionButtonActivity.this.findViewById(R.id.coordinator1), "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", new View.OnClickListener() {
@Override
public void onClick(View view) {
}
}).show();
}
});
}
}
3、效果如下:
(2)CoordinatorLayout和AppBarLayout
CoordinatorLayout最主要的用途就是和appbar一起使用。Design library当中引入了AppBarLayout,用来允许Toolbar和其他的视图比如TabLayout对其他滚动的视图做出反应,那个滚动的视图必须标记ScrollingViewBehavior。
1、AppBarLayout当中嵌套TabLayout
布局文件:
当往上滚动RecyclerView的时候,Toolbar会隐藏起来。
要想达到Toolbar隐藏的效果,看以上的布局文件,有几点说明:
1、首先顶层布局必须是CoordinatorLayout
2、给需要隐藏的组件设置 app:layout_scrollFlags滚动标志,比如这里的Toolbar。这个标志有四种,如下所示:
scroll: 所有想滚动出屏幕的view都需要设置这个flag, 没有设置这个flag的view将被固定在屏幕顶部。例如TabLayout 没有设置这个值,将会停留在屏幕顶部。
enterAlways: 设置这个flag时,向下的滚动都会导致该view变为可见,启用快速“返回模式”。
enterAlwaysCollapsed: 当你的视图已经设置minHeight属性又使用此标志时,你的视图只能以最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。
exitUntilCollapsed: 滚动退出屏幕,最后折叠在顶端。
特别需要注意的是:所有使用scroll标志的组件必须放在没有使用这个标志的组件之前,比如前面的Toolbar放在TabLayout之前,Toolbar使用了scroll标志,而TabLayout没有使用这个标志。这样可以确保所有的视图从顶部退出,留下固定的没有使用这个标志的元素在后面显示出来!
3、给可以滑动组件设置app:layout_behavior属性,这里给ViewPager设置了此属性为app:layout_behavior="@string/appbar_scrolling_view_behavior",这个是系统自带的效果。
2、AppBarLayout当中嵌套CollapsingToolbarLayout
通过把一个Toolbar直接加入到AppBarLayout当中,可以获取到两个collapsing标志:enterAlwaysCollapsed和enterAlwaysCollapsed,但是并没有详细的控制关于怎么对这个collapsing做出反应,所以在Design library当中又引入了CollapsingToolbarLayout。
首先是布局文件:
关于CollapsingToolbarLayout,有几个属性说明:
1、Collapsing title:ToolBar的标题,当CollapsingToolbarLayout全屏没有折叠时,title显示的是大字体,在折叠的过程中,title不断变小到一定大小的效果。你可以调用setTitle(CharSequence)方法设置title。
2、Content scrim:ToolBar被折叠到顶部固定时候的背景,你可以调用setContentScrim(Drawable)方法改变背景或者 在属性中使用 app:contentScrim=”?attr/colorPrimary”来改变背景。 注意这里我们不能给Toolbar设置背景,不然没有透明效果!
3、Status bar scrim:状态栏的背景,调用方法setStatusBarScrim(Drawable)。不过这个只能在Android5.0以上系统有效果。
4、Parallax scrolling children:CollapsingToolbarLayout滑动时,子视图的视觉差,可以通过属性app:layout_collapseParallaxMultiplier=”0.6”改变。值de的范围[0.0,1.0],值越大视察越大。
5、CollapseMode :子视图的折叠模式,在子视图设置,有两种模式。“pin”:固定模式,在折叠的时候最后固定在顶端;“parallax”:视差模式,在折叠的时候会有个视差折叠的效果。我们可以在布局中使用属性app:layout_collapseMode=”parallax”来改变。
比如这里Toolbar就设置成了"pin"模式,然后ImageView就设置成了parallax模式。
6、如果我们把CollapsingToolbarLayout的layout_scrollFlags的exitUntilCollapsed标志去掉,那么CollapsingToolbarLayout里面的控件在折叠的时候都不会显示在顶端,都会隐藏起来,忽略控件的折叠模式。
7、同时标志exitUntilCollapsed本身就包含Toolbar折叠到顶端,如果此时把Toolbar的app:layout_collapseMode设置为"parallax",那么Toolbar在折叠到顶端的时候,图标和菜单都不会显示出来,这个需要注意一下,所以一般把Toolbar的app:layout_collapseMode设置为"pin",这个读者可以自己试一下!
CoordinatorLayout 还提供了一个 layout_anchor 的属性,连同 layout_anchorGravity 一起,可以用来放置与其他视图关联在一起的悬浮视图(如 FloatingActionButton)。本例中使用FloatingActionButton。
通过下面的参数设置了FloatingActionButton的位置,两个属性共同作用使得FAB 浮动按钮也能折叠消失,展现。
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"
3. 关联悬浮视图设置app:layout_anchor,app:layout_anchorGravity属性
3、自定义behavior
CoordinatorLayout功能如此强大,而他的神奇之处在于Behavior对象,CoordinatorLayout自己并不控制View,所有的控制权都在Behavior。前面写到了FloatingActionButton.Behavior,AppBarLayout.Behavior, AppBarLayout.ScrollingViewBehavior。 AppBarLayout中有两个Behavior,一个是拿来给它自己用的,另一个是拿来给它的兄弟结点用的。这些Behavior实现了复杂的控制功能。系统的Behavior毕竟有限,我们可以通过自定义的方式来实现自己的Behavior。
通过继承自 CoordinatorLayout.Behavior
比如我们查看FloatingActionButton,里面有一个静态的内部类:Behavior,继承自CoordinatorLayout.Behavior
/**
* Behavior designed for use with {@link FloatingActionButton} instances. Its main function
* is to move {@link FloatingActionButton} views so that any displayed {@link Snackbar}s do
* not cover them.
*/
public static class Behavior extends CoordinatorLayout.Behavior {
// We only support the FAB <> Snackbar shift movement on Honeycomb and above. This is
// because we can use view translation properties which greatly simplifies the code.
private static final boolean SNACKBAR_BEHAVIOR_ENABLED = Build.VERSION.SDK_INT >= 11;
private ValueAnimatorCompat mFabTranslationYAnimator;
private float mFabTranslationY;
private Rect mTmpRect;
app:layout_behavior=”com.example.app.YourView$Behavior属性来达到效果!
当然,我们也可以继承自现成的Behavior,比如现在有一个需求:当滑动RecyclerView的时候,位于右下角的FloatingActionButton自动隐藏和显示,我们可以自定义一个继承自FloatingActionButton.Behavior的类,如下所示:
public class ScrollAwareFABBehaviorDefault extends FloatingActionButton.Behavior {
public ScrollAwareFABBehaviorDefault(Context context, AttributeSet attrs) {
super();
}
@Override
public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
final View directTargetChild, final View target, final int nestedScrollAxes) {
// Ensure we react to vertical scrolling
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
|| super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
}
@Override
public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
final View target, final int dxConsumed, final int dyConsumed,
final int dxUnconsumed, final int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
// User scrolled down and the FAB is currently visible -> hide the FAB
child.hide();
} else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
// User scrolled up and the FAB is currently not visible -> show the FAB
child.show();
}
}
}
如下所示:
效果如下所示,当RecyclerView上下滑动的时候,FloatingActionButton自动显示和隐藏:
以上就是CoordinatorLayout的一个大致介绍,更加详尽的说明请参考Material Design设计规范:
https://material.google.com/
到此为止,关于Android Design Support Library的介绍就告一段落了!
参考:
https://android-developers.blogspot.com/2015/05/android-design-support-library.html
http://blog.csdn.net/xyz_lmn/article/details/48055919
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0407/4126.html