Android轉(zhuǎn)場效果實(shí)現(xiàn)示例淺析
前言
又沒什么好的思路,還是隨便寫一些,所以這次就來整點(diǎn)活。
我們都知道Activity的跳轉(zhuǎn)擁有默認(rèn)的跳轉(zhuǎn)動(dòng)畫,或者把這個(gè)默認(rèn)的動(dòng)畫給取消,就會(huì)讓跳轉(zhuǎn)的效果讓人覺得比較生硬。那我們能不能做出一些比較好的轉(zhuǎn)場效果呢?本篇只介紹實(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)場的效果,其實(shí)和上面的共享元素的效果類似。
總結(jié)
能實(shí)現(xiàn)轉(zhuǎn)場的方式很多,不用拘束于調(diào)用原生的方法,比如如果真依賴原生提供的方法,要是真要適配5.0以下的怎么做?最重要的是要發(fā)揮自己的想象力,去思考。當(dāng)然,這個(gè)原生提供的系統(tǒng)確實(shí)也有很多學(xué)問在里邊,想要玩得爐火純青,也是需要不斷的去嘗試,不斷的去踩坑。
以上就是Android轉(zhuǎn)場效果實(shí)現(xiàn)示例淺析的詳細(xì)內(nèi)容,更多關(guān)于Android轉(zhuǎn)場效果的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Android轉(zhuǎn)場動(dòng)畫深入分析探究
- Android?Flutter實(shí)現(xiàn)頁面切換轉(zhuǎn)場動(dòng)畫效果
- Android實(shí)現(xiàn)Reveal圓形Activity轉(zhuǎn)場動(dòng)畫的完整步驟
- Android工具欄頂出轉(zhuǎn)場動(dòng)畫的實(shí)現(xiàn)方法實(shí)例
- Android5.0之Activity的轉(zhuǎn)場動(dòng)畫的示例
- 詳解Android(共享元素)轉(zhuǎn)場動(dòng)畫開發(fā)實(shí)踐
- Android中轉(zhuǎn)場動(dòng)畫的實(shí)現(xiàn)與兼容性處理
相關(guān)文章
Android為Tiny4412設(shè)備驅(qū)動(dòng)在proc目錄下添加一個(gè)可讀版本信息的文件
今天小編就為大家分享一篇關(guān)于Android為Tiny4412設(shè)備驅(qū)動(dòng)在proc目錄下添加一個(gè)可讀版本信息的文件,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12
Android手機(jī)衛(wèi)士之確認(rèn)密碼對(duì)話框
這篇文章主要為大家詳細(xì)介紹了Android手機(jī)衛(wèi)士之確認(rèn)密碼對(duì)話框,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10
Android AlarmManager實(shí)現(xiàn)定時(shí)循環(huán)后臺(tái)任務(wù)
這篇文章主要為大家詳細(xì)介紹了Android AlarmManager實(shí)現(xiàn)定時(shí)循環(huán)后臺(tái)任務(wù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06
Android進(jìn)階之從IO到NIO的模型機(jī)制演進(jìn)
這篇文章主要為大家介紹了Android進(jìn)階之從IO到NIO的模型機(jī)制演進(jìn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
Android RecyclerView實(shí)現(xiàn)下拉刷新和上拉加載
這篇文章主要介紹了Android RecyclerView實(shí)現(xiàn)下拉刷新和上拉加載的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-05-05
Android?Flutter實(shí)現(xiàn)評(píng)分組件的示例代碼
在很多應(yīng)用中,我們都需要收集用戶的評(píng)分,比如商品滿意度、配送滿意度、應(yīng)用使用體驗(yàn)等等。本文就利用flutter_rating_bar實(shí)現(xiàn)簡易的評(píng)分組件,感興趣的可以2022-11-11
Android DrawerLayout布局與NavigationView導(dǎo)航菜單應(yīng)用
這篇文章主要介紹了Android DrawerLayout抽屜布局與NavigationView導(dǎo)航菜單應(yīng)用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-01-01
Android自定義View設(shè)定到FrameLayout布局中實(shí)現(xiàn)多組件顯示的方法 分享
Android自定義View設(shè)定到FrameLayout布局中實(shí)現(xiàn)多組件顯示的方法 分享,需要的朋友可以參考一下2013-05-05

