CollapsingToolbarLayout可折叠式标题栏

来源:互联网 发布:淘宝网上托福答案 编辑:程序博客网 时间:2024/04/30 11:45

顾名思义,CollapsingToolbarlayout是一个作用于Toolbar基础之上的布局,它可以让Toolbar的效果变得更加丰富,不仅仅是展示一个标题栏,而是能够实现非常华丽的效果。
不过,CollapsingToolbarlayout是不能独立存在的,它的设计时被限定只能作为APPBarLayout的直接子布局来使用。而AppBarLayout又必须是CoordinatorLayout的子布局。
效果图如下:

Android studio中有一个Activity模板叫ScrollingActivity,它实现的就是简单的可折叠工具栏,我们将此模板添加到项目中。

然后在布局文件的CollapsingToolbarLayout中定义标题栏的具体内容,

<android.support.design.widget.CollapsingToolbarLayout            android:id="@+id/toolbar_layout"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:fitsSystemWindows="true"            app:contentScrim="?attr/colorPrimary"            app:layout_scrollFlags="scroll|exitUntilCollapsed">            <ImageView                android:id="@+id/image_view"                android:scaleType="centerCrop"                android:src="@drawable/toolbarimage"                app:layout_collapseMode="parallax"                android:fitsSystemWindows="true"                android:layout_width="match_parent"                android:layout_height="match_parent" />            <android.support.v7.widget.Toolbar                android:id="@+id/toolbar"                android:layout_width="match_parent"                android:layout_height="?attr/actionBarSize"                app:layout_collapseMode="pin"                app:popupTheme="@style/AppTheme.PopupOverlay">            </android.support.v7.widget.Toolbar>        </android.support.design.widget.CollapsingToolbarLayout>

AppBarLayout是一种支持响应滚动手势的app bar布局(比如工具栏滚出或滚入屏幕),CollapsingToolbarLayout则是专门用来实现子布局内不同元素响应滚动细节的布局。CollapsingToolbarLayout和ScrollView一起使用会有滑动bug,注意要使用NestedScrollView来替代ScrollView。

接下来写功能逻辑:

  1. 添加回退键

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_item_scrolling);        ButterKnife.inject(this);        setSupportActionBar(toolbar);        //启用HomeAsUp按钮,也就是回退键        ActionBar actionBar = getSupportActionBar();        if (actionBar != null) {            actionBar.setDisplayHomeAsUpEnabled(true);        }    }    ...        //处理HomeAsUp回退按钮的点击事件    @Override    public boolean onOptionsItemSelected(MenuItem item) {        switch (item.getItemId()) {            case android.R.id.home:                finish();                return true;        }        return super.onOptionsItemSelected(item);    }

2.状态栏透明,充分利用系统状态栏控件

Android5.0之后系统支持对状态栏的背景或颜色进行操作,因此来实现一个系统差异型的效果,使用背景和状态栏融合的模式,在之前的系统中使用普通的模式。
想要状态栏透明,需要借助fitsSystemWindows这个属性来实现。必须将ImageView布局以及其所有福布局都给fitsSystemWindows设置为true。

在values-21目录中创建一个styles.xml文件。代码如下:

<resources>    <style name="ItemShowActivityTheme" parent="AppTheme">        <item name="windowActionBar">false</item>        <item name="windowNoTitle">true</item>        <item name="android:windowDrawsSystemBarBackgrounds">true</item>        <item name="android:statusBarColor">@android:color/transparent</item>    </style></resources>

然后让Activity使用这个主题,修改AndroidManifest.xml中的代码,如下所示:

<activity    android:name=".ItemScrollingActivity"    android:label="@string/title_activity_item_scrolling"    android:theme="@style/ItemShowActivityTheme"></activity>

但是5.0之前的系统却无法识别该主题,因此需要对values/styles.xml文件进行修改,如下:

<style name="ItemShowActivityTheme" parent="AppTheme"></style>

3.状态栏渐变的不透明层

为了避免视频封面图片颜色过浅影响状态栏信息的显示,还可以加一个渐变的不透明层。实现渐变遮罩层很简单。先在res/drawable文件夹下新建了一个名为gradient的xml文件,其中代码如下:

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <gradient        android:startColor="#33000000"        android:endColor="#00000000"        android:angle="270" /></shape>

shape节点中,可以通过android:shape来设置形状,默认是矩形。gradient节点中angle的值270是从上到下,0是从左到右,90是从下到上。起始颜色#33000000是20%不透明度的黑色,#00000000表示全透明。

然后在CollapsingToolbarLayout里的ImageView代码下面加上一个自定义view,背景设置为上面的渐变效果。

<View   android:layout_width="match_parent"   android:layout_height="40dp"   android:background="@drawable/gradient"   android:fitsSystemWindows="true"/>

4.监听CollapsingToolbarLayout的折叠、展开状态。

可以通过调用AppBarLayout的addOnOffsetChangedListener方法监听AppBarLayout的位移,判断CollapsingToolbarLayout的状态。
布局文件代码:

<android.support.v7.widget.Toolbar                android:id="@+id/toolbar"                android:layout_width="match_parent"                android:layout_height="?attr/actionBarSize"                app:layout_collapseMode="pin"                app:popupTheme="@style/AppTheme.PopupOverlay">                <!--自定义带图片的立即播放按钮-->                <android.support.v7.widget.ButtonBarLayout                    android:id="@+id/playButton"                    android:layout_width="match_parent"                    android:layout_height="match_parent"                    android:layout_marginLeft="60dp"                    android:visibility="gone">                    <ImageView                        android:layout_width="wrap_content"                        android:layout_height="match_parent"                        android:layout_gravity="center_horizontal"                        android:src="@drawable/ic_media_embed_play"/>                    <TextView                        android:layout_width="wrap_content"                        android:layout_height="wrap_content"                        android:textColor="#ffffff"                        android:text="立即播放"                        android:layout_gravity="center_vertical"                        />                </android.support.v7.widget.ButtonBarLayout>            </android.support.v7.widget.Toolbar>

逻辑代码如下:

先写一个枚举定义出CollapsingToolbarLayout展开、折叠、中间,这三种状态。

private CollapsingToolbarLayoutState state; private enum CollapsingToolbarLayoutState {    EXPANDED,    COLLAPSED,    INTERNEDIATE}

接下来对AppBarLayout进行监听,判断CollapsingToolbarLayout的状态并实现相应的逻辑。

使用CollapsingToolbarLayout的时候要注意,在完成CollapsingToolbarLayout设置之后再调用Toolbar的setTitle()等方法将没有效果,我们需要改为调用CollapsingToolbarLayout的setTitle()等方法来对工具栏进行修改。

appBar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {            @Override            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {                if (verticalOffset == 0) {                    //展开状态                    if (state != CollapsingToolbarLayoutState.EXPANDED) {                        state = CollapsingToolbarLayoutState.EXPANDED;//修改状态标记为展开                        toolbarLayout.setTitle(movieName);//设置title为EXPANDED                    }                    //折叠的监听                } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) {                    if (state != CollapsingToolbarLayoutState.COLLAPSED) {                        playButton.setVisibility(View.VISIBLE);//显示播放按钮                        toolbarLayout.setTitle("");//设置title不显示                        state = CollapsingToolbarLayoutState.COLLAPSED;//修改状态标记为折叠                    }                } else {                    //展开的监听                    if (state != CollapsingToolbarLayoutState.INTERNEDIATE) {                        if (state == CollapsingToolbarLayoutState.COLLAPSED) {                            playButton.setVisibility(View.GONE);//由折叠变为中间状态时隐藏播放按钮                        }                        toolbarLayout.setTitle(movieName);//设置title为INTERNEDIATE                        state = CollapsingToolbarLayoutState.INTERNEDIATE;//修改状态标记为中间                    }                }            }        });

然后对播放按钮设置监听。

原创粉丝点击