一、AppBarLayout
AppBarLayout是继承自LinearLayout,默认是垂直方向,可以看成是一个垂直方向的线性布局,其作用是将APPBarLayout包裹的内容都作为AppBar,支持手势滑动。
AppBarLayout必须作为Toolbar的父布局容器,换句话就是说,使用AppBarLayout布局时,需要包裹Toolbar布局。
支持手势滑动时,需要和CoordinatorLayout配合使用。
CoordinatorLayout是一个为子视图之间相互协调手势效果的协调布局, 在不指定视图位置时,和FrameLayout一样,所有视图都位于在左上角。一般都是和AppBarLayout 、CollapsingToolbarLayout配合使用。
CollapsingToolbarLayout一般作为AppBarLayout的子视图使用,当其包裹Toolbar时,提供了一个可以折叠的Toolbar,需要有折叠效果的组件还需设置 layout_collapseMode属性。是继承自FrameLayout布局,如果包裹的视图不指定位置,会和FrameLayout一样位于在左上角。
使用上面这些布局,都要导入Material Design依赖包,我使用的是Android Studio 3.0版本,导入包
implementation 'com.android.support:design:28.0.0-alpha1'
(1)自定义一个Toolbar布局toolbar_layout.xml
(2)activity_app_bar_layout.xml
(3)RecyclerView的适配器
public class RVMyAdapter extends RecyclerView.Adapter
{ private Context context; private List list; public RVMyAdapter(Context context, List list) { this.context = context; this.list = list; } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { TextView textView=new TextView(context); return new RecyclerView.ViewHolder(textView) {}; } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { ((TextView)viewHolder.itemView).setText(list.get(i)); } @Override public int getItemCount() { return list.size(); } }
(4)AppBarLayoutActivity.java
public class AppBarLayoutActivity extends Activity { private Toolbar toolbar; private RecyclerView recyclerView; private List
list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sapp_bar_layout); //设置toolbart替代ActionBar toolbar=findViewById(R.id.toolbar); setSupportActionBar(toolbar); //设置recyclerView填充数据 recyclerView=findViewById(R.id.recyclerView); list=new ArrayList<>(); for (int i = 0; i < 1000; i++) { list.add(String.format(Locale.CHINA,"第%03d条数据",i)); } recyclerView.setAdapter(new RVMyAdapter(this,list)); } }
(5)运行界面
(6)效果实现说明:
为了使Toolbar可以手势滑动,首先,给Toolbar设置app:layout_scrollFlags="scroll | enterAlways"属性。其次,CoordinatorLayout布局下必须包裹一个可以滑动的布局,比如,可以是RecyclerView(经测试,ListView、ScrollView不支持) , 并且给这滑动组件设置属性app:layout_behavior="@string/appbar_scrolling_view_behavior"来告诉CoordinatorLayout,该组件是带有滑动行为的组件,然后CoordinatorLayout在接收到滑动时会通知AppBarLayout 中可滑动的Toolbar可以滑出屏幕了。
给想要实现手势滑动的组件设置的layout_scrollFlags属性有如下几种选项:
scroll: 所有想滚动出屏幕的view都需要设置这个值,没有设置这个值的view将被固定在屏幕顶部。enterAlways: 任意向下的滚动都会导致该view变为可见,启用快速“返回模式”。 enterAlwaysCollapsed: 当滚动视图到达顶部时view才扩大到完整高度。exitUntilCollapsed: 滚动退出屏幕,最后折叠在顶端。
(7)总结
为了使Toolbar有手势滑动的效果,必须做到下面几点:
1、CoordinatorLayout作为整个布局的父布局容器
2、Toolbar的父布局容器须为AppBarLayout,给Toolbar设置属性
app:layout_scrollFlags=" ",值为scroll|enterAlways表示滚动出屏幕|任意向下滑动就可见,值为scroll|enterAlwaysCollapsed表示滚动出屏幕|向下滑动顶端出现才可见
3、CoordinatorLayout需包裹一个滑动组件,比如RecyclerView,并给滑动组件设置属性:
app:layout_behavior="@string/appbar_scrolling_view_behavior"
(8)扩展一下,稍稍修改下activity_app_bar_layout.xml布局,在AppBarLayout中增加一个ImageView控件,其他地方不变
界面如下图所示,运行中我们可以发现,这种情况下,即使Toolbar设置了属性app:layout_scrollFlags="scroll | enterAlways",RecyclerView在滑动过程中Toolbar也没有出现滑动。如果将app:layout_scrollFlags="scroll | enterAlways"属性设置给AppBarLayout,Toolbar仍然没有滑动。如果将app:layout_scrollFlags="scroll | enterAlways"属性设置给刚添加的ImageView,ImageView却出现了滑动,向上滑动时Toolbar会固定在顶部位置。如果这种情况想要实现Toolbar也可滑动,怎么办?这个问题将会在下面给出解决。
(1)CollapsingToolbarLayout的常用属性
app:contentScrim="@color/colorAccent" //设置被折叠到顶部固定时候的背景
app:layout_scrollFlags="scroll | exitUntilCollapsed" //设置滑动标志 scroll: 所有想滚动出屏幕的view都需要设置这个值,exitUntilCollapsed: 滚动退出屏幕,最后折叠在顶端。
app:layout_collapseParallaxMultiplier="0.2" //设置CollapsingToolbarLayout滑动时其子视图的视觉差
app:layout_collapseMode="parallax" // 设置子视图的折叠模式 “pin”:固定模式,在折叠的时候最后固定在顶端;“parallax”:视差模式,在折叠的时候会有个视差折叠的效果。
(2)自定义的toolbar_layout布局、代码文件、RecyclerView适配器文件与上面的一样,这里就不重复贴了,这里只贴一下布局文件。
(3)布局文件
(5)运行界面
(6)注意:Toolbar的高度layout_height必须固定,不能是“wrap_content”,否则Toolbar不会滑动,也不会折叠。
(7)扩展:如果将CollapsingToolbarLayout的属性app:layout_scrollFlags=""设置为scroll | enterAlways,就会实现可滑动的ImageView+Toolbar,这刚好可以解决四(7)中的问题。
说了这么多,具体还是要自己动手去实练一遍才有感觉。