Android-MaterialDesign-实现折叠式Tool

作者: MonkeyLei | 来源:发表于2019-07-21 16:49 被阅读1次

    小萌新做的几个项目没怎么涉及到一些这方面的UI设计,所以基本上就是看过,都没真正去试用过,好尴尬呀!就是琢磨要实现一个,下拉图片跟随拉动,然后按钮或者标题跟随变化消失,上拉置顶后标题显示置顶颜色,同时按钮显示的效果。

    如下类似效果:

    image image

    <figcaption style="margin-top: 0.66667em; padding: 0px 1em; font-size: 0.9em; line-height: 1.5; text-align: center; color: rgb(153, 153, 153);">上拉标题栏逐渐显示朋友圈,同时颜色加深</figcaption>

    然后开发交流群就很热心的啦...

    image

    然后就大概知道了AppBarLayout | Android DevelopersCollapsingToolbarLayout | Android DevelopersToolbar | Android Developers 。当然了解实践过程中发现还得配合CoordinatorLayout | Android Developers方可实现相关的效果。

    如果单纯的看官方文档东西还是多,而且像我发的这些链接都是相关方法,属性的介绍。api文档部分没什么demo啥的,比较少,之前学约束布局的时候倒是有的哟。 可能小萌新为了快速入手,就尽快的看相关网友的文章,github上的一些demo案例。

    这个官方文档也有很多例子示例 | Android Developers 都在github上面,不太会搜呀!哈哈。。。

    对MD了解各大概,对上面效果有个认识,就可以开始入手自己尝试一下。小萌新自然就从想控件入手,比如了解下Toolbar-v7兼容库中的,然后了解下CollapsingToolbarLayout -md库的可伸缩toolbar布局控件,从字面意思就大概知道,这是一个Toolbar用的外层控件,哟嘿!再然后AppBarLayout-把其所有子元素当做一个AppBar来使用。前面两个控件配合实现折叠toolbar,这个就负责布局就好了,保证作为一个整体,作为一个Appbar来使用!再接着还需要CoordinatorLayout - 它包含了AppBarLayout子控件和xx子控件,xx子控件可以是RecyclerView、NestedScrollView、ScrollView等可滑动控件,这样当我们上拉下拉这些控件的时候能和toolbar一起联动!

    小萌新一开始挺迷茫的,就是你知道某个控件后,发现不知道怎么用。看api其实也能看到一些层级关系:

    比如CollapsingToolbarLayout | Android Developers

    CollapsingToolbarLayout is a wrapper for Toolbar which implements a collapsing app bar. 
    It is designed to be used as a direct child of a AppBarLayout. 
    CollapsingToolbarLayout contains the following features:
    

    表达就是说CollapsingToolbarLayout是toolbar的一个容器,设计用于AppBarLayout的一个子控件。可能仔细琢磨下,貌似大概知道应该怎么用,哈哈。。 但是我觉得看看官方demo还是比较好,不然确实快速入手蛮困难的。

    小萌新我直接看的网友的分享,我觉得2016人家就用了,而且分析的还可以实现折叠式Toolbar:CollapsingToolbarLayout 使用完全解析 自己都有点惭愧!

    另外就是说如果要实现效果还得CoordinatorLayout | Android Developers 的辅助才行,这个东东涉及一个CoordinatorLayout.Behavior | Android Developers的概念,后面要专门学习下这块的知识。 因为之后你可能用CoordinatorLayout去搭配其他控件做其他效果,所以你需要去掌握这个控件以及相关layout_behavior的一些个概念 这里就抛砖引玉一下,至少有个大体的深入学习的框框先定下来。

    然后看下小萌新尝试的效果,针对网上的案例做了一些其他效果的实践

    image

    控制了下ImageView的缩放,位移,以及ImageView上的图片的缩放效果(就是setImageMatrix的简单使用- 注意前提是android:scaleType="matrix")。

    1. 实现关键点就是:AppBarLayout的addOnOffsetChangedListener的AppBarLayout.OnOffsetChangedListener回调,这个就是我们处理缩放、位移的地方了啦!注意点:而且像Image的位移,那个ImageView是需要放置到CoordinatorLayout之外,否则你位移的距离是会被布局限制的,就不能做全局位移了。

    1.1 另外一个注意点就是:你的界面的theme不能带标题了有,需要去掉哟!我一般都有一个这样的主题,所有的界面都会设置这个。

    image image

    1.2 其实如果你想先看效果,可以不用管addOnOffsetChangedListener回调的处理也行。那样标题栏和里面的Image也会跟随CoordinatorLayout上拉下拉产生对应的效果。不过我们想额外再控制点其他控件,以便产生更多的效果。

    1.3 关于Toolbar、CollapsingToolbarLayout的一些代码设置,我们可以通过官方api有所了解,如果吃不准的话,就可以参考网上的资料。

    像setTitle这些,还是比较好理解。只是小萌新不知道如何使用,只能尝试了吧?

    image

    再附上上图完成之前效果的一些代码设置:

            ///< 工具栏
            Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(mToolbar);
            getSupportActionBar().setDisplayHomeAsUpEnabled(false); ///< 左上角返回图标 - false不显示
            mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onBackPressed();  ///< 退出
                }
            });
    
            //使用CollapsingToolbarLayout必须把title设置到CollapsingToolbarLayout上,设置到Toolbar上则不会显示
            CollapsingToolbarLayout mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
            mCollapsingToolbarLayout.setTitle("哇咔咔");
            //通过CollapsingToolbarLayout修改字体颜色
            mCollapsingToolbarLayout.setExpandedTitleColor(Color.WHITE);//设置还没收缩时状态下字体颜色
            mCollapsingToolbarLayout.setCollapsedTitleTextColor(Color.BLACK);//设置收缩后Toolbar上字体的颜色
    

    2. 直接来布局 activity_collapsing_toolbar_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout 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.CollapsingToolbarLayoutActivity">
    
        <android.support.design.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <android.support.design.widget.AppBarLayout
                android:id="@+id/collapsing_appbar_layout"
                android:layout_width="match_parent"
                android:layout_height="256dp"
                android:fitsSystemWindows="true">
    
                <!--enterAlways  exitUntilCollapsed enterAlwaysCollapsed-->
                <!--app:contentScrim="#30469b" - 当Toolbar收缩到一定程度时的所展现的主体颜色-->
                <!--app:expandedTitleMarginStart - 展开时距离左边的距离-->
                <!--app:layout_scrollFlags="scroll"所有想要滑动的控件都要设置这个标志位-->
                <!--    layout_scrollFlags="exitUntilCollapsed" 向上滑动时收缩当前View。但view可以被固定在顶部-->
                <android.support.design.widget.CollapsingToolbarLayout
                    android:id="@+id/collapsing_toolbar_layout"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    app:contentScrim="#30469b"
                    app:expandedTitleMarginStart="148dp"
                    app:layout_scrollFlags="scroll|exitUntilCollapsed">
    
                    <ImageView
                        android:id="@+id/collapsing_toolbarIv"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:scaleType="matrix"
                        android:src="@drawable/timg2"
                        app:layout_collapseMode="parallax"
                        app:layout_collapseParallaxMultiplier="0.7" />
                    <!--pin parallax-->
                    <!--pin:有该标志位的View在页面滚动的过程中会一直停留在顶部-->
                    <!--parallax:有该标志位的View表示能和页面同时滚动-->
                    <android.support.v7.widget.Toolbar
                        android:id="@+id/toolbar"
                        android:layout_width="match_parent"
                        android:layout_height="?attr/actionBarSize"
                        android:background="@color/colorAccent"
                        app:layout_collapseMode="pin">
    
                        <ImageView
                            android:id="@+id/toolbar_rightIv"
                            android:layout_width="?attr/actionBarSize"
                            android:layout_height="?attr/actionBarSize"
                            android:layout_gravity="right"
                            android:src="@mipmap/ic_launcher" />
                    </android.support.v7.widget.Toolbar>
                </android.support.design.widget.CollapsingToolbarLayout>
            </android.support.design.widget.AppBarLayout>
    
            <android.support.v4.widget.NestedScrollView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">   <!--为滑动控件设置Behavior,这样上面的控件才能做出相应改变 -->
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="vertical">
    
                    <include layout="@layout/item_card" />
    
                    <include layout="@layout/item_card" />
    
                    <include layout="@layout/item_card" />
    
                    <include layout="@layout/item_card" />
    
                    <include layout="@layout/item_card" />
    
                    <include layout="@layout/item_card" />
    
                    <include layout="@layout/item_card" />
    
                    <include layout="@layout/item_card" />
    
                </LinearLayout>
            </android.support.v4.widget.NestedScrollView>
        </android.support.design.widget.CoordinatorLayout>
    
        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintTop_toTopOf="parent">
    
            <ImageView
                android:id="@+id/toolbar_right2Iv"
                android:layout_width="?attr/actionBarSize"
                android:layout_height="?attr/actionBarSize"
                android:layout_gravity="left"
                android:src="@mipmap/ic_launcher" />
        </android.support.constraint.ConstraintLayout>
    </android.support.constraint.ConstraintLayout>
    
    

    item_card.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="100dp">
    
        <View
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="10dp"
            android:background="@color/colorPrimary" />
    </LinearLayout>
    
    

    2.1 然后上代码吧CollapsingToolbarLayoutActivity.java

    package com.example;
    
    import android.graphics.Color;
    import android.support.design.widget.AppBarLayout;
    import android.support.design.widget.CollapsingToolbarLayout;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.support.v7.widget.Toolbar;
    import android.util.Log;
    import android.util.TypedValue;
    import android.view.View;
    import android.widget.ImageView;
    
    import com.example.hl.ViewTool;
    import com.example.lieyun_android.myapplication.R;
    
    public class CollapsingToolbarLayoutActivity extends AppCompatActivity {
        private ImageView rightIv, getRight2Iv, toolbarIv;
        private int initHeight;
        private int toolbarHeight;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_collapsing_toolbar_layout);
    
            rightIv = (ImageView) findViewById(R.id.toolbar_rightIv);
            getRight2Iv = (ImageView) findViewById(R.id.toolbar_right2Iv);
            toolbarIv = (ImageView) findViewById(R.id.collapsing_toolbarIv);
    
            rightIv.post(new Runnable() {
                @Override
                public void run() {
                    //int width = rightIv.getMeasuredWidth();
                    initHeight = rightIv.getMeasuredHeight();
                }
            });
    
            // Calculate ActionBar height
            TypedValue tv = new TypedValue();
            if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
                toolbarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
            }
    
            ///< AppBar高度
            AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.collapsing_appbar_layout);
            appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
                @Override
                public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                    Log.e("test",    "verticalOffset=" + verticalOffset);
                    ///< 左上角按钮做位移,注意为0的情况就间接的做消失处理
                    getRight2Iv.setTranslationY(-verticalOffset == 0.0f ? -200 : -verticalOffset);
    
                    ///< 偏移量超过了右上角按钮高度就返回,不允许反向放大,下面有个比例scale
                    if (-verticalOffset > initHeight){
                        return;
                    }
                    float scale = (-verticalOffset) / (float)initHeight;
                    Log.e("test",  "scale=" + scale);
                    rightIv.setScaleX(scale);
                    rightIv.setScaleY(scale);
    
                    float scaleR;
                    if (scale > 0.0f){
                        scaleR = (1.0f - scale);
                        Log.e("test",  "scale2=" + scaleR);
                        if (scaleR < 0.5f){
                            return;
                        }
                    }else{
                        scaleR = 1.0f - scale;
                    }
                    //toolbarIv.setScaleX(scaleR);
                    //toolbarIv.setScaleY(scaleR);
                    ///< 负责处理ImageView的drawable的缩放效果,需要Matrix哟。。这个有时间要深入。
                    ViewTool.scaleImageViewDrawable(toolbarIv, scaleR);
                }
            });
    
            ///< 工具栏
            Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(mToolbar);
            getSupportActionBar().setDisplayHomeAsUpEnabled(false); ///< 左上角返回图标 false - 不显示
            mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onBackPressed();
                }
            });
    
            //使用CollapsingToolbarLayout必须把title设置到CollapsingToolbarLayout上,设置到Toolbar上则不会显示
            CollapsingToolbarLayout mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
            mCollapsingToolbarLayout.setTitle("哇咔咔");
            //通过CollapsingToolbarLayout修改字体颜色
            mCollapsingToolbarLayout.setExpandedTitleColor(Color.WHITE);//设置还没收缩时状态下字体颜色
            mCollapsingToolbarLayout.setCollapsedTitleTextColor(Color.BLACK);//设置收缩后Toolbar上字体的颜色
        }
    }
    
    

    工具类 ViewTool.java

       package com.example.hl;
    
    import android.graphics.Matrix;
    import android.graphics.drawable.Drawable;
    import android.util.Log;
    import android.widget.ImageView;
    
    /**
     * Created by hl on 2018/3/20.
     */
    
    public class ViewTool {
        public static void scaleImageViewDrawable(ImageView imageView, float scale){
            Drawable drawable = imageView.getDrawable();
            if (null == drawable){
                return;
            }
    
            int imageWidth = drawable.getIntrinsicWidth();// 图片的宽度
            int imageHeight = drawable.getIntrinsicHeight();// 图片的高度
    
            int width = imageView.getWidth();// 控件的宽度
            int height = imageView.getHeight();// 控件的高度
    
            int dx = width / 2 - imageWidth / 2;
            int dy = height / 2 - imageHeight / 2;
    
            Matrix mScaleMatrix = new Matrix();
            mScaleMatrix.postTranslate(dx, dy);
            Log.e("test", "postScale=" + scale);
            mScaleMatrix.postScale(scale*2.5f/3, scale*2.5f/3, width / 2, height / 2);
            imageView.setImageMatrix(mScaleMatrix);
        }
    }
    
    

    基本就ok了。。缺的图片补补就好了。时间有点赶。具体效果还可以调。而且要想搞得更好,肯定还是需要再深入一些其他知识的(什么behavior啥的,其他md的控件啥的....),这篇就算是初识。。小萌新要接触,学习,实践的东西还好多呀。。我的天。。。

    相关文章

      网友评论

        本文标题:Android-MaterialDesign-实现折叠式Tool

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