模仿手机淘宝 标题效果 android

前阵子,有个朋友让我看手机淘宝app 我的淘宝,我的淘宝,那个可以滑动用户名。他们公司要用,他要做ios的可是我看到这个效果第一反应是,这不就是,android5.0的一个控件吗?没错就是coordinatorlayout behavior 各种头部动画,都可以他写,关于,hehavior的帖子很多了。我就不在这里介绍了,大家可以随意百度看解释。
我们先看,最终效果图。有图有真相。

虽然有水印,我已经尽力了

是不是,有点像,我必须说明,我是在源文件基础上修改来的,这贴出来,原作者的git下载地址 :githup(虽然这个大牛也一定不会理我,但是做人要有道德)
其实如果你去他的githup看了。你就会发现我做的工作其实并不对,没事,真心不多,我就添加了一个toolbar,修来原有代码不超过五行。是不是感觉有了互联网,我这种渣渣也能变成了。过程不重要,思路很重要。下来我们来看看具体我都修改了那些地方。

<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:ignore="RtlHardcoded">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/main.appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/main.collapsing"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <ImageView
                android:id="@+id/main.imageview.placeholder"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:src="@drawable/quila2"
                android:tint="#11000000"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.9"

                />
//其实这个framelayout 已经没有什么用了。他的作用就是,一个高度展位,懒了一下,没有调整。哈哈哈。
            <FrameLayout
                android:id="@+id/main.framelayout.title"
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:layout_gravity="bottom|center_horizontal"
                android:background="@color/primary"
                android:orientation="vertical"
                android:visibility="invisible"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.3">


            </FrameLayout>
//我添加的一个toolbar 其实就是再贴,修改了一下
            <android.support.v7.widget.Toolbar
                android:id="@+id/tools"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@color/cardview_light_background"
                app:contentInsetLeft="0dp"
                app:contentInsetStart="0dp"
                app:layout_collapseMode="pin">

                <LinearLayout
                    android:id="@+id/main.textview.title"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@color/cardview_light_background"
                    android:gravity="center"
                    android:orientation="vertical">
//这里修改的是一个高度,就是这是这里,,,设置最终的高度,
                    <de.hdodenhof.circleimageview.CircleImageView
                        android:layout_width="@dimen/image_final_width"
                        android:layout_height="@dimen/image_final_width"
                        android:layout_gravity="center_horizontal"
                        android:src="@drawable/quila"
                        app:border_color="@android:color/holo_green_dark"
                        app:border_width="2dp"

                        />

                </LinearLayout>
            </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"
        android:scrollbars="none"
        app:behavior_overlapTop="30dp"
        android:background="@color/cardview_light_background"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"

        >

        <android.support.v7.widget.CardView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            app:cardElevation="8dp"
            app:contentPadding="16dp">

            <TextView
                android:id="@+id/textView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:lineSpacingExtra="8dp"
                android:text="@string/lorem"
                android:textSize="18sp" />
        </android.support.v7.widget.CardView>


    </android.support.v4.widget.NestedScrollView>

//注意看,我隐藏掉了 toolbar,但是并没有gone他,因为还是要让他,占位置,让我的小头像跟随
    <android.support.v7.widget.Toolbar
        android:id="@+id/main.toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/cardview_light_background"
        app:contentInsetLeft="0dp"
        app:contentInsetStart="0dp"
        app:layout_anchor="@id/main.framelayout.title"
        app:layout_collapseMode="pin"
        android:visibility="invisible"
        app:theme="@style/ThemeOverlay.AppCompat.Dark"
        app:title="">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="horizontal"

            >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginLeft="8dp"
                android:gravity="center_vertical"
                android:text="@string/quila_name2"
                android:textColor="@android:color/white"
                android:textSize="20sp" />

        </LinearLayout>
    </android.support.v7.widget.Toolbar>


        <de.hdodenhof.circleimageview.CircleImageView
            android:layout_width="@dimen/image_width"
            android:layout_height="@dimen/image_width"
            android:layout_gravity="center_horizontal"
            android:src="@drawable/quila"
            app:border_color="@android:color/holo_red_dark"
            app:border_width="2dp"
            app:finalHeight="@dimen/image_final_width"
            app:finalYPosition="2dp"
            app:layout_behavior="saulmm.myapplication.AvatarImageBehavior"
            app:startHeight="2dp"
            app:startToolbarPosition="2dp"
            app:startXPosition="2dp" />


</android.support.design.widget.CoordinatorLayout>

其实就是一个道理,真亦假时假亦真,看到的不一定是真实的。都是虚幻,哈哈。也是之前看到,另一个大牛,写爆炸android特效经常用的,贯彻他的思路,我才能想到这个偷懒的方法。讲讲我的思路:

我们利用原有的toolbar作为,小头像的移动依靠,当小头像移动到我们自己添加toolbar的位置的时候,将我们我们的toolbar显示出来。

有人会提问,这尼玛在逗我吗?你这样隐藏显示的,有什么意义?

原因是这样的:因为布局的原因。android5.0的toolbar 一定必须是顶层的吧。你的所有内容都应该是在他下面的吧。按照这个思路,我们就知道,其实,为什么没有隐藏小头像的原因,那就是,我们把自己toolbar显示出来就是,为了压盖这原有的小头像。为了达到和淘宝的效果一样,一瞬间掩藏。你会感觉,小头像是流畅的跑到了toolbar上的其实不然,你松手就会被在AppBarLayout下的toolbar覆盖掉。这就是为什么要要这个时候把原本准备好的小头像显示出来的原因,如果我解释的不太清楚,可以看看,我的图片,我用绿色边勾勒的是小头像是我提前准备好的那张头像。

好了其实这些都不是我想说的重点,重点是,大神写的这个流畅的,Behavior
好了我需要在粘贴两个重点的代码。

    private void maybeInitProperties(CircleImageView child, View dependency) {
        if (mStartYPosition == 0)
            mStartYPosition = (int) (dependency.getY());

        if (mFinalYPosition == 0)
            mFinalYPosition = (dependency.getHeight() /2);

        if (mStartHeight == 0)
            mStartHeight = child.getHeight();

        if (mStartXPosition == 0)
            mStartXPosition = (int) (child.getX() + (child.getWidth() / 2));

        if (mFinalXPosition == 0)
            mFinalXPosition =  ((int) dependency.getWidth() / 2);

        if (mStartToolbarPosition == 0)
            mStartToolbarPosition = dependency.getY();

        if (mChangeBehaviorPoint == 0) {
            mChangeBehaviorPoint = (child.getHeight() - mCustomFinalHeight) / (2f * (mStartYPosition - mFinalYPosition));
        }
    }

看这个代码的时候我准备了一张图片,虽然有点糙,但是凑合看吧


超级麻烦的手绘图片

这就是大概一个,逻辑图片,说明了。大概要用的几个属性值是什么意思,这里最重点的是这句话

  mChangeBehaviorPoint = (child.getHeight() - mCustomFinalHeight) / (2f * (mStartYPosition - mFinalYPosition));

一看就知道,他们要比例什么了,


圆圈圈和正方形

简单解释一下,一个两个圆的差值 比矩形的差值还✖️2 这是要做什么,我看完整个代码才懂,他是为了。一个位置上做缩放动画,让缩放动画更加紧凑的一个过程,✖️2的意思其实就是增加除数值,让这个动画相应位置更加向上一点。必须说,我原本以为是一个,数学表达式,结果好像不是的,是一个动画设计思路。

@Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, CircleImageView child, View dependency) {
        maybeInitProperties(child, dependency);

        final int maxScrollDistance = (int) (mStartToolbarPosition);
        float expandedPercentageFactor = dependency.getY() / maxScrollDistance;

        if (expandedPercentageFactor < mChangeBehaviorPoint) {
            float heightFactor = (mChangeBehaviorPoint - expandedPercentageFactor) / mChangeBehaviorPoint;

            float distanceXToSubtract = ((mStartXPosition - mFinalXPosition)
                    * heightFactor) + (child.getHeight()/2);
            float distanceYToSubtract = ((mStartYPosition - mFinalYPosition)
                    * (1f - expandedPercentageFactor)) + (child.getHeight()/2);

            child.setX(mStartXPosition - distanceXToSubtract);
            child.setY(mStartYPosition - distanceYToSubtract);

            float heightToSubtract = ((mStartHeight - mCustomFinalHeight) * heightFactor);

            CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
            lp.width = (int) (mStartHeight - heightToSubtract);
            lp.height = (int) (mStartHeight - heightToSubtract);
            child.setLayoutParams(lp);
        } else {
            float distanceYToSubtract = ((mStartYPosition - mFinalYPosition)
                    * (1f - expandedPercentageFactor)) + (mStartHeight/2);

            child.setX(mStartXPosition - child.getWidth()/2);
            child.setY(mStartYPosition - distanceYToSubtract);

            CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
            lp.width = (int) (mStartHeight);
            lp.height = (int) (mStartHeight);
            child.setLayoutParams(lp);
        }
        return true;
    }

重点代码

  if (expandedPercentageFactor < mChangeBehaviorPoint) 

一个if搞定了全世界,if后面的是小头像缩放功能的已经X、Y轴的移动。else是处理,还原大小和位置移动的仅仅是Y轴的。

就这样,所有的工作都做完了。我不知道第一次的表达,是不是够清楚,其实源码没有修改什么,如果需要我可以,上传,重点是,是原作者的思路。
我修改后的源码
马上准备 ios的类似源码分析,努力做到,ios和android一起跑着玩的节奏。希望能带节奏。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,009评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,808评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,891评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,283评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,285评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,409评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,809评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,487评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,680评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,499评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,548评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,268评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,815评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,872评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,102评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,683评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,253评论 2 341

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,333评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,005评论 4 61
  • 一大早,心情好,我、爷爷、奶奶,我们准备去何山公园。 坐307公交到佳林苑的公交站台,边走边问路,终于在十点二十分...
    senny1978阅读 229评论 0 0
  • 电影《房间》讲了一对了不起的母子奔向自由的故事。17岁的女孩joy在一天放学回家的路上,被一个男人谎称自己的狗生病...
    高中语文笔记帮阅读 508评论 0 3