Aandroid在ViewPager中添加ListView,aandroidviewpager
最近的項目中碰到一個需要橫豎都能滑動的頁面效果,如同手機qq的好友菜單介面(如),可以通過選項卡來選擇需要的介面,也可以通過螢幕手指的滑動來實現,而每一個分頁面的內容對應的是一個可以上下滑動的ListView,所以最後結合起來的效果是,在頁面中可以上下滑動,在各個分頁之間可以左右滑動。
對於這個效果有兩種方案,一種是通過TabActivitiy來實現,將選項卡設定為TabActibitiy的標誌,通過將需要的分頁載入到Tab的各個標誌中去,但是這種方法,由於每一次切換選項卡的時候都會重新去建立一個新Activity的執行個體,所以當介面很多時切換會很遲鈍,同時這種方法不能實現螢幕手指滑動來切換介面。
另外一種就是今天要講的,在ViewPager中添加ListView。
先說ViewPager,ViewPager是google官方提供的一個相容低版本android裝置的軟體包,
ViewPager的主要功能是使視圖左右滑動,單純ViewPaager添加靜態頁面的教程可以在網上搜到,這裡只是簡單介紹:(看不太懂的請參考其他ViewPager教程)
1.在布局檔案中加入組件
<android.support.v4.view.ViewPager android:id="@+id/heroPager" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
和android的其他組件一樣,這裡只需要聲明一個組件,並指定它的基本屬性。
2.載入要顯示的選項卡
<pre name="code" class="java" style="color: rgb(70, 70, 70); font-size: 14px; line-height: 21px; text-indent: 28px;"><span style="font-family: 宋體;">//這個方法從viewPager中移動當前的view。</span>
public void destroyItem(View container, int position, Object object){} //這個方法返回一個對象,該對象表明PagerAapter選擇哪個對象放在當前的ViewPager中。
public Object instantiateItem(View container, int position){}
//返回當前分頁數。
public int getCount() { return mListViews.size(); }
//該方法判斷是否由該對象產生介面。
public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; }
4.為viewPager添加適配器:
viewPager.setAdapter(new HeroPagerAdapter(viewList));
好了,以上是在ViewPager中添加常規的靜態介面的方法,對於listview,是需要設定適配器的,listview本身也是一個動態組件,下面將介紹如何在ViewPager中添加動態listview。
同樣的,要先在布局檔案中加入ViewPager組件,同以上步驟1.
第二步,也是最重要的一步。
前幾個操作和以上是一樣的,先聲明一個LayoutInflater對象:
LayoutInflater inflater = getLayoutInflater();
擷取viewPager組件:
viewPager = (ViewPager) findViewById(R.id.heroPager);
建立一個list對象:
viewList = new ArrayList<View>();
這裡,我曾經試過如下方法,都是錯誤的,希望大家引起注意:
直接通過強制類型轉換,將View對象轉換為ListView對象:
ListView view1 = (ListView) inflater.inflate(R.layout.hero_list, null);
這個方法編譯可以通過,但是在運行時系統會報出一個類型轉換的錯誤!
直接通過findViewbyId方法通過listview的組件ID來擷取listview對象:
ListView listView1 = (ListView)findViewById(R.id.heroList);
這個方法也是編譯時間可以通過,運行時在這一步不會出現問題,但是當下面為listview添加SimpleAdpater適配器的時候,會拋出一個null 指標異常,偵錯模式到這一步時,會觀察到通過findViewbyId方法得到的listview是一個Null 物件。
原來findviewById是View這個類中的方法,預設調用時其實應該是:
this.findviewById();
由於代碼中的R.id.herolist這個listview的聲明並不在當前的viewPager所在的xml布局中,所以直接通過findviewById方法是不能得到該listview的執行個體的。
既然知道了findviewById()原理,那麼就好辦了!直接先通過LayoutInflater對象來執行個體化listview所在的布局,然後通過這個view的findviewById方法來擷取listview的執行個體。
View view1 = inflater.inflate(R.layout.hero_list, null);
View view2 = inflater.inflate(R.layout.hero_list, null);
ListView listview1 = view1.findViewById(R.id.heroList);
ListView listview2 = view1.findViewById(R.id.heroList);
注意view對應的布局是hero_list,listview對應的布局是herolist,兩者不一樣。
也可以簡化如下:
ListView listView1 = (ListView) (inflater.inflate(R.layout.hero_list, null)).findViewById(R.id.heroList);
ListView listView2 = (ListView) (inflater.inflate(R.layout.hero_list, null)).findViewById(R.id.heroList);
剩下的步驟3和步驟4和上文中的一樣,重寫PagerAdapter類並添加適配器。
不過不要忘了給每一個listview都添加一個適配器,listview添加SimpleAdapter的步驟我相信大家已經很熟悉了,這裡就不再詳述了,直接上代碼:
SimpleAdapter simpleAdapter_Wu = new SimpleAdapter(this, herolist_wu, R.layout.hero_info, new String[]{"heroImage", "heroName"}, new int[]{R.id.heroImage, R.id.heroName}); SimpleAdapter simpleAdapter_Shu = new SimpleAdapter(this, herolist_shu, R.layout.hero_info, new String[]{"heroImage", "heroName"}, new int[]{R.id.heroImage, R.id.heroName}); listView1.setAdapter(simpleAdapter_Wu); listView2.setAdapter(simpleAdapter_Shu);
到這裡,就和以上的不一樣了!!
LayoutInflater對象的inflater方法只能執行個體化一個view對象,由於android中不能通過直接將一個xml布局聲明為一個Listview,所以就不能直接通過inflater方法來執行個體listview對象。
這樣就成功的將兩個listview添加到ViewPager中了,以下是,(水平有限,不知道怎麼做動態)
在剛開始做這個的時候,也在網上搜尋過關於在viewPager中添加listview的方法,都沒有找到相關的教程,自己摸索了一天終於把它做出來了,這裡和大家分享一下,也希望能給需要類似效果的朋友一些協助。