在之前的學習中我們接觸到了一些簡單常用的控制元件和監聽器,但這些在實際開發中是遠遠不夠的,接下來一起來認識更高階的控制元件和更豐富的監聽器,以及學會如何使用介面卡搭建起資料來源和檢視介面的橋樑。高階控制元件篇第的一部分將圍繞介面卡講解它是如何在某些高階控制元件發揮重要作用。本篇控制元件清單:
- ListView 列表
- Spinner 下拉選單
- GridView 網格檢視
- ViewPager 檢視滑動切換工具
那什麼是資料介面卡Adapter呢?如開頭所說,它的作用是把複雜的資料填充在指定檢視介面上。常用兩種Adapter: ArrayAdapter(用於繫結單一的資料,資料來源是陣列或集合)SimpleAdapter(用於繫結格式複雜的資料,資料來源是特定的泛型集合)。接下來將以ListView為例,看看這兩種介面卡的使用方法和效果。
1.ListView 列表
ListView是最為常用的控制元件之一,它以列表的形式展示具體內容,並且能夠根據資料的長度自適應顯示。下圖是一個每項資料只有一行文字的ListView效果圖,對於這類單一資料,用ArrayAdapter載入資料再合適不過,接下來一起學習一下。
佈局介面只需要一個ListView,設定好寬高和id就夠了。另外,還常用屬性android:divider設定列表分割線的顏色,如透明色 #00000000.
在MainActivity用id找到佈局中的ListView之後,就是載入介面卡的過程了:
可以看到使用過程無非三個步驟:資料來源準備->介面卡載入資料來源->控制元件載入介面卡,在關鍵的第二步對ArrayAdapter初始化中,提供的三個引數完成了在哪裡顯示、每一項資料如何顯示(這裡直接使用安卓提供好一個佈局)、顯示哪些資料及有多少項這些任務,再set到ListView上,就實現了一開始看到的介面效果。所以ListView只負責載入和管理檢視,其他顯示內容都是交給Adapter去做的。
當然ListView的每一項Item都是可以被監聽的,監聽器是OnItemClickListener,其中返回的引數position表示被點選的某項在整個List中的位置,從0起算,這樣就能用ListView的getItemAtPosition()方法獲取到被點選項的內容:
當點選第一項“wifi”時效果如下:
接下來再看一個頁面效果:
在這個ListView能看到每個Item不再是簡單的一行,有文字也有圖片,這種格式複雜的資料就要用到SimpleAdapter了,還是在main.xml裡準備好ListView控制元件,再回到MainActivity來學習如何用之前學會的三步驟來載入SimpleAdapter吧!
第一步準備資料來源,可以看到資料來源dataList是一個特定的泛型集合,這裡String代表文字,Object代表圖片,然後呼叫getData()初始化dataList。
每一個Map對應一項Item,為了方便用for迴圈讓每個Item裡圖示都一樣,文字內容遞增就可以,然後新增到dataList,這樣就完成一個有20項Item的List。這裡注意Map鍵值對裡的鍵名,後面會需要。
第二步介面卡載入資料來源,在此之前,需要給列表每一項做個佈局item.xml,這個不難理解,因為在ArrayAdpter例子裡我們直接使用系統提供的佈局而已。注意要給出TextView和ImageView的id,馬上就會用到。
現在又到了關鍵一步,SimpleAdapter初始化比較複雜,需要用到五個引數,前三個容易理解,後兩個就是之前需要留心的兩個要點。這一步實現了控制元件與資料的一一繫結。最後一步載入介面卡就大功告成了!
現在再介紹ListView上常用的監聽器OnScrollListener,用於監聽滾動變化,當使用者拉到列表最底下的時候可幫助檢視在滾動中載入資料。現在為列表設定監聽器listView.setOnScrollListener(this),並實現onScrollStateChanged ()、onScroll()方法。
這裡重寫第一個方法,能看到事件會返回一個scrollState,它有三個狀態值,下圖列印出詳細描述。因為需要在檢視一直滑動到底端給出新的Item,為dataList增添新的map之後,要用到adpter非常關鍵的方法**notifyDataSetChanged()**通知介面卡資料發生了變化要重新載入資料,這再次印證之前所說資料的顯示是介面卡的工作而不是列表。
效果如下,可以看到當使用者看完20項繼續向下拖時就會有源源不斷的新內容更新上來。
學完這兩個常用介面卡使用和適用情況之後,對比可看出ArrayAdapter使用起來明顯簡單許多,思考一個問題,ArrayAdapter的第二個引數如果不用系統提供的列表項佈局而是自定義佈局,是否也能做到圖文並存的效果呢?答案是肯定的,只不過需要自定義一個介面卡繼承ArrayAdapter並重寫一些方法了。下面就來學習如何定製一個ListView介面吧!
這次做一個更好看的介面,準備好小動物的圖片就可以開始大展身手了!
回憶一下例項化一個ArrayAdapter時需要的三個引數,其中列表項佈局以及介面卡的適配型別都是要重新考慮的。那麼先就從這開始準備吧!
每個Item都是由左邊一張圖片和右邊一行文字組成的,下面程式碼中需要解釋的是使用 tools: 的屬性在我們預覽能看到效果但不會出現在執行後的佈局,方便我們提前看效果又不至於影響後續工作。
接著需要準備一個實體類Animal作為介面卡的適配型別,這個類裡提供動物圖片和名稱兩個屬性、用來初始化屬性的構造方法以及對應的get方法即可。
然後到了關鍵一步,建立一個自定義的介面卡且繼承ArrayAdapter,重寫父類一組含三個引數的建構函式,並將列表項子佈局的id儲存下來。接著重寫getView()方法,先用getItem(position)得到當前Item項的Animal例項,再用LayoutInflater系列方法把子佈局傳入當前佈局得到一個View,接著呼叫這個View的findViewById()找到ImageView和TextView例項,這樣就可以把從當前項物件get的內容設定到這兩個控制元件裡去顯示圖片和文字了。
一切準備就緒之後,後面的步驟基本信手拈來了,相信下面這段程式碼你一定沒問題了。
點選某個Item也會有響應:
這裡對getView()多提幾句,如果我們只是用上面幾行程式碼來執行ListView的話效率會非常低,因為每次為了要顯示每個子項去呼叫getView()方法後都會將佈局重新載入一遍,如果能將顯示過的Item View快取起來,以後出現直接複用就能達到提升ListView執行效率的效果了。優化後程式碼如下:
以下是原始碼:
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,列表項內容一般是文字,用ArrayAdapter就能做到,觸類旁通,相信做一個下圖所示的下拉選單已經難不倒你了!
選擇系統提供的一個佈局作為Spinnner的選單樣式,注意是設定在介面卡上,這裡給Spinner安裝監聽器是OnItemSelectListener,用介面卡和列表都可以定位到某Item,完成後效果如下:
3.GridView 網格檢視
從名字中能看出來GridView的特點,它使得每個Item以網格的形式展現,除此之外使用方式和ListView非常相似。下面準備用SimpleAdapter做一個這樣的Demo:
GirdView本身還有些常用的屬性: android:verticalSpacing(兩列之間的間距),android:horizontalSpacing(兩行之間的間距), android:numColumns(每行顯示多少列,選值為auto_fit表示自動適應展示幾列)。
接下來就是GridView繫結SimpleAdapter的過程了,不再細說,需要強調這裡把圖示和文字分別放在兩個陣列中且一一對應以便能通過迴圈得到資料來源dataList。監聽器是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資料來源的介面卡PagerAdapter,感受一下風格各樣的介面卡。
首先在佈局裡匯入v4包兩個控制元件,其中PagerTabStrip是ViewPager子標籤,包含在ViewPager裡,這裡用它作標題。
由於PagerAdapter是抽象類,使用時需要自定義子類。初始化時讓這個介面卡獲取到兩個資料來源List:頁卡List和標題List,之後重寫幾個方法更好的完善這個介面卡的功能。
接著三步驟,在主活動準備好兩個List,這裡用View.inflate ()方法將佈局轉化成View物件,資料載入到自定義介面卡上,adapter載入到ViewPager即可,又給ViewPager設定監聽器OnPageChangeListener監聽頁卡是否發生變化。另外,我們還獲取到控制元件PagerTabStrip去給標題做些美化工作。
最後效果如圖,手指左右滑動就可以實現頁面切換了。
其實所有這些Adapter都是從父類BaseAdapter擴充套件而來的,也就是說我們也可以根據自己的需要自定義一個Adapter繼承BaseAdapter,然後具體實現下面4個方法:
由於adapter中含有要顯示的資料集合,資料集合中元素個數即可被展示的View個數,每個資料的獲取、每個Item View的樣式都由adapter控制,每個position位置上資料都繫結到Item View上,這樣資料和檢視也就結合在一起了。由於篇幅原因不在這裡接著具體展開,後續再深入探究。
本篇先到這裡,下一篇還有更多有趣的高階控制元件等我們學習~