Android知识进阶(遥远的重头开始)优秀案例Android控件

Android-MaterialDesign-实现折叠式Tool

2019-07-21  本文已影响1人  MonkeyLei

小萌新做的几个项目没怎么涉及到一些这方面的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的控件啥的....),这篇就算是初识。。小萌新要接触,学习,实践的东西还好多呀。。我的天。。。

上一篇下一篇

猜你喜欢

热点阅读