在之前的學習中我們接觸到了一些簡單常用的控件和監(jiān)聽器尊流,但這些在實際開發(fā)中是遠遠不夠的缔莲,接下來一起來認識更高級的控件和更豐富的監(jiān)聽器澎媒,以及學會如何使用適配器搭建起數(shù)據(jù)源和視圖界面的橋梁后雷。高級控件篇第的一部分將圍繞適配器講解它是如何在某些高級控件發(fā)揮重要作用吧史。本篇控件清單:
- ListView 列表
- Spinner 下拉列表
- GridView 網(wǎng)格視圖
- ViewPager 視圖滑動切換工具
那什么是數(shù)據(jù)適配器Adapter呢?如開頭所說蕴轨,它的作用是把復雜的數(shù)據(jù)填充在指定視圖界面上港谊。常用兩種Adapter:ArrayAdapter(用于綁定單一的數(shù)據(jù),數(shù)據(jù)源是數(shù)組或集合)橙弱,SimpleAdapter(用于綁定格式復雜的數(shù)據(jù)歧寺,數(shù)據(jù)源是特定的泛型集合)。接下來將以ListView為例棘脐,看看這兩種適配器的使用方法和效果斜筐。
1.ListView 列表
ListView是最為常用的控件之一,它以列表的形式展示具體內(nèi)容蛀缝,并且能夠根據(jù)數(shù)據(jù)的長度自適應顯示顷链。下圖是一個每項數(shù)據(jù)只有一行文本的ListView效果圖,對于這類單一數(shù)據(jù)屈梁,用ArrayAdapter加載數(shù)據(jù)再合適不過嗤练,接下來一起學習一下榛了。
布局界面只需要一個ListView,設置好寬高和id就夠了潭苞。另外忽冻,還常用屬性android:divider設置列表分割線的顏色,如透明色#00000000.
在MainActivity用id找到布局中的ListView之后此疹,就是加載適配器的過程了:
可以看到使用過程無非三個步驟:數(shù)據(jù)源準備->適配器加載數(shù)據(jù)源->控件加載適配器僧诚,在關鍵的第二步對ArrayAdapter初始化中,提供的三個參數(shù)完成了在哪里顯示蝗碎、每一項數(shù)據(jù)如何顯示(這里直接使用安卓提供好一個布局)湖笨、顯示哪些數(shù)據(jù)及有多少項這些任務,再set到ListView上蹦骑,就實現(xiàn)了一開始看到的界面效果慈省。所以ListView只負責加載和管理視圖,其他顯示內(nèi)容都是交給Adapter去做的眠菇。
當然ListView的每一項Item都是可以被監(jiān)聽的边败,監(jiān)聽器是OnItemClickListener,其中返回的參數(shù)position表示被點擊的某項在整個List中的位置捎废,從0起算笑窜,這樣就能用ListView的getItemAtPosition()方法獲取到被點擊項的內(nèi)容:
當點擊第一項“wifi”時效果如下:
接下來再看一個頁面效果:
在這個ListView能看到每個Item不再是簡單的一行,有文字也有圖片登疗,這種格式復雜的數(shù)據(jù)就要用到SimpleAdapter了排截,還是在main.xml里準備好ListView控件,再回到MainActivity來學習如何用之前學會的三步驟來加載SimpleAdapter吧辐益!
第一步準備數(shù)據(jù)源断傲,可以看到數(shù)據(jù)源dataList是一個特定的泛型集合,這里String代表文字智政,Object代表圖片认罩,然后調(diào)用getData()初始化dataList。
每一個Map對應一項Item续捂,為了方便用for循環(huán)讓每個Item里圖標都一樣垦垂,文字內(nèi)容遞增就可以,然后添加到dataList疾忍,這樣就完成一個有20項Item的List。這里注意Map鍵值對里的鍵名床三,后面會需要一罩。
第二步適配器加載數(shù)據(jù)源,在此之前撇簿,需要給列表每一項做個布局item.xml聂渊,這個不難理解差购,因為在ArrayAdpter例子里我們直接使用系統(tǒng)提供的布局而已。注意要給出TextView和ImageView的id汉嗽,馬上就會用到欲逃。
現(xiàn)在又到了關鍵一步,SimpleAdapter初始化比較復雜饼暑,需要用到五個參數(shù)稳析,前三個容易理解,后兩個就是之前需要留心的兩個要點弓叛。這一步實現(xiàn)了控件與數(shù)據(jù)的一一綁定彰居。最后一步加載適配器就大功告成了!
現(xiàn)在再介紹ListView上常用的監(jiān)聽器OnScrollListener撰筷,用于監(jiān)聽滾動變化陈惰,當用戶拉到列表最底下的時候可幫助視圖在滾動中加載數(shù)據(jù)。現(xiàn)在為列表設置監(jiān)聽器listView.setOnScrollListener(this)毕籽,并實現(xiàn)onScrollStateChanged ()抬闯、onScroll()方法。
這里重寫第一個方法关筒,能看到事件會返回一個scrollState溶握,它有三個狀態(tài)值,下圖打印出詳細描述平委。因為需要在視圖一直滑動到底端給出新的Item奈虾,為dataList增添新的map之后,要用到adpter非常關鍵的方法notifyDataSetChanged()通知適配器數(shù)據(jù)發(fā)生了變化要重新加載數(shù)據(jù)廉赔,這再次印證之前所說數(shù)據(jù)的顯示是適配器的工作而不是列表肉微。
效果如下,可以看到當用戶看完20項繼續(xù)向下拖時就會有源源不斷的新內(nèi)容更新上來蜡塌。
學完這兩個常用適配器使用和適用情況之后碉纳,對比可看出ArrayAdapter使用起來明顯簡單許多,思考一個問題馏艾,ArrayAdapter的第二個參數(shù)如果不用系統(tǒng)提供的列表項布局而是自定義布局劳曹,是否也能做到圖文并存的效果呢?答案是肯定的琅摩,只不過需要自定義一個適配器繼承ArrayAdapter并重寫一些方法了铁孵。下面就來學習如何定制一個ListView界面吧!
這次做一個更好看的界面房资,準備好小動物的圖片就可以開始大展身手了蜕劝!
回憶一下實例化一個ArrayAdapter時需要的三個參數(shù),其中列表項布局以及適配器的適配類型都是要重新考慮的。那么先就從這開始準備吧岖沛!
每個Item都是由左邊一張圖片和右邊一行文本組成的暑始,下面代碼中需要解釋的是使用tools:的屬性在我們預覽能看到效果但不會出現(xiàn)在運行后的布局,方便我們提前看效果又不至于影響后續(xù)工作婴削。
接著需要準備一個實體類Animal作為適配器的適配類型廊镜,這個類里提供動物圖片和名稱兩個屬性、用來初始化屬性的構(gòu)造方法以及對應的get方法即可唉俗。
然后到了關鍵一步嗤朴,創(chuàng)建一個自定義的適配器且繼承ArrayAdapter,重寫父類一組含三個參數(shù)的構(gòu)造函數(shù)互躬,并將列表項子布局的id保存下來播赁。接著重寫getView()方法,先用getItem(position)得到當前Item項的Animal實例吼渡,再用LayoutInflater系列方法把子布局傳入當前布局得到一個View容为,接著調(diào)用這個View的findViewById()找到ImageView和TextView實例,這樣就可以把從當前項對象get的內(nèi)容設置到這兩個控件里去顯示圖片和文字了寺酪。
一切準備就緒之后坎背,后面的步驟基本信手拈來了,相信下面這段代碼你一定沒問題了寄雀。
點擊某個Item也會有響應:
這里對getView()多提幾句得滤,如果我們只是用上面幾行代碼來運行ListView的話效率會非常低,因為每次為了要顯示每個子項去調(diào)用getView()方法后都會將布局重新加載一遍盒犹,如果能將顯示過的Item View緩存起來懂更,以后出現(xiàn)直接復用就能達到提升ListView運行效率的效果了。優(yōu)化后代碼如下:
以下是源代碼:
public View getView(int position, View convertView, ViewGroup parent) {
Animal animal=getItem(position);
View view;
ViewHolder viewHolder;
if(convertView==null){
view=LayoutInflater.from(getContext()).inflate(resourceId, null);
viewHolder=new ViewHolder();
viewHolder.imageView= (ImageView) view.findViewById(R.id.animal_image);
viewHolder.textView= (TextView) view.findViewById(R.id.animal_name);
view.setTag(viewHolder);
}else{
view=convertView;
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.textView.setText(animal.getAnimalName());
viewHolder.imageView.setImageResource(animal.getImageId());
return view;
}
class ViewHolder{
ImageView imageView;
TextView textView;
}
}
到此學了這么多急膀,相信你對適配器可以熟練使用了吧沮协!只要三步就搞定。想必在其他控件上應用適配器也很容易了卓嫂,下面快來再認識兩個高級控件慷暂。
2.Spinner 下拉列表
與ListView類似的,每個下拉列表項對應一個Item晨雳,列表項內(nèi)容一般是文字行瑞,用ArrayAdapter就能做到,觸類旁通餐禁,相信做一個下圖所示的下拉列表已經(jīng)難不倒你了血久!
選擇系統(tǒng)提供的一個布局作為Spinnner的菜單樣式,注意是設置在適配器上帮非,這里給Spinner安裝監(jiān)聽器是OnItemSelectListener氧吐,用適配器和列表都可以定位到某Item绷旗,完成后效果如下:
3.GridView 網(wǎng)格視圖
從名字中能看出來GridView的特點,它使得每個Item以網(wǎng)格的形式展現(xiàn)副砍,除此之外使用方式和ListView非常相似。下面準備用SimpleAdapter做一個這樣的Demo:
GirdView本身還有些常用的屬性: android:verticalSpacing(兩列之間的間距)庄岖,android:horizontalSpacing(兩行之間的間距)豁翎, android:numColumns(每行顯示多少列,選值為auto_fit表示自動適應展示幾列)隅忿。
接下來就是GridView綁定SimpleAdapter的過程了心剥,不再細說,需要強調(diào)這里把圖標和文字分別放在兩個數(shù)組中且一一對應以便能通過循環(huán)得到數(shù)據(jù)源dataList背桐。監(jiān)聽器是OnItemClickListener优烧。
最后為了界面美觀,在注冊該活動時候設置theme是Black且NoTitleBar链峭,注意被設置成android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"的活動一定繼承的是android.app包下Activity畦娄,如果是V7兼容包下的AppCompatActivity會導致程序崩潰無法打開。點擊運行來看看是不是達到上面的效果了呢弊仪?
其實除了這兩個常用Adatper熙卡,還有一些Adapter也實用,下面通過ViewPager控件再來認識一個Adapter励饵。
4.ViewPager 視圖滑動切換工具
ViewPager是android擴展包v4包中的類驳癌,這個類可以讓用戶左右切換當前的視圖(View、Fragment都可以)役听,很多APP都用到這個功能颓鲜,可見其重要程度,因此想用這點篇幅詳解ViewPager是完全不夠的典予,這里就僅僅給大家介紹用來幫助ViewPager管理View數(shù)據(jù)源的適配器PagerAdapter甜滨,感受一下風格各樣的適配器。
首先在布局里導入v4包兩個控件熙参,其中PagerTabStrip是ViewPager子標簽艳吠,包含在ViewPager里,這里用它作標題孽椰。
由于PagerAdapter是抽象類昭娩,使用時需要自定義子類。初始化時讓這個適配器獲取到兩個數(shù)據(jù)源List:頁卡List和標題List黍匾,之后重寫幾個方法更好的完善這個適配器的功能栏渺。
接著三步驟,在主活動準備好兩個List锐涯,這里用View.inflate ()方法將布局轉(zhuǎn)化成View對象磕诊,數(shù)據(jù)加載到自定義適配器上,adapter加載到ViewPager即可,又給ViewPager設置監(jiān)聽器OnPageChangeListener監(jiān)聽頁卡是否發(fā)生變化霎终。另外滞磺,我們還獲取到控件PagerTabStrip去給標題做些美化工作。
最后效果如圖莱褒,手指左右滑動就可以實現(xiàn)頁面切換了击困。
其實所有這些Adapter都是從父類BaseAdapter擴展而來的,也就是說我們也可以根據(jù)自己的需要自定義一個Adapter繼承BaseAdapter广凸,然后具體實現(xiàn)下面4個方法:
由于adapter中含有要顯示的數(shù)據(jù)集合阅茶,數(shù)據(jù)集合中元素個數(shù)即可被展示的View個數(shù),每個數(shù)據(jù)的獲取谅海、每個Item View的樣式都由adapter控制脸哀,每個position位置上數(shù)據(jù)都綁定到Item View上,這樣數(shù)據(jù)和視圖也就結(jié)合在一起了扭吁。由于篇幅原因不在這里接著具體展開撞蜂,后續(xù)再深入探究。
本篇先到這里侥袜,下一篇還有更多有趣的高級控件等我們學習~