Android轉(zhuǎn)場(chǎng)效果實(shí)現(xiàn)示例淺析
前言
又沒什么好的思路,還是隨便寫一些,所以這次就來整點(diǎn)活。
我們都知道Activity的跳轉(zhuǎn)擁有默認(rèn)的跳轉(zhuǎn)動(dòng)畫,或者把這個(gè)默認(rèn)的動(dòng)畫給取消,就會(huì)讓跳轉(zhuǎn)的效果讓人覺得比較生硬。那我們能不能做出一些比較好的轉(zhuǎn)場(chǎng)效果呢?本篇只介紹實(shí)現(xiàn)的思路,而不去深究某個(gè)思路的具體實(shí)現(xiàn),因?yàn)橛行┲R(shí)點(diǎn)內(nèi)容太多了,如果深入去看怕是很難一時(shí)半會(huì)講明白。
Activity跳轉(zhuǎn)動(dòng)畫
Activity是可以設(shè)置跳轉(zhuǎn)動(dòng)畫的,有了動(dòng)畫之后,跳轉(zhuǎn)的效果的體驗(yàn)就會(huì)比之前好一些。
我這里先寫兩個(gè)動(dòng)畫,跳轉(zhuǎn)時(shí)新頁面進(jìn)入的動(dòng)畫
<set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="100%" android:toXDelta="0%" android:fromYDelta="0%" android:toYDelta="0%" android:duration="1000"/> </set>
和舊頁面退出的動(dòng)畫
<set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0%" android:toXDelta="-100%" android:fromYDelta="0%" android:toYDelta="0%" android:duration="1000"/> </set>
然后在跳轉(zhuǎn)時(shí)調(diào)用方法
Intent intent = new Intent(TwoActivity.this, ThreeActivity.class); startActivity(intent); overridePendingTransition(R.anim.activity_start,R.anim.activity_end);
這樣就能實(shí)現(xiàn)頁面切換時(shí)的動(dòng)畫效果,但是要有一點(diǎn)需要注意,這個(gè)動(dòng)畫一定要合理,因?yàn)槭莿?dòng)畫展示完之后第二個(gè)頁面才展示,如果你動(dòng)畫的邏輯涉及得不合理,會(huì)出現(xiàn)動(dòng)畫結(jié)束之后再展示第二個(gè)頁面這個(gè)過程會(huì)顯得很生硬。
但是如果僅僅只有頁面切換的動(dòng)畫,還是覺得差點(diǎn)意思。這時(shí)候就需要發(fā)揮自己想象力了。我這里可以用一個(gè)自定義View和這個(gè)動(dòng)畫進(jìn)行聯(lián)動(dòng),讓他們看起來是一個(gè)整體的效果。
比如我這樣寫一個(gè)View
<RelativeLayout android:id="@+id/btn" android:layout_width="120dp" android:layout_height="60dp" android:background="@drawable/test_start" android:layout_alignParentEnd="true" android:layout_marginTop="50dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下一步" android:layout_centerInParent="true" android:textColor="#ffff" /> </RelativeLayout>
設(shè)置一個(gè)背景,顏色和第二個(gè)頁面的顏色相同
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <!--背景顏色--> <solid android:color="@color/jh_blue" /> <corners android:topLeftRadius="100dp" android:bottomLeftRadius="100dp" /> </shape>
最終會(huì)展現(xiàn)出這樣的效果
共享元素
在5.0之后,android提供了共享元素的實(shí)現(xiàn)。Material Design剛出來的時(shí)候我還沒畢業(yè),我覺得現(xiàn)在回去看它的這個(gè)思想和一些內(nèi)容,確實(shí)能有一些其它的收獲,這個(gè)概念的提出確實(shí)牛
共享元素簡單來說效果就是你兩個(gè)頁面之間的跳轉(zhuǎn),設(shè)置了共享的元素會(huì)做個(gè)動(dòng)畫,會(huì)讓人感覺是這個(gè)頁面的View做了一個(gè)動(dòng)畫移動(dòng)到另一個(gè)頁面,體現(xiàn)出現(xiàn)的效果就很好。
那既然效果好,為什么不普遍使用呢?我覺得有兩個(gè)原因,第一個(gè)是之前不像現(xiàn)在一樣基本都是5.0以上的手機(jī),之前要對(duì)4.4做適配,然后開發(fā)中,沒那方面的需求,自然也不會(huì)往那個(gè)方向去想,甚至都不知道Android有提供這個(gè)東西。第二個(gè)原因是好用是好用,相對(duì)的坑也多。
可以先看看如何實(shí)現(xiàn),我這里寫個(gè)簡單點(diǎn)的Demo,首先在第一個(gè)頁面創(chuàng)建一個(gè)view
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" > <ImageView android:id="@+id/iv_test" android:layout_width="90dp" android:layout_height="90dp" android:layout_marginTop="500dp" android:src="@drawable/aaaaa" android:transitionName="test" /> </RelativeLayout>
看到這里有個(gè)屬性transitionName,這個(gè)就是定義共享元素,然后在第二個(gè)頁面也創(chuàng)建一個(gè)view
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/blue" android:gravity="center_horizontal" > <ImageView android:id="@+id/iv_test" android:layout_width="180dp" android:layout_height="180dp" android:layout_marginTop="20dp" android:src="@drawable/aaaaa" android:transitionName="test" /> </RelativeLayout>
看到他們的transitionName是一樣的,然后在跳轉(zhuǎn)時(shí)用ActivityOptions.makeSceneTransitionAnimation就行了,具體的它已經(jīng)里面幫你封裝好了
ImageView imageView = findViewById(R.id.iv_test); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(TwoActivity.this, ThreeActivity.class); Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(TwoActivity.this, imageView, "test") .toBundle(); startActivity(intent, bundle); } });
就這么簡單,其中要注意的是你頁面的style如果是用Material的style就沒什么問題,但如果不是,你就需要在你的style中設(shè)置
<item name="android:windowActivityTransitions">true</item>
當(dāng)然也可以在代碼中動(dòng)態(tài)設(shè)置
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
最終的效果就是這樣的
這個(gè)動(dòng)畫效果是默認(rèn)的,如果你要自己實(shí)現(xiàn),就需要自己去寫transition,比如我這里這樣設(shè)置時(shí)間
<fade xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300" />
<style name="test_style" parent="android:Theme.NoTitleBar.Fullscreen"> <item name="android:windowActivityTransitions">true</item> <item name="android:windowEnterTransition">@transition/activity_fade</item> <item name="android:windowExitTransition">@transition/activity_fade</item> </style>
它其實(shí)功能很龐大,同樣的坑也會(huì)很多。我這里就不往下說了,前面也說了,這篇文章主要是寫個(gè)思路,你要是能把它玩好了,就和自定義view一樣,屬性動(dòng)畫一樣,想實(shí)現(xiàn)什么效果,就實(shí)現(xiàn)什么效果,我也不常用,對(duì)這個(gè)技術(shù)點(diǎn)也只是入門。
通過window去實(shí)現(xiàn)
這個(gè)思路是在activity上方有個(gè)圖層,圖層中有個(gè)view和下方圖層的view的大小和位置相同,然后去改上圖層的view。此時(shí)如果下圖層做跳轉(zhuǎn),也不會(huì)影響,就是能實(shí)現(xiàn)和上面共享元素一樣的效果。但是我以前用的window是系統(tǒng)級(jí)別的window,所以能實(shí)現(xiàn)效果,其它級(jí)別的不知道會(huì)不會(huì)有問題,得開發(fā)時(shí)候具體調(diào)試才知道,總之主要看思路,先不用在意細(xì)節(jié)。
還是用一個(gè)Demo來舉例,先寫Activity的頁面,兩個(gè)textview是用做標(biāo)識(shí)看效果的
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" > <ImageView android:id="@+id/iv_test" android:layout_width="90dp" android:layout_height="90dp" android:layout_marginTop="500dp" android:src="@drawable/aaaaa" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="在圖片上方" android:layout_marginTop="480dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="在圖片下方" android:layout_below="@+id/iv_test" /> </RelativeLayout>
再寫window的布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" > <ImageView android:id="@+id/iv_test" android:layout_width="90dp" android:layout_height="90dp" android:layout_marginTop="500dp" android:src="@drawable/aaaaa" /> </RelativeLayout>
可以看到兩個(gè)view的初始位置和大小都相同,然后看看具體的實(shí)現(xiàn)
public class TwoActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test_two); ImageView imageView = findViewById(R.id.iv_test); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { playWindow(); } }); } private void playWindow() { RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.test_window, null); View windowView = relativeLayout.findViewById(R.id.iv_test); WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); WindowManager.LayoutParams wlp = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_APPLICATION, WindowManager.LayoutParams.FLAG_FULLSCREEN , PixelFormat.RGBA_8888); windowManager.addView(relativeLayout, wlp); windowView.post(new Runnable() { @Override public void run() { start(windowView); } }); } private void start(final View view) { int w = view.getWidth(); int h = view.getHeight(); ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 300); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int v = (int) animation.getAnimatedValue(); RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) view.getLayoutParams(); rlp.width = w + v; rlp.height = h + v; view.setLayoutParams(rlp); view.invalidate(); } }); valueAnimator.setDuration(700).start(); } }
demo里面我為了方便用了TYPE_APPLICATION,但實(shí)際我這邊開發(fā)用的是FIRST_SYSTEM_WINDOW以上的系統(tǒng)層級(jí)彈窗。
然后我們來看看最終的效果
這里是做了個(gè)放大的效果,但實(shí)際你可以放大后跳轉(zhuǎn)Activity然后移動(dòng)位置,再縮小,就有無縫轉(zhuǎn)場(chǎng)的效果,其實(shí)和上面的共享元素的效果類似。
總結(jié)
能實(shí)現(xiàn)轉(zhuǎn)場(chǎng)的方式很多,不用拘束于調(diào)用原生的方法,比如如果真依賴原生提供的方法,要是真要適配5.0以下的怎么做?最重要的是要發(fā)揮自己的想象力,去思考。當(dāng)然,這個(gè)原生提供的系統(tǒng)確實(shí)也有很多學(xué)問在里邊,想要玩得爐火純青,也是需要不斷的去嘗試,不斷的去踩坑。
以上就是Android轉(zhuǎn)場(chǎng)效果實(shí)現(xiàn)示例淺析的詳細(xì)內(nèi)容,更多關(guān)于Android轉(zhuǎn)場(chǎng)效果的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Android轉(zhuǎn)場(chǎng)動(dòng)畫深入分析探究
- Android?Flutter實(shí)現(xiàn)頁面切換轉(zhuǎn)場(chǎng)動(dòng)畫效果
- Android實(shí)現(xiàn)Reveal圓形Activity轉(zhuǎn)場(chǎng)動(dòng)畫的完整步驟
- Android工具欄頂出轉(zhuǎn)場(chǎng)動(dòng)畫的實(shí)現(xiàn)方法實(shí)例
- Android5.0之Activity的轉(zhuǎn)場(chǎng)動(dòng)畫的示例
- 詳解Android(共享元素)轉(zhuǎn)場(chǎng)動(dòng)畫開發(fā)實(shí)踐
- Android中轉(zhuǎn)場(chǎng)動(dòng)畫的實(shí)現(xiàn)與兼容性處理
相關(guān)文章
Android仿IOS UIAlertView對(duì)話框
這篇文章主要為大家詳細(xì)介紹了Android仿IOS UIAlertView對(duì)話框,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06Android GridView 滑動(dòng)條設(shè)置一直顯示狀態(tài)(推薦)
這篇文章主要介紹了Android GridView 滑動(dòng)條設(shè)置一直顯示狀態(tài)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12談?wù)凙ndroid6.0運(yùn)行時(shí)的權(quán)限處理
之前有人在 Android 6.0 的機(jī)型上運(yùn)行了DragGridView結(jié)果出異常奔潰了。想必問題的原因大家都知道,是Android 6.0新引入了在運(yùn)行時(shí)權(quán)限申請(qǐng)(Runtime Permissions)的功能。那么這所謂的運(yùn)行時(shí)申請(qǐng)權(quán)限究竟是怎么一回事呢,下面跟著小編一起來看看吧!2016-08-08Flutter實(shí)現(xiàn)底部菜單導(dǎo)航
這篇文章主要為大家詳細(xì)介紹了Flutter實(shí)現(xiàn)底部菜單導(dǎo)航,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02Android中ImageView使用網(wǎng)絡(luò)圖片資源的方法
這篇文章主要介紹了Android中ImageView使用網(wǎng)絡(luò)圖片資源的方法,較為詳細(xì)的分析了ImageView調(diào)用網(wǎng)絡(luò)圖片的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10Android編程實(shí)現(xiàn)創(chuàng)建,刪除,判斷快捷方式的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)創(chuàng)建,刪除,判斷快捷方式的方法,結(jié)合實(shí)例形式分析了Android編程針對(duì)快捷方式的常用操作技巧,需要的朋友可以參考下2017-02-02Flutter手勢(shì)密碼的實(shí)現(xiàn)示例(附demo)
本文主要介紹了Flutter手勢(shì)密碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08