基本特效:饿了么丝滑无缝过分搜索栏的实现

新年好,首先给你们发个红包。css

[意念红包]请闭上眼睛经过念力领取。html


这都2017年了,是时候来一波基础特效教程了!android

若是我不偷懒的话,或许能够成为一个系列都基础教程哦。固然若是成为了一个系列,这个系列就像标题说的同样,是基础特效。因此内容会比较简单,若是你是老司机的话,能够直接飘过了(顺便带我上车!)。git

本次项目地址:https://github.com/githubwing/WingUEgithub

此次依然拿饿了么开刀。来庖丁一个搜索栏过分效果,以下图:
这里写图片描述微信

额,图片仍是比较大的,为了避免浪费排版空间,此次就不上饿了么原图了,直接上效果图。效果仍是差很少的哈。markdown

如你所见,这是一个过分效果。 用一个群友的话来讲就是丝滑过分根本看不出来是两个Activity。app

一个Activity仍是两个?

这是两个Activity,看起来顺化的缘由是使用了一种叫作共享元素的概念。Android 5.0自带共享元素的实现,可是有一些缺点好比:不能改变大小, 不能兼容4.X 等等。ide

如何实现?

其实本次的效果在高仿微信下滑返回PhotoView中有运用以及介绍。可是因为篇幅没有作详细的介绍,如今就向你们介绍实现这种效果的思路。动画

首先既然叫作共享元素,那么可想而知确定有两个Activity拥有一项共同的元素,多是图片、一个TextView、一个EditText等等。如效果图,他就是共享一整个EditText。准确地说是一个组成看似EditText的元素组。

为了实现这个效果,咱们须要在两个Activity中都放置一样的搜索栏元素。

<FrameLayout  android:layout_width="match_parent" android:layout_height="150dp" android:background="#0096FF" android:padding="10dp">

        <TextView  android:layout_marginLeft="10dp" android:layout_marginTop="20dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="广东省广州市番禺区" android:textColor="#fff" android:textSize="16sp" />

        <TextView  android:id="@+id/tv_search_bg" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/ele_search_bg" android:gravity="center" android:padding="10dp" />


        <TextView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:text="搜索商家、商品名称" />
        <TextView  android:gravity="center" android:textColor="#fff" android:text="烧烤 螺蛳粉 火锅 巴掌 麦当劳 冒菜 臭豆腐 云吞面 " android:layout_gravity="bottom" android:layout_width="match_parent" android:layout_height="wrap_content" />
    </FrameLayout>

如今咱们两个Activity都有这个元素了。接下来要作的只有一步:那就是startActivity。

哈哈,我真的没有逗你,由于其实全部你看到的动画都是在第二个Activity完成的。由效果图能够看到,在动画执行的过程当中仍是能够看到前一个Activity的,因此咱们须要对第二个Activity进行特殊的“透明处理”。

在style.xml里面新增长一个透明的主题,而且应用给第二个Activity。

<style name="Translucent" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowIsTranslucent">true</item>
    </style>

接下来,只要在第二个Activity打开的时候,进行一些动画便可。因此首先咱们要把第一个Activity中元素的坐标传给第二个Activity。

Intent intent = new Intent(EleActivity.this,EleSearchActivity.class);
                int location[] = new int[2];
                mSearchBGTxt.getLocationOnScreen(location);
                intent.putExtra("x",location[0]);
                intent.putExtra("y",location[1]);
                startActivity(intent);
                overridePendingTransition(0,0);

注意这里拿到的是在屏幕中的坐标。因此在第二个Activity中,获取第二个元素的坐标也要用屏幕中的坐标。

拿到以后,再根据两个坐标的差值进行平移操做,这样位移起来就彻底不须要考虑其余坐标系了。至于为何,留个做业(斜眼):

float originY = getIntent().getIntExtra("y", 0);

        int location[] = new int[2];
        mSearchBGTxt.getLocationOnScreen(location);

        float translateY = originY - (float) location[1];

若是你想要预览位置效果,能够直接view.setTranslateY(translateY);

接下来动画只要交给ValueAnimator,在这里把搜索栏的背景单独抽成一个View,用来进行X缩放操做。因此如今要作的动画有:

  1. 左侧箭头的Y轴平移动画。
  2. 右侧搜索的Y轴平移动画。
  3. 中间文字以及背景的Y轴平移动画。
  4. 中间背景的X缩放动画。
  5. 下部View内容的透明动画。
translateVa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mSearchBGTxt.setY((Float) valueAnimator.getAnimatedValue());
                mArrowImg.setY(mSearchBGTxt.getY() + (mSearchBGTxt.getHeight() - mArrowImg.getHeight()) / 2);
                mHintTxt.setY(mSearchBGTxt.getY() + (mSearchBGTxt.getHeight() - mHintTxt.getHeight()) / 2);
                mSearchTxt.setY(mSearchBGTxt.getY() + (mSearchBGTxt.getHeight() - mSearchTxt.getHeight()) / 2);
            }
        });

等动画执行完毕之后,只须要将View正确归为便可!

固然返回的时候,只须要往相反的地方作动画~ 另外还须要特别注意的地方有,在启动或者关闭Activity的时候,须要调用下面的代码来关闭切换动画来保证效果。

overridePendingTransition(0, 0);

感受此次效果虽然简单,可是应用场景仍是挺广得。

本次项目地址:https://github.com/githubwing/WingUE

若是你喜欢 欢迎Star,也能够加入个人Android酒馆:425983695

参考文章: 低版本实现共享元素动画

相关文章
相关标签/搜索