MaterialDesign系列文章(七)AppbarLayout的使用

3,606 阅读7分钟

大家好我是笔墨Android,曾经的我总是迷茫的,不知道怎么学习才是最好的!但是最近我听到我对一句话,对我特别又感触 做好现在能做的,你会慢慢的发现你在改变! 谁都有改变自己的权力,就看你是否想要去改变!其实我们每天只要做一点点的改变,会从量到质改变!今天说的有些寒酸了,但是自从我开始认真的写博客,我发现我的生活正慢慢改变着!

此图片来源于网络

今天聊点什么呢?上篇文章讲到了MaterialDesign系列文章(六)CoordinatorLayout的一些联动,其中提到了很多关于MaterialDesign的控件,但是只是一笔带过了,没有具体的分析,为了让小伙伴们能更好的理解!所以我觉得有必要单独讲讲每一控件!今天就先从AppBarLayout开始吧!

本文知识点:

  • AppBarLayout是什么?能用来干什么?
  • AppBarLayout的一些使用案例。

1.AppBarLayout是什么?能用来干什么?

AppBarLayout is a vertical LinearLayout which implements many of the features of material designs app bar concept, namely scrolling gestures.Children should provide their desired scrolling behavior through setScrollFlags(int) and the associated layout xml attribute: app:layout_scrollFlags.This view depends heavily on being used as a direct child within a CoordinatorLayout. If you use AppBarLayout within a different ViewGroup, most of it's functionality will not work.

我用人话翻译一下啊!AppBarLayout继承LinearLayout,可以响应用户的手势操作,但是必须在CoordinatorLayout下使用,否则会有许多功能使用不了。

其实说到AppBarLayout你能想到什么?其实最开始我想到也只有联动,没有别的,但是关于AppBarLayout的联动你真的知道吗?相信看了上一篇文章的人都会觉得,AppBarLayout总是和TabLayout,CollapsingToolbarLayout联动。其实AppBarLayout的用处远远不止这些?还有的就是套路。。。

2. AppBarLayout的使用!

相信看了上一篇文章的小伙伴都知道了AppBarLayout怎么和CoordinatorLayout、CollapsingToolbarLayout、TabLayout联动,往往AppBarLayout的出现频率和CoordinatorLayout、CollapsingToolbarLayout、TabLayout时一样的,也就是说基本上讲的都是它们怎么联动!但是其实Toolbar不是非要和他们连用的。它可以自己和自己玩。。。而且玩的还很开心!当你无聊的时候你可以拿他当竖直的LinearLayout使用,心情好了你可以和CoordinatorLayout、TabLayout一起用。像我这种既无聊又心情好的时候我就自己玩。哈哈,扯远了。让我们看看它是怎么自(。・∀・)ノ゙嗨的吧!先来一张效果图...

录得不好多见谅

其实你仔细看看这个效果是不是很常见的吸顶效果!这种效果在电商的首页比较多见。其实也是很好实现的,这里简单拿布局说一下吧!

<?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.jinlong.newmaterialdesign.material.AppBarLayoutActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="#e79349"
            android:gravity="center"
            android:scaleType="center"
            android:text="这里可以放ViewPager"
            android:textColor="@android:color/white"
            android:textSize="20sp"
            app:layout_scrollFlags="scroll" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_tab"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:overScrollMode="never"
            android:scrollbars="none"
            app:layout_scrollFlags="scroll" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="#009988"
            android:gravity="center"
            android:text="这里时需要吸顶的效果内容,可以是任何内容的"
            android:textColor="@android:color/white" />

    </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">


        <LinearLayout
            android:id="@+id/ll_bottom"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="500dp"
                android:gravity="center"
                android:text="底部还有内容啊!!!" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#009988"
                android:gravity="center"
                android:text="标签1" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#002288"
                android:gravity="center"
                android:text="标签2" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#009922"
                android:gravity="center"
                android:text="标签3" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#00aa88"
                android:gravity="center"
                android:text="标签4" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#999988"
                android:gravity="center"
                android:text="标签5" />
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

这个内容主要是依托于app:layout_scrollFlags="scroll"来实现一些你想要的效果,你可以设置不同的布局,来得到你想要的内容!

重点来了!!! AppBarLayout的监听,之前在文章中讲到AppBarLayout和CoordinatorLayout、CollapsingToolbarLayout、TabLayout联动的问题,今天测试来了提出一个问题,说联动的时候标题的文字,说联动时候的那个动画太难看,做简单一点,直接渐变的显示多好!

然后我就默默的掏出了手机,打开付款吗,来你先扫一下咱俩在继续说!!!结果人家真的扫了,不过给我我一分钱。。。当时我是崩溃的,但是话都说出去了。别鼓掌,要脸。。。接下来就有下面的内容了!其实AppBarLayouot是有关于这个监听的,没有的话我也不会这么就答应了,小哥哥是不打没有准备的仗的!哈哈。。。

        AppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                //偏移量的计算
            }
        });

这个监听,给我们返回了响应的滑动变化量,我们可以根据总高度,然后根据变化量算出一个比例,就可以很好的计算出应该设置的透明度了!其实有了这个偏移量加个什么动画也是可以的嘛!请大家冥想一分钟,看看有没有思路。马上给出答案。。。。先来张图走一波!

这个效果进攻娱乐,只是设置了TextView的旋转属性从而进行计算,只是给大家带来个思路,所以别局限于我讲的内容,要融汇贯通!

        AppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

                //这个是计算App bar Layout的总高度的API
                int totalScrollRange = appBarLayout.getTotalScrollRange();

                float ratio = Math.abs((float) verticalOffset / totalScrollRange);

                mTvTitle.setRotation(ratio * 360);
            }
        });

图片效果仅供娱乐

这里有一点要说明一下,就是有关于滑动方向的,向上滑动为负值。向下滑动为正值。所以这里使用的是绝对值进行计算的。还有一点就是刚开始进来的时候会走一次回调,计算出来的结果是0,所以设置透明度的时候,应该注意这里。因为总体的比值不会大于1,所以刚开始的时候你要是想看见它的,设置透明度的取反就可以了也就是 (1-比值) 就可以了!代码是这样的!

        mAbl.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

                //这个是计算App bar Layout的总高度的API
                int totalScrollRange = appBarLayout.getTotalScrollRange();

                float ratio = Math.abs((float) verticalOffset / totalScrollRange);

                mTvTitle.setAlpha(1 - ratio);

                Log.e(TAG, "onOffsetChanged: " + ratio + "---" + verticalOffset);
            }
        });

就不上图了,具体看你们的需求了。我们当时的需求就是,Toolbar在上面,全部折叠的时候才显示出来。要是处于打开状态的话就不现实!和这个大同小异,只要你算好比值就可以了!在给你们点福利!

public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener {
 
    public enum State {
        EXPANDED,
        COLLAPSED,
        IDLE
    }
 
    private State mCurrentState = State.IDLE;
 
    @Override
    public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {
        if (i == 0) {
            if (mCurrentState != State.EXPANDED) {
                onStateChanged(appBarLayout, State.EXPANDED);
            }
            mCurrentState = State.EXPANDED;
        } else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
            if (mCurrentState != State.COLLAPSED) {
                onStateChanged(appBarLayout, State.COLLAPSED);
            }
            mCurrentState = State.COLLAPSED;
        } else {
            if (mCurrentState != State.IDLE) {
                onStateChanged(appBarLayout, State.IDLE);
            }
            mCurrentState = State.IDLE;
        }
    }
 
    public abstract void onStateChanged(AppBarLayout appBarLayout, State state);
}

    mAppBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
            @Override
            public void onStateChanged(AppBarLayout appBarLayout, State state) {
                Log.d("STATE", state.name());
                if( state == State.EXPANDED ) {
                    
                    //展开状态
                    
                }else if(state == State.COLLAPSED){
                    
                    //折叠状态
                     
                }else {
                
                    //中间状态
                
                }
            }
        });

这个是判断AppBarLayout展开于折叠状态的。怎么用我就不说了!今天的分享就到这里吧!内容不多,希望大家过一个愉快的周末!!!作为程序员的我们周末多出去溜达一下,找找妹子,单身狗的世界是没有色彩的。。。


说两句题外话,我觉得学习这个东西,应该有自己的体系。其实我也总在想,怎么写文章你们才能记住,包括我自己也是,有的时候用的话也要回来看看博客才能想起一些内容的用法。最近有小伙伴说文章太多了,看不完。其实我也在想,怎么才能最简单的把这些内容介绍给大家!简短的怕你不理解,太长的怕你看不完...希望小伙盘们提出你们的想法,我会及时改进的!!!