新年好,首先給你們發個紅包。css
[意念紅包]請閉上眼睛經過念力領取。html
這都2017年了,是時候來一波基礎特效教程了!android
若是我不偷懶的話,或許能夠成爲一個系列都基礎教程哦。固然若是成爲了一個系列,這個系列就像標題說的同樣,是基礎特效。因此內容會比較簡單,若是你是老司機的話,能夠直接飄過了(順便帶我上車!)。git
本次項目地址:https://github.com/githubwing/WingUEgithub
此次依然拿餓了麼開刀。來庖丁一個搜索欄過分效果,以下圖:
微信
額,圖片仍是比較大的,爲了避免浪費排版空間,此次就不上餓了麼原圖了,直接上效果圖。效果仍是差很少的哈。markdown
如你所見,這是一個過分效果。 用一個羣友的話來講就是絲滑過分根本看不出來是兩個Activity。app
這是兩個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縮放操做。因此如今要作的動畫有:
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
參考文章: 低版本實現共享元素動畫