美文网首页Material Design
修改CollapsingToolbarLayout折叠时候的阴影

修改CollapsingToolbarLayout折叠时候的阴影

作者: 斯特的简书 | 来源:发表于2018-11-08 16:53 被阅读89次

    CollapsingToolbarLayout处于折叠状态(Collapsed)状态时,所含Toolbar下方默认会出现阴影,该阴影并非内部Toolbar的阴影,而是外部AppLayout的阴影,所以要修改这个阴影就需要处理AppBarLayout。5.0以下的系统可以通过设置app:elevetion来产生阴影,5.0以上系统则没有效果,设了该属性反而所有阴影都会消失。

    查看AppBarLayout源码,发现getTargetElevation()方法已经废弃了,永远返回0,setTargetElevation()也废弃了,看一下说明和所留下的保底实现:

         * @deprecated target elevation is now deprecated. AppBarLayout's elevation is now
         * controlled via a {@link android.animation.StateListAnimator}. If a target
         * elevation is set, either by this method or the {@code app:elevation} attribute,
         * a new state list animator is created which uses the given {@code elevation} value.
         *
         * @attr ref android.support.design.R.styleable#AppBarLayout_elevation
         */
        @Deprecated
        public void setTargetElevation(float elevation) {
            if (Build.VERSION.SDK_INT >= 21) {
                ViewUtilsLollipop.setDefaultAppBarLayoutStateListAnimator(this, elevation);
            }
        }
    

    也就是说现在Elevation这个属性需要通过StateListAnimator的方式来设置。下面的保底方法点进去看一下:

        /**
         * Creates and sets a {@link StateListAnimator} with a custom elevation value
         */
        static void setDefaultAppBarLayoutStateListAnimator(final View view, final float elevation) {
            final int dur = view.getResources().getInteger(R.integer.app_bar_elevation_anim_duration);
    
            final StateListAnimator sla = new StateListAnimator();
            // 可用并且可折叠但未折叠(展开)状态下去掉阴影
            // Enabled and collapsible, but not collapsed means not elevated
            sla.addState(new int[]{android.R.attr.enabled, R.attr.state_collapsible,
                            -R.attr.state_collapsed},
                    ObjectAnimator.ofFloat(view, "elevation", 0f).setDuration(dur));
            // 可用状态下加上阴影
            // Default enabled state
            sla.addState(new int[]{android.R.attr.enabled},
                    ObjectAnimator.ofFloat(view, "elevation", elevation).setDuration(dur));
            // 其他状态下去掉阴影
            // Disabled state
            sla.addState(new int[0],
                    ObjectAnimator.ofFloat(view, "elevation", 0).setDuration(0));
    
            view.setStateListAnimator(sla);
        }
    

    我们可以模仿这里的方式,通过5.0后推荐的ObjectAnimator方式添加阴影,如果要在xml中设置的话,就需要新建一个Drawable资源(这里名叫appbar_elevation.xml):

    <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
        <!--折叠状态下的阴影-->
        <item app:state_collapsed="true">
            <objectAnimator 
                android:propertyName="elevation" 
                android:valueTo="5dp" 
                android:valueType="floatType" />
        </item>
        <!--展开状态下的阴影-->
        <item app:state_collapsed="false">
            <objectAnimator 
                android:propertyName="elevation" 
                android:valueTo="0dp" 
                android:valueType="floatType" />
        </item>
    </selector>
    

    然后为AppBarLayout设置stateListAnimator属性:

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="120dp"
            android:background="#FFFFFFFF"
            android:stateListAnimator="@drawable/appbar_elevation">
    

    这样就可以了。

    相关文章

      网友评论

        本文标题:修改CollapsingToolbarLayout折叠时候的阴影

        本文链接:https://www.haomeiwen.com/subject/xivwxqtx.html