天天看點

CollapsingToolbarLayout的使用及折疊事件監聽

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()方法引起的展開)。過濾的話像我一樣設定标志就行了。