1.AppBarLayout 2.CoordinatorLayo
✨设置透明:
一:在Activity的布局的根标签中写入透明颜色:
android:background="#80000000"
二:在清单文件中相应的activity中配置:
android:theme="@android:style/Theme.Translucent.NoTitleBar"。
✨一个页面的布局关系:statusbar, actionbar, toolbar
1.AppBarLayout 2.CoordinatorLayout 3.CollapsingToolbarLayout
✨ 总结一下theme。
layout关系:
CoordinatorLayout
- AppBarLayout
- CollapsingToolbarLayout
- android.support.v7.widget.Toolbar
- NestedScrollView (来通知AppBarLayout 何时进行滚动)
- app:layout_behavior="@string/appbar_scrolling_view_behavior"
CoordinatorLayout:
它主要用于两个方面:
当做普通的FrameLayout作为根布局使用
作为一个或者多个子View进行复杂交互的容器。
AppbarLayout:
AppBarLayout 继承自LinearLayout,布局方向为垂直方向。所以你可以把它当成垂直布局的LinearLayout来使用。AppBarLayout是在LinearLayou上加了一些材料设计的概念,它可以让你定制当某个可滚动的兄弟View(如RecyclerView,NestedScrollView)的滚动手势发生变化时,其内部的子View实现何种动作。
AppBarLayout需要配合CoordinatorLayout进行使用,如果只是放到普通的ViewGroup中使用的话将无法实现它的效果。
我们可以通过给Appbar下的子View添加app:layout_scrollFlags来设置各子View执行的动作。
scroll:子View如果设置layout_scrollFlags属性的值为scroll,这个View会随着Scrolling View一起滚动,当向上滚动的时候,Toolbar会滚出屏幕外,如果不设置,那么Toolbar会固定不动。
- app:layout_behavior="@string/appbar_scrolling_view_behavior"
enterAlways:使用这个flag,当Scrolling View 向下滑动时,子View 将直接向下滑动,而不管Scrolling View 是否在滑动。注意:要与scroll 搭配使用,否则是不能滑动的。(上图演示的效果,正是scroll和enterAlways两个flag同时使用产生的效果,即向上滚动,Toolbar滚出屏幕,向下滚动,Toolbar重新进入屏幕)。
enterAlwaysCollapsed:enterAlwaysCollapsed 是对enterAlways 的补充,当Scrolling View 向下滑动的时候,滑动View(也就是设置了enterAlwaysCollapsed 的View)下滑至折叠的高度,当Scrolling View 到达滑动范围的结束值的时候,滑动View剩下的部分开始滑动。这个折叠的高度是通过View的minimum height (最小高度)指定的。(要配合scroll|enterAlways 一起使用)
Snap:在滚动结束后,如果view只是部分可见,它将滑动到最近的边界。比如,如果view的底部只有25%可见,它将滚动离开屏幕,而如果底部有75%可见,它将滚动到完全显示。
CollapsingToolbarLayout:是ToolBar的升级版,是一个容器,可以装ToolBar和其他的View。
一个FrameLayout,它内部能有多个子元素,而子元素也会有不同的表现。这些子元素可以添加layout_collapseMode标志位进而产生不同的行为。其实这里也只有两种标志位,分别是:
1、 pin:有该标志位的View在页面滚动的过程中会一直停留在顶部,比如Toolbar被固定在顶部
2、parallax:有该标志位的View表示能和页面同时滚动。
与该标志位相关联的一个属性是:layout_collapseParallaxMultiplier,该属性是视差因子,表示该View与页面的滚动速度存在差值,造成一种相对滚动的效果。
AppBarLayout.Behavior
而Behavior主要的使用方式其实是通过反射来实现的,我们在layout_behavior中并没有直接进行引用,而是写了包名+类名,所以Behavior是不能够被混淆的。
解释一下几个方法和它们的调用时机:
/**
* 表示是否给应用了Behavior 的View 指定一个依赖的布局,通常,当依赖的View 布局发生变化时
* 不管被被依赖View 的顺序怎样,被依赖的View也会重新布局
* @param parent
* @param child 绑定behavior 的View
* @param dependency 依赖的view
* @return 如果child 是依赖的指定的View 返回true,否则返回false
*/
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return super.layoutDependsOn(parent, child, dependency);
}
/**
* 当被依赖的View 状态(如:位置、大小)发生变化时,这个方法被调用
* @param parent
* @param child
* @param dependency
* @return
*/
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
return super.onDependentViewChanged(parent, child, dependency);
}
/**
* 当coordinatorLayout 的子View试图开始嵌套滑动的时候被调用。当返回值为true的时候表明
* coordinatorLayout 充当nested scroll parent 处理这次滑动,需要注意的是只有当返回值为true
* 的时候,Behavior 才能收到后面的一些nested scroll 事件回调(如:onNestedPreScroll、onNestedScroll等)
* 这个方法有个重要的参数nestedScrollAxes,表明处理的滑动的方向。
*
* @param coordinatorLayout 和Behavior 绑定的View的父CoordinatorLayout
* @param child 和Behavior 绑定的View
* @param directTargetChild
* @param target
* @param nestedScrollAxes 嵌套滑动 应用的滑动方向,看 {@link ViewCompat#SCROLL_AXIS_HORIZONTAL},
* {@link ViewCompat#SCROLL_AXIS_VERTICAL}
* @return
*/
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
}
/**
* 嵌套滚动发生之前被调用
* 在nested scroll child 消费掉自己的滚动距离之前,嵌套滚动每次被nested scroll child
* 更新都会调用onNestedPreScroll。注意有个重要的参数consumed,可以修改这个数组表示你消费
* 了多少距离。假设用户滑动了100px,child 做了90px 的位移,你需要把 consumed[1]的值改成90,
* 这样coordinatorLayout就能知道只处理剩下的10px的滚动。
* @param coordinatorLayout
* @param child
* @param target
* @param dx 用户水平方向的滚动距离
* @param dy 用户竖直方向的滚动距离
* @param consumed
*/
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
}
/**
* 进行嵌套滚动时被调用
* @param coordinatorLayout
* @param child
* @param target
* @param dxConsumed target 已经消费的x方向的距离
* @param dyConsumed target 已经消费的y方向的距离
* @param dxUnconsumed x 方向剩下的滚动距离
* @param dyUnconsumed y 方向剩下的滚动距离
*/
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
}
/**
* 嵌套滚动结束时被调用,这是一个清除滚动状态等的好时机。
* @param coordinatorLayout
* @param child
* @param target
*/
@Override
public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target) {
super.onStopNestedScroll(coordinatorLayout, child, target);
}
/**
* onStartNestedScroll返回true才会触发这个方法,接受滚动处理后回调,可以在这个
* 方法里做一些准备工作,如一些状态的重置等。
* @param coordinatorLayout
* @param child
* @param directTargetChild
* @param target
* @param nestedScrollAxes
*/
@Override
public void onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
super.onNestedScrollAccepted(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
}
/**
* 用户松开手指并且会发生惯性动作之前调用,参数提供了速度信息,可以根据这些速度信息
* 决定最终状态,比如滚动Header,是让Header处于展开状态还是折叠状态。返回true 表
* 示消费了fling.
*
* @param coordinatorLayout
* @param child
* @param target
* @param velocityX x 方向的速度
* @param velocityY y 方向的速度
* @return
*/
@Override
public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY) {
return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
}
//可以重写这个方法对子View 进行重新布局
@Override
public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
return super.onLayoutChild(parent, child, layoutDirection);
Google给我提供了一些特殊场景的Behavior
与AppbarLayout组合的滚动布局(RecyclerView, NestedScrollView等),需要设置 app:layout_behavior = "@string/appbar_scrolling_view_behavior" .没有设置的话, AppbarLayout将不会响应滚动布局的滚动事件.