新年好,首先给大家发个红包。
[意念红包]请闭上眼睛通过念力领取。
这都2017年了,是时候来一波基础特效教程了!
如果我不偷懒的话,或许可以成为一个系列都基础教程哦。当然如果成为了一个系列,这个系列就像标题说的一样,是基础特效。所以内容会比较简单,如果你是老司机的话,可以直接飘过了(顺便带我上车!)。
本次项目地址: https://github.com/githubwing/WingUE
这次依然拿饿了么开刀。来庖丁一个搜索栏过度效果,如下图:
额,图片还是比较大的,为了不浪费排版空间,这次就不上饿了么原图了,直接上效果图。效果还是差不多的哈。
如你所见,这是一个过度效果。 用一个群友的话来说就是丝滑过度根本看不出来是两个Activity。
这是两个Activity,看起来顺化的原因是使用了一种叫做共享元素的概念。Android 5.0自带共享元素的实现,但是有一些缺点比如:不能改变大小, 不能兼容4.X 等等。
其实本次的效果在 高仿微信下滑返回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
参考文章: 低版本实现共享元素动画