Android ViewFlipper的簡(jiǎn)單使用
大家都使用過(guò)ViewPager,但是ViewPager還有一個(gè)兄弟,那就是ViewFlipper。兩者的名字非常相似,我們可以將ViewPager理解成“一頁(yè)一頁(yè)的視圖”,ViewFlipper則是“快速翻轉(zhuǎn)的視圖”,但后者的使用率卻遠(yuǎn)不及前者,不過(guò)這并不意味著ViewFlipper就弱了。現(xiàn)在我們就來(lái)拜訪一下經(jīng)常被冷落的ViewFlipper。
1、創(chuàng)建工程及頁(yè)面視圖布局
在Android Studio中新建一個(gè)工程,實(shí)現(xiàn)這樣一個(gè)效果:創(chuàng)建紅、橙、綠、藍(lán)四種顏色的頁(yè)面,然后通過(guò)ViewFlipper讓它們來(lái)回切換。四個(gè)頁(yè)面布局文件的名稱如下所示:
item_view1.xml的代碼如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:background="@android:color/holo_red_light" android:layout_width="match_parent" android:layout_height="match_parent"> </LinearLayout>
另外三個(gè)布局的代碼只要把背景色換掉就可以了。
2、添加布局至ViewFlipper
頁(yè)面創(chuàng)建好了,那我們?cè)趺窗阉胖玫絍iewFlipper中呢?很簡(jiǎn)單,ViewFlipper支持include標(biāo)簽添加頁(yè)面,我們只需在activity_main.xml中將四個(gè)布局依次include進(jìn)去即可。
直接運(yùn)行就可以看到下面的效果了:
除了直接在布局文件中添加頁(yè)面外,也可以在代碼中添加,把a(bǔ)ctivity_mai.xml中include標(biāo)簽注釋掉,然后在MainActivity中初始化ViewFlipper之后再添加如下的代碼:
//要添加的頁(yè)面布局ID private int viewIds[] = {R.layout.item_view1, R.layout.item_view2, R.layout.item_view3, R.layout.item_view4}; /** * 將頁(yè)面添加進(jìn)ViewFlipper */ private void addViews() { View itemView; for (int viewId : viewIds) { itemView = View.inflate(this,viewId,null); viewFlipper.addView(itemView); } }
然后在onCreate中調(diào)用addViews方法即可。
3、添加頁(yè)面切換動(dòng)畫(huà)
頁(yè)面切換的效果我們是實(shí)現(xiàn)了,但是沒(méi)有變化過(guò)程,看起來(lái)太生硬了,累眼睛。如果能有動(dòng)畫(huà)效果的話就會(huì)舒服很多。這里,我們就要用到兩個(gè)新屬性了:
- inAnimation:視圖進(jìn)入時(shí)的動(dòng)畫(huà)效果
- outAnimation:視圖退出時(shí)的動(dòng)畫(huà)效果
這兩個(gè)屬性也可以在代碼中設(shè)置的,稍后我們會(huì)用到。現(xiàn)在,我們就創(chuàng)建所需要的動(dòng)畫(huà)文件。比如,我想要實(shí)現(xiàn)左右循環(huán)滑動(dòng)的動(dòng)畫(huà)效果,那么就可以分成兩種情況來(lái)討論:一種是新的視圖從左邊進(jìn)入,原有的視圖從右邊退出,即從左往右滑動(dòng);另一種是新視圖從右邊進(jìn)入,原有的視圖從左邊退出,即從右往左滑動(dòng)。弄清楚所有的動(dòng)畫(huà)效果之后,我們就在res文件夾下新建一個(gè)anim文件夾,創(chuàng)建如下如下四種動(dòng)畫(huà)效果:
left_in.xml
視圖從左邊進(jìn)入界面的動(dòng)畫(huà):
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="500" android:fromXDelta="-100%p" android:toXDelta="0"/> </set>
left_out.xml
視圖從左邊退出界面的動(dòng)畫(huà):
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="500" android:fromXDelta="0" android:toXDelta="-100%p"/> </set>
right_in.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="500" android:fromXDelta="100%p" android:toXDelta="0"/> </set>
right_out.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="500" android:fromXDelta="0" android:toXDelta="100%p"/> </set>
現(xiàn)在我們先來(lái)試試從左往右轉(zhuǎn)的動(dòng)畫(huà)效果。在布局中給ViewFlipper加上如下的屬性:
android:inAnimation="@anim/left_in" android:outAnimation="@anim/right_out"
運(yùn)行一下,就可以實(shí)現(xiàn)從左往右滑動(dòng)的動(dòng)畫(huà)效果了(GIF圖有點(diǎn)失真,不過(guò)效果是沒(méi)問(wèn)題的)。
相信不用我說(shuō),你也知道怎么讓它從右往左滑動(dòng)了吧?
4、手指左右滑屏一(使用觸摸監(jiān)聽(tīng)事件實(shí)現(xiàn))
看著畫(huà)面自顧自地滑動(dòng),是不是心癢癢的?沒(méi)關(guān)系,下面我們就來(lái)讓它響應(yīng)我們手指的滑動(dòng)。在此之前,先做點(diǎn)準(zhǔn)備工作:前往布局文件,去掉動(dòng)畫(huà)屬性,并將autoStart屬性設(shè)為false。
要讓它聽(tīng)從“指揮”,我們可以先繼承OnTouchListener接口,然后實(shí)現(xiàn)onTouch方法:
private float startX; //手指按下時(shí)的x坐標(biāo) private float endX; //手指抬起時(shí)的x坐標(biāo) private float moveX = 100f; //判斷是否切換頁(yè)面的標(biāo)準(zhǔn)值 /** * 觸摸監(jiān)聽(tīng)事件 * @param v * @param event * @return */ @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //手指按下時(shí)獲取起始點(diǎn)坐標(biāo) startX = event.getX(); break; case MotionEvent.ACTION_UP: //手指抬起時(shí)獲取結(jié)束點(diǎn)坐標(biāo) endX = event.getX(); //比較startX和endX,判斷手指的滑動(dòng)方向 if (endX - startX > moveX) { //手指從左向右滑動(dòng) viewFlipper.setInAnimation(this, R.anim.left_in); viewFlipper.setOutAnimation(this, R.anim.right_out); viewFlipper.showPrevious(); } else if (startX - endX > moveX) { //手指向右向左滑動(dòng) viewFlipper.setInAnimation(this, R.anim.right_in); viewFlipper.setOutAnimation(this, R.anim.left_out); viewFlipper.showNext(); } break; } return true; }
上面的代碼不難,注釋也寫得比較清楚了。總體的思路就是獲取手指按下和抬起時(shí)的坐標(biāo),然后判斷是向左還是向右滑動(dòng)。值得注意的是showPrevious和showNext方法,前者是顯示上一個(gè)視圖,后者則是顯示后一個(gè)視圖。最后還要記住,返回值要改為true,否則觸摸事件是無(wú)法響應(yīng)的。
效果圖如下,可以向左,也可以向右。
5、手指左右滑屏二(使用手勢(shì)監(jiān)聽(tīng)事件實(shí)現(xiàn))
除了觸摸監(jiān)聽(tīng)事件之外,我們也可以用手勢(shì)監(jiān)聽(tīng)事件OnGestureListener實(shí)現(xiàn)同樣的效果,但繼承了該接口之后要實(shí)現(xiàn)一連串的方法,代碼一下子膨脹起來(lái)了,而我們需要的只是其中一個(gè)方法啊。好在Android還提供了一個(gè)類SimpleOnGestureListener,這樣我們只要自定義一個(gè)類繼承它,然后實(shí)現(xiàn)我們需要的方法就可以了:
//創(chuàng)建手勢(shì)監(jiān)聽(tīng)器 GestureDetector gestureDetector = new GestureDetector(this, new MyGestureListener()); /** * 自定義手勢(shì)監(jiān)聽(tīng)類 */ class MyGestureListener extends GestureDetector.SimpleOnGestureListener{ @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (e2.getX() - e1.getX() > moveX){ viewFlipper.setInAnimation(MainActivity.this, R.anim.left_in); viewFlipper.setOutAnimation(MainActivity.this, R.anim.right_out); viewFlipper.showPrevious(); } else if (e2.getX() - e1.getX() < moveX){ viewFlipper.setInAnimation(MainActivity.this, R.anim.right_in); viewFlipper.setOutAnimation(MainActivity.this, R.anim.left_out); viewFlipper.showNext(); } return true; } }
這里的onFling方法得解釋一下,它表示的是手指在屏幕上移動(dòng)然后松開(kāi)的手勢(shì),也就是滑動(dòng)。前面兩個(gè)參數(shù)分別表示手指按下和松開(kāi)時(shí)的事件,通過(guò)它們的對(duì)象去調(diào)用getX()方法就可以獲取滑動(dòng)前后的坐標(biāo)了。后面的步驟就跟我們?cè)谟|摸事件里面的一樣,相信你能理解的。
我一開(kāi)始以為到這里就大功告成了,可運(yùn)行之后卻紋絲不動(dòng)!仔細(xì)查看文檔,發(fā)現(xiàn)還必須到觸摸監(jiān)聽(tīng)方法中調(diào)用onTouchEvent方法才行,否則觸摸事件不會(huì)起作用的。
@Override public boolean onTouch(View v, MotionEvent event) { gestureDetector.onTouchEvent(event); return true; }
6、后記
ViewFlipper的用法就告一段落了,寫這篇文章的時(shí)候我還順便復(fù)習(xí)了手勢(shì)監(jiān)聽(tīng)事件等知識(shí),也希望你能有所收獲。下面是源碼:
ViewFlipperDemo
7、參考文章
谷歌官方文檔之ViewFlipper
Android的手勢(shì)操作識(shí)別
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android開(kāi)發(fā)自學(xué)筆記(二):工程文件剖析
這篇文章主要介紹了Android開(kāi)發(fā)自學(xué)筆記(二):工程文件剖析,本文講解了AndroidManifest.xml、src文件夾、res文件夾等文件的作用,需要的朋友可以參考下2015-04-04Android自定義控件實(shí)現(xiàn)不規(guī)則區(qū)域點(diǎn)擊事件
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)不規(guī)則區(qū)域點(diǎn)擊事件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Android實(shí)戰(zhàn)教程第四十篇之Chronometer實(shí)現(xiàn)倒計(jì)時(shí)
這篇文章主要介紹了Android實(shí)戰(zhàn)教程第四十篇之Chronometer實(shí)現(xiàn)倒計(jì)時(shí),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11android中ViewPager結(jié)合Fragment進(jìn)行無(wú)限滑動(dòng)
本篇文章中主要介紹了android中ViewPager結(jié)合Fragment進(jìn)行無(wú)限滑動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03Android仿活動(dòng)時(shí)分秒倒計(jì)時(shí)效果
這篇文章主要為大家詳細(xì)介紹了Android仿活動(dòng)時(shí)分秒倒計(jì)時(shí)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02Android ListView之setEmptyView正確使用方法
這篇文章主要介紹了Android ListView之setEmptyView正確使用方法的相關(guān)資料,希望通過(guò)本文能幫助到大家使用該方法,需要的朋友可以參考下2017-09-09android webview 中l(wèi)ocalStorage無(wú)效的解決方法
這篇文章主要介紹了android webview 中l(wèi)ocalStorage無(wú)效的解決方法,本文直接給出解決方法實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-06-06Android學(xué)習(xí)筆記之ContentProvider和Uri詳解
本篇文章主要介紹了Android學(xué)習(xí)筆記之ContentProvider和Uri詳解,對(duì)于學(xué)習(xí)Android的朋友具有一定的參考價(jià)值,有需要可以可以了解一下。2016-11-11