CollapsingToolbarLayout的使用及折叠事件监听

时间:2021-07-10 05:26:35

CollapsingToolbarLayout给我么提供了一个可以折叠的toolbar。效果如下

CollapsingToolbarLayout的使用及折叠事件监听

它是design包里面的组件,使用前需要导入库依赖。compile 'com.android.support:design:25.3.1'

先看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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.appbarlayout.MainActivity">

<android.support.design.widget.AppBarLayout
android:id="@+id/barlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00000000">

<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collap"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="@color/colorPrimary"
app:title="效果"
app:layout_scrollFlags="snap|scroll|exitUntilCollapsed">

<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/bg2"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7"
/>

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />

</android.support.design.widget.CollapsingToolbarLayout>

</android.support.design.widget.AppBarLayout>

<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="文字"/>

</android.support.v4.widget.NestedScrollView>

<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"
android:layout_margin="5dp"
app:layout_anchor="@id/barlayout"
app:layout_anchorGravity="bottom|right"/>

</android.support.design.widget.CoordinatorLayout>

它是需要放入APPBarLayout中的,也就是同样通过滑动控件的behavior控制Bar的行为,属性体现在app:layout_scrollFlags,与滑动控件的app:layout_behavior上,如不理解参考这篇博客http://blog.csdn.net/lhp15575865420/article/details/76576809 

然后把图片(也可以是其他控件)跟toolbar放在CollapsingToolbarLayout 。实现折叠效果的核心就是app:layout_collapseMode这个属性,它有两个值,pin,这个属性,当CollapsingToolbarLayout完全收缩时,toolbar还能留在屏幕上 。parallax,内容滑动时,它可以同时滚动且有视差效果, 而layout_collapseparallaxMultipier这个属性就是配合使用的视差因子,取值0~1 。 还有一点,app:contentScrim设置折叠后的背景颜色,但是如果不设置,背景就是那张图片收缩后的样子。这里还用了一个design包的组件,FloatingActionButton,这个组件用法跟普通按钮区别不大,不过在这可以用来实现在展开时按钮出来,折叠时收进去。通过app:layout_anchor为它指定一个锚点,也就是把它放那个控件里面,然后app:layout_anchorGravity为它指定位置。布局文件写好后,运行起来效果就有了。

但是,如果想利用它实现下拉刷新,这个时候就得需要监听标题栏是折叠或者展开,还得能够主动设置展开或者折叠。下面是Java代码。

public class MainActivity extends AppCompatActivity {

public TextView textView;
public CollapsingToolbarLayout collap;
public AppBarLayout appBarLayout;
public FloatingActionButton fab;
public Toolbar toolbar;

//因为setExpanded会调用事件监听,所以通过标志过滤掉
public static int expendedtag=2;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

initview();
setview();
listen();

}

public void initview(){
textView= (TextView) findViewById(R.id.text);
collap= (CollapsingToolbarLayout) findViewById(R.id.collap);
appBarLayout= (AppBarLayout) findViewById(R.id.barlayout);
fab= (FloatingActionButton) findViewById(R.id.fab);
toolbar= (Toolbar) findViewById(R.id.toolbar);
}
public void setview(){
String s="一二三四五六七八九十";
for(int i=0;i<10;i++){
s=s+s;
}

textView.setText(s);
setSupportActionBar(toolbar);
appBarLayout.setExpanded(false);

}
public void listen(){
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//设置折叠或展开状态为折叠
//由于设置状态会调用一次监听事件,监听标志设为1
appBarLayout.setExpanded(false);
expendedtag=1;
}
});

appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
//verticalOffset是当前appbarLayout的高度与最开始appbarlayout高度的差,向上滑动的话是负数
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
//通过日志得出活动启动是两次,由于之前有setExpanded所以三次
Log.d("启动活动调用监听次数","几次");
if(getSupportActionBar().getHeight()-appBarLayout.getHeight()==verticalOffset){
//折叠监听
//Toast.makeText(MainActivity.this,"折叠了",Toast.LENGTH_SHORT).show();
}
if(expendedtag==2&&verticalOffset==0){
//展开监听
Toast.makeText(MainActivity.this,"展开了",Toast.LENGTH_SHORT).show();
}
if(expendedtag!=2&&verticalOffset==0){
expendedtag++;
}
}
});
}
}
事件监听和主动设置折叠展开APPBarLayout里的方法实现的。就是调用方法就行了代码有,不解释。但是要注意的偏移量改变的监听(折叠展开监听)它是在偏移量改变的时候调用,也就是下拉或者上滑的时候调用,静止不动不调用。但是要注意的是,setExpanded()的时候会调用,还有就是活动启动,加载布局的时候也会调用两次。所以,如果要在折叠或者展开监听里进行一些处理,要过滤掉这些,(上面过滤掉了setExpanded()方法引起的展开)。过滤的话像我一样设置标志就行了。