Android實(shí)現(xiàn)一個(gè)比相冊(cè)更高大上的左右滑動(dòng)特效(附源碼)
在Android里面,想要實(shí)現(xiàn)一個(gè)類似相冊(cè)的左右滑動(dòng)效果,我們除了可以用Gallery、HorizontalScrollView、ViewPager等控件,還可以用一個(gè)叫做 ViewFlipper 的類來(lái)代替實(shí)現(xiàn),它繼承于 ViewAnimator。如見其名,這個(gè)類是跟動(dòng)畫有關(guān),會(huì)將添加到它里面的兩個(gè)或者多個(gè)View做一個(gè)動(dòng)畫,然后每次只顯示一個(gè)子View,通過在 View 之間切換時(shí)執(zhí)行動(dòng)畫,最終達(dá)到一個(gè)類似相冊(cè)能左右滑動(dòng)的效果。
本次功能要實(shí)現(xiàn)的兩個(gè)基本效果
- 最基本的左右滑動(dòng)效果
- 從屏幕的45度方向進(jìn)入和退出的效果
實(shí)現(xiàn)思路
- 按照 ViewFlipper 的源碼說明,它是將兩個(gè)或多個(gè)View用動(dòng)畫展示出來(lái)。那么我就在 ViewFlipper 內(nèi)放入兩個(gè)布局,每個(gè)布局都包含一個(gè) TextView 和 ImageView,分別用于顯示文字和圖片
- 既然要有動(dòng)畫效果,我準(zhǔn)備使用Android的位移動(dòng)畫類 TranslateAnimation,設(shè)置起始的橫縱坐標(biāo)值
- 為了讓效果明顯,我會(huì)設(shè)置 ViewFlipper 的進(jìn)入和退出屏幕的動(dòng)畫,并且在左滑時(shí)呈現(xiàn)一個(gè)動(dòng)畫、右滑時(shí)呈現(xiàn)另一個(gè)動(dòng)畫(需要判斷是左滑還是右滑:重寫 onTouchEvent 方法,比較橫坐標(biāo)X的值的變化)
源碼如下:
1、主Activity
// import語(yǔ)句省略
public class ViewFlipperDemo extends Activity {
private static final String TAG = "ViewFlipperDemo";
private ViewFlipper mViewFlipper;
private float mOldTouchValue;
@Override
protected void onCreate(Bundle onSavedInstance) {
super.onCreate(onSavedInstance);
// 設(shè)置為全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.view_flipper_demo);
mViewFlipper = findViewById(R.id.viewFlipper1);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mOldTouchValue = event.getX();
break;
case MotionEvent.ACTION_UP:
float currentX = event.getX();
// 手指向右滑動(dòng): 手指向右滑動(dòng)時(shí)橫坐標(biāo) X 的值會(huì)變大,因此 currentX 的值更大
if (mOldTouchValue < currentX) {
// 進(jìn)入屏幕的動(dòng)效
mViewFlipper.setInAnimation(AnimationHelper.inFromLeftAnimation());
// 退出屏幕的動(dòng)效
mViewFlipper.setOutAnimation(AnimationHelper.outToRightAnimation());
mViewFlipper.showNext();
}
// 橫坐標(biāo)的值變小,說明是左滑
if (mOldTouchValue > currentX) {
// 進(jìn)入屏幕的動(dòng)效
mViewFlipper.setInAnimation(AnimationHelper.inFromRightAnimation());
// 退出屏幕的動(dòng)效
mViewFlipper.setOutAnimation(AnimationHelper.outToLeftAnimation());
mViewFlipper.showPrevious();
}
break;
default:
break;
}
return super.onTouchEvent(event);
}
}
2、對(duì)應(yīng)的布局文件 view_flipper_demo.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/colorBlack"
android:gravity="center"
android:text="這是一個(gè)ViewFlipper樣例"
android:paddingTop="20dp"/>
<ViewFlipper android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/viewFlipper1">
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/colorBlue"
android:gravity="center"
android:text="這是第一個(gè)ViewFlipper頁(yè)面"/>
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/avasterdr"/>
</LinearLayout>
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center" >
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/colorBlue"
android:gravity="center"
android:text="這是第二個(gè)ViewFlipper頁(yè)面"/>
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/avastertony"/>
</LinearLayout>
</ViewFlipper>
</LinearLayout>
3、動(dòng)畫輔助類 AnimationHelper.java
public class AnimationHelper {
// 左滑的進(jìn)入動(dòng)畫
public static Animation inFromRightAnimation() {
Animation inFromRight = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT,
1.0f,
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
0.0f);
inFromRight.setDuration(500);
inFromRight.setInterpolator(new AccelerateInterpolator());
return inFromRight;
}
// 左滑的退出動(dòng)畫
public static Animation outToLeftAnimation() {
Animation outToLeft = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
-1.0f,
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
0.0f);
outToLeft.setDuration(500);
outToLeft.setInterpolator(new AccelerateInterpolator());
return outToLeft;
}
// 右滑的進(jìn)入動(dòng)畫
public static Animation inFromLeftAnimation() {
Animation inFromLeft = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT,
-1.0f,
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
0.0f);
inFromLeft.setDuration(500);
inFromLeft.setInterpolator(new AccelerateInterpolator());
return inFromLeft;
}
// 右滑的退出動(dòng)畫
public static Animation outToRightAnimation() {
Animation outToRight = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
1.0f,
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
0.0f);
outToRight.setDuration(500);
outToRight.setInterpolator(new AccelerateInterpolator());
return outToRight;
}
}
4、對(duì)應(yīng)的效果圖如下

可以看到,這個(gè)左右滑動(dòng)效果沒有任何酷炫的地方。我們不妨先來(lái)看看跟動(dòng)畫相關(guān)的幾個(gè)重點(diǎn)地方:
(1)函數(shù) setInAnimation:是指 View 進(jìn)入屏幕的動(dòng)效
(2)函數(shù) setOutAnimation:是指 View 退出屏幕的動(dòng)效
(3)TranslateAnimation的構(gòu)造函數(shù)的參數(shù)解釋:
1、fromXType/toXType/fromYType/toYType,取值共有三個(gè):
Animation.ABSOLUTEAnimation.RELATIVE_TO_SELFAnimation.RELATIVE_TO_PARENT
我這里用的是 Animation.RELATIVE_TO_PARENT,當(dāng)傳入該參數(shù)時(shí),其余幾個(gè)坐標(biāo)值需要傳入百分比參數(shù)(1.0表示100%);如果傳入 Animation.ABSOLUTE,坐標(biāo)值需要傳入屏幕上的絕對(duì)位置(比如1000,1000)
2、fromXValue:起點(diǎn)的橫坐標(biāo)值
3、toXValue:終點(diǎn)的橫坐標(biāo)值
4、fromYValue:起點(diǎn)的縱坐標(biāo)值
5、toYValue:終點(diǎn)的縱坐標(biāo)值
如果我們想讓這個(gè)效果變成45度從屏幕的四個(gè)角進(jìn)入和退出,那代碼就應(yīng)該這么寫(注意代碼中傳入的 4 個(gè)橫縱坐標(biāo)值):
// 左滑的進(jìn)入動(dòng)畫
public static Animation inFromRightAnimation() {
Animation inFromRight = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT,
1.0f,
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
-1.0f,
Animation.RELATIVE_TO_PARENT,
0.0f);
inFromRight.setDuration(500);
inFromRight.setInterpolator(new AccelerateInterpolator());
return inFromRight;
}
// 左滑的退出動(dòng)畫
public static Animation outToLeftAnimation() {
Animation outToLeft = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
-1.0f,
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
1.0f);
outToLeft.setDuration(500);
outToLeft.setInterpolator(new AccelerateInterpolator());
return outToLeft;
}
// 右滑的進(jìn)入動(dòng)畫
public static Animation inFromLeftAnimation() {
Animation inFromLeft = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT,
-1.0f,
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
-1.0f,
Animation.RELATIVE_TO_PARENT,
0.0f);
inFromLeft.setDuration(500);
inFromLeft.setInterpolator(new AccelerateInterpolator());
return inFromLeft;
}
// 右滑的退出動(dòng)畫
public static Animation outToRightAnimation() {
Animation outToRight = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
1.0f,
Animation.RELATIVE_TO_PARENT,
0.0f,
Animation.RELATIVE_TO_PARENT,
1.0f);
outToRight.setDuration(500);
outToRight.setInterpolator(new AccelerateInterpolator());
return outToRight;
}
對(duì)應(yīng)的效果如下:

之所以有 -1.0f 這個(gè)值,是因?yàn)槠聊簧系臋M縱坐標(biāo)值的分布可以用如下象限來(lái)表示:

ViewFlipper中的 View 就位于象限的中心位置。因此,如果動(dòng)畫從左上角進(jìn)入,那么它的起始橫縱坐標(biāo)就是(-1,-1)。大家可以按照這個(gè)思路去實(shí)現(xiàn)自己想要的動(dòng)效。
到此這篇關(guān)于Android實(shí)現(xiàn)一個(gè)比相冊(cè)更高大上的左右滑動(dòng)特效(附源碼)的文章就介紹到這了,更多相關(guān)android 實(shí)現(xiàn)左右滑動(dòng)特效內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android自定義view實(shí)現(xiàn)滑動(dòng)解鎖效果
- Android實(shí)現(xiàn)小米相機(jī)底部滑動(dòng)指示器
- Android實(shí)現(xiàn)View滑動(dòng)效果的6種方法
- Android自定義SeekBar實(shí)現(xiàn)滑動(dòng)驗(yàn)證且不可點(diǎn)擊
- Android SeekBar實(shí)現(xiàn)禁止滑動(dòng)
- Android 滑動(dòng)Scrollview標(biāo)題欄漸變效果(仿京東toolbar)
- Android RecycleView滑動(dòng)停止后自動(dòng)吸附效果的實(shí)現(xiàn)代碼(滑動(dòng)定位)
- Android實(shí)現(xiàn)上下菜單雙向滑動(dòng)
- Android實(shí)現(xiàn)滑動(dòng)效果
- Android實(shí)現(xiàn)手勢(shì)滑動(dòng)(左滑和右滑)
- Android RecyclerView實(shí)現(xiàn)滑動(dòng)刪除
- 詳解Android使用CoordinatorLayout+AppBarLayout+CollapsingToolbarLayou實(shí)現(xiàn)手指滑動(dòng)效果
- Android實(shí)現(xiàn)三段式滑動(dòng)效果
相關(guān)文章
android二級(jí)listview列表實(shí)現(xiàn)代碼
今天來(lái)實(shí)現(xiàn)以下大眾點(diǎn)評(píng)客戶端的橫向listview二級(jí)列表,感興趣的朋友可以研究下2013-01-01
Android 懸浮窗權(quán)限各機(jī)型各系統(tǒng)適配大全(總結(jié))
這篇文章主要介紹了Android 懸浮窗權(quán)限各機(jī)型各系統(tǒng)適配大全(總結(jié)),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
判斷Android程序是否在前臺(tái)運(yùn)行的兩種方法
這篇文章主要介紹了判斷Android程序是否在前臺(tái)運(yùn)行的兩種方法,本文直接給出實(shí)現(xiàn)代碼,,需要的朋友可以參考下2015-06-06
Android:Field can be converted to a local varible.的解決辦法
這篇文章主要介紹了Android:Field can be converted to a local varible.的解決辦法的相關(guān)資料,希望通過本文能幫助到大家,讓大家遇到這樣的問題輕松解決,需要的朋友可以參考下2017-10-10
Android如何利用RecyclerView實(shí)現(xiàn)列表倒計(jì)時(shí)效果實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于Android如何利用RecyclerView實(shí)現(xiàn)列表倒計(jì)時(shí)效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02
Android自定義LinearLayout實(shí)現(xiàn)淘寶詳情頁(yè)
這篇文章主要為大家詳細(xì)介紹了Android自定義LinearLayout實(shí)現(xiàn)淘寶詳情頁(yè)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
Android開發(fā)之無(wú)痕過渡下拉刷新控件的實(shí)現(xiàn)思路詳解
下拉刷新效果功能在程序開發(fā)中經(jīng)常會(huì)見到,今天小編抽時(shí)間給大家分享Android開發(fā)之無(wú)痕過渡下拉刷新控件的實(shí)現(xiàn)思路詳解,需要的朋友參考下吧2016-11-11

