前言:Coordinator单词意为协调者,CoordinatorLayout是Material Design中最重要也是最难的一个控件。这篇博客虽然名为CoordinatorLayout但其实是包括了另两个控件:AppBarLayout、CollapsingToolbarLayout,这两个控件也只有在CoordinatorLayout的协调下才能真正展现它们的强大之处。
一、CoordinatorLayout下的Snackbar
之前在Material Design Library系列之FloatingActionButton与Snackbar这篇博客中提到过当Snackbar在CoordinatorLayout布局下会有一个滑动移除的效果,这里就先通过这个简单的栗子来了解下CoordinatoLayout的使用。
接下来实现的效果是这样的:
Snackbar的移除是因为手势的向右滑动
1.新建工程并添加依赖:
compile 'com.android.support:design:24.0.0'
2.修改activity_main.xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.FloatingActionButton
android:id="@+id/id_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_dialog_email"
android:layout_gravity="end|bottom"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Snackbar Test!"
android:textSize="30sp"
android:gravity="center"/>
</android.support.design.widget.CoordinatorLayout>
这里将最外层的布局设为CoordinatorLayout,在该布局的右下角添加了FloatingActionButton,主界面只是放了个TextView。
3.修改MainActivity.java代码如下:
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.id_fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "点击了FAB", Snackbar.LENGTH_SHORT).show();
}
});
}
}
这里给FloatingActionButton添加了点击监听事件,点击后弹出一个Snackbar。
这里多说两句:CoordinatorLayout是从FrameLayout继承而来的,使用的时候与其他布局一样,它的布局方式是一层一层叠上去的。
源码地址:http://download.csdn.net/detail/chenhao0428/9557200
二、CoordinatorLayout下的AppBarLayout
AppBarLayout可以将它包裹的控件根据用户动作实现隐藏或重现,不仅仅限于toolbar。
AppBarLayout的使用步骤:
⑴用CoordinatorLayout包住AppBarLayout
⑵顶部区域的View都放在AppBarLayout里面
⑶在AppBarLayout的外面CoordinatorLayout的里面放置一个带有滚动的View
⑷在AppBarLayout里面的View,通过app:layout_scrollFlags属性来控制滚动时的表现
⑸在可以滚动的View上设置属性app:layout_behavior
app:layout_scrollFlags属性有四个可选值:
⑴scroll => 可滚动
⑵enterAlways => 向下移动时显示View
⑶exitUntilCollapsed => 向上滚动时收缩View
⑷enterAlwaysCollapsed => 当View已经设置minHeight属性又使用此标志时,View以最小高度进入
接下来实现的效果是这样的:
向下滑动RecyclerView,Toolbar会被隐藏;向上滑动RecyclerView,Toolbar恢复出现
1.新建工程并添加依赖:
compile 'com.android.support:design:24.0.0'
2.修改activity_main.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:layout_width="match_parent"
android:layout_height="match_parent">
<!-- AppBarLayout必须是第一个嵌套在CoordinatorLayout里的子view -->
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+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/id_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:layout_below="@id/id_toolbar"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
根据google的官方文档,AppBarLayout必须是第一个嵌套在CoordinatorLayout里的子View。
分析一下该布局:
CoordinatorLayout下包裹了AppBarLayout和RecyclerView,并将RecyclerView这个滚动View设置属性app:layout_behavior="@string/appbar_scrolling_view_behavior";
AppBarLayout下包裹了Toolbar,并将Toolbar设置属性app:layout_scrollFlags="scroll|enterAlways"。
3.为了更好地适配RecyclerView的数据,新增一个布局recycler_item.xml,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:background="#AABBCC">
<TextView
android:id="@+id/id_item_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:background="#CCBBAA"/>
</LinearLayout>
4.新建一个类MyRecyclerAdapter用来适配RecyclerView数据,代码如下:
class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.ViewHolder> {
private LayoutInflater mInflater;
private String[] mDatas = null;
public MyRecyclerAdapter(Context context) {
mInflater = LayoutInflater.from(context);
mDatas = new String[20];
for (int i=0; i<20; i++) {
int index = i + 1;
mDatas[i] = "item" + index;
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recycler_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemTv.setText(mDatas[position]);
}
@Override
public int getItemCount() {
return mDatas.length;
}
//自定义的ViewHolder,持有每个Item的所有界面元素
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView itemTv;
public ViewHolder(View view) {
super(view);
itemTv = (TextView) view.findViewById(R.id.id_item_tv);
}
}
}
5.修改MainActivity.java代码如下:
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Toolbar mToolbar;
private RecyclerView mRecyclerView;
private LinearLayoutManager mLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//toolbar部分
mToolbar = (Toolbar) findViewById(R.id.id_toolbar);
mToolbar.setTitle("标题栏");
//RecyclerView部分
mRecyclerView = (RecyclerView) findViewById(R.id.id_recycler);
//设置固定大小
mRecyclerView.setHasFixedSize(true);
//创建线性布局
mLayoutManager = new LinearLayoutManager(this);
//垂直方向
mLayoutManager.setOrientation(OrientationHelper.VERTICAL);
//给RecyclerView设置布局管理器
mRecyclerView.setLayoutManager(mLayoutManager);
//创建适配器
RecyclerView.Adapter adapter = new MyRecyclerAdapter(this);
mRecyclerView.setAdapter(adapter);
}
}
这段代码注释已经说得很清楚了,我就不再啰嗦了。
总结一下:AppBarLayout的使用主要在布局部分的协调,java代码只需实现自身原本的功能即可。
源码地址:http://download.csdn.net/detail/chenhao0428/9557207
三、CoordinatorLayout下的CollapsingToolbarLayout
CollapsingToolbarLayout继承自FrameLayout,用来折叠、拉伸其内的控件。
接下来实现的效果是这样的:
注:这里开始的代码是在第二部分的基础上进行修改。
1.修改actvity_main.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:layout_width="match_parent"
android:layout_height="match_parent">
<!-- AppBarLayout必须是第一个嵌套在CoordinatorLayout里的子view -->
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="180dp"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/id_collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="180dp"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/toolbar_background"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="@+id/id_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/id_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:layout_below="@id/id_toolbar"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
这里主要在AppBarLayout的里面Toolbar的外面添加了CollapsingToolbarLayout,并在其中添加了一个ImageView,当拉伸的时候展现的就是该图片。app:contentScrim表示当CollapsingToolbarLayout完全收缩时的背景颜色。
将ImageView的app:layout_collapseMode设置为parallax,表示当内容滚动时该View也可以同时滚动,实现视差滚动效果。
将Toolbar的app:layout_collapseMode设置为pin,表示当CollapsingToolbarLayout完全收缩后Toolbar还可以保留在屏幕上。
2.MainActivity.java代码基本不变,但有一点是要注意的,原本对Toolbar操作的部分应改为对CollapsingToolbarLayout操作。
mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.id_collapsing_toolbar);
mCollapsingToolbarLayout.setTitle("标题栏");
源码地址:http://download.csdn.net/detail/chenhao0428/9557486