CollapsingToolbarLayout可折叠式标题栏

顾名思义,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;//修改状态标记为中间
                    }
                }
            }
        });

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值