天天看點

android ListView加HeadView左右切換圖檔(類似各大新聞用戶端)

         我簡單的介紹下實作方法:其實就是listview addheaderview.隻不過這個view是一個可以切換圖檔的view,至于這個view怎麼做,就要根據自己的喜愛了,實作有多種方法,下面我簡單介紹一下.

第一種:viewflipper+gesturedetector

主布局就是一個listview,這裡就不介紹了,我介紹下切換圖檔布局

head_iamge.xml

這裡我就添加一系列切換點,至于顯示新聞标題,透明效果等等,大家可以自己布局,方法同理,不難實作.

接下來我們看動畫布局.

push_left_in.xml

push_left_out.xml

push_right_in.xml

push_right_out.xml

我簡單介紹下這些布局:

push_left_in:左邊進入,則要進入的view初始位置在-100%p位置,終止位置在0,而push_left_out:左邊出來,則此時view的位置在0,而終止位置在-100%p.

右進右出同理,至于alpha漸變,很簡單,動畫就說道這裡,相信了解動畫的同學們不用看就ok了.

下面重點是如何實作.

代碼:

mainactivity.java

效果圖:

android ListView加HeadView左右切換圖檔(類似各大新聞用戶端)
android ListView加HeadView左右切換圖檔(類似各大新聞用戶端)

你可以手勢左右滑動圖檔切換,由于我們加入了動畫,則在切換圖檔效果會比較人性,這一點比較不錯.另外一點,我開啟了timer,讓它自己切換,感覺這點比較不錯,可惜好多應用都沒有這麼搞,總之實作就行了,我們開發人員嘛,就是開發别人想出來的東西,感慨程式員苦逼...

如果你按照上訴操作的話會有幾個問題:1,我移動圖檔下面的item圖檔也會切換,2,我在滑動切換圖檔的時候偶爾也會執行onclick事件,這兩點bug嚴重不允許,為之我也煞費神經細胞啊,沒辦法因為基礎不好,對觸摸種種事件還是搞不明白,有時間了還得在看看研究研究,扯遠了,下面我說下解決方法:

第一:我隻讓listview的第一項監聽手勢操作,其他的不執行.

方法很簡單,自定義一個listview.重寫其ontouchevent事件.

大家一看就明白了,我們隻對position==0進行手勢監聽,也許有人問了,其實也可以直接在mainactivity中的dispatchtouchevent分發事件中擷取點選listview的position,可是這樣不準确,我點選第0項擷取的有的是0,有的是1,原因目前不明,不過但可以肯定,這樣是能擷取listview的position的,是以就幹脆自定義吧,這樣不會出錯.這樣解決了不會滑動下面item圖檔跟着切換.

再有就是我們要把listview item的第一項 onclick事件禁止了,我們直接把這個點選事件搬到onsingletapup中,這樣就不會因為手勢操作而影響item的onclick事件了,這樣問題基本都解決了,其實我想有簡單的方法,隻要把touch事件弄懂,可惜啊...不給力啊...

效果和上面一樣.

經過多次測試,目前沒有發現問題,如有不妥我會給出提示.

第二種方法:viewpager.

viewpager效果相比大家都熟知,是以我就省略顯示的那部分,方法和上面一樣,隻是顯示用的是viewpager而已.

但是這裡面存在一個嚴重的問題:viewpager和listview共存的問題,二者都有自身的滑動事件,必然要産生沖突。viewpager操作起來相當的不靈敏.

這裡我重點說一下解決辦法:我們需要自定義listview,對其攔截事件進行處理.另外我們要用手勢,判斷上下左右滑動.

mylistview.java

這樣viewpager滑動就不會受listview幹擾了,listview上下也可以滑動.

由于自己對事件分發不是很了解,是以不過多介紹,想知道的話,自己慢慢研究吧,我這裡隻是提供一個解決方法,我也在學習中...

其他部分不難,這裡就不講解了.

感覺還是第二種方法好,這也是為什麼那麼多用戶端都是這麼搞,不過各有千秋,因人而異.

對第二種方法實作簡單講解:

我們的目的是:我們左右滑動viewpager的時候listview不影響,而當viewpager上下滑動的時候可以随意滑動.

我們可以這樣做:我們把onintercepttouchevent傳回值更改為fase,那麼意味着,如果孩子存在onintercepttouchevent那麼會繼續傳遞給孩子的onintercepttouchevent...後面我們不管(此時listview失去touch事件),這個時候viewpager擷取touch事件.

這個時候viewpager就可以左右滑動(不可以上下滑動)。 如果孩子不存在onintercepttouchevent,listview執行本身ontouch.  

那麼把onintercepttouchevent傳回值更改為true.意思就是:我對touch事件進行攔截,不進行向下傳遞,直接執行自身的ontouch事件,這個時候viewpager就可以上下滑了(不可以左右滑動切換).

根據實情,那麼我們如何動态控制這個onintercepttouchevent的傳回值,這個時候我們可以借助:gesturedetector手勢來實作.

上面這個方法可以根據手勢來判斷我們手的滑動方向.而:boolean b = mgesturedetector.ontouchevent(ev);

這個值就是onscroll傳回的值.這個值是代表我們手勢mgesturedetector消費了沒,為什麼這麼說呢,因為這個和我們外界的touch分開了,就算我們在這裡消費了那麼外面該怎麼執行就怎麼執行。經過測試覺得mgesturedetector.ontouchevent(ev)這個方法就是執行手勢相應方法,然後傳回的是onscroll的傳回值.

而當我們上下滑動的時候mgesturedetector.ontouchevent(ev)傳回true,而viewpager需要上下滑動的時候隻需要将onintercepttouchevent的傳回值更改為true,左右滑動同理.

那麼這樣我們就實作了viewpager與listview滑動的沖突.

好了,就寫到這裡了,下面給一個demo,大家可以拿去看看!

http://download.csdn.net/detail/gulaer/4965682

繼續閱讀