學(xué)習(xí)筆記| AS入門(五) 高級(jí)控件篇(上)

在之前的學(xué)習(xí)中我們接觸到了一些簡(jiǎn)單常用的控件和監(jiān)聽器,但這些在實(shí)際開發(fā)中是遠(yuǎn)遠(yuǎn)不夠的,接下來一起來認(rèn)識(shí)更高級(jí)的控件和更豐富的監(jiān)聽器,以及學(xué)會(huì)如何使用適配器搭建起數(shù)據(jù)源和視圖界面的橋梁。高級(jí)控件篇第的一部分將圍繞適配器講解它是如何在某些高級(jí)控件發(fā)揮重要作用。本篇控件清單:

  • ListView 列表
  • Spinner 下拉列表
  • GridView 網(wǎng)格視圖
  • ViewPager 視圖滑動(dòng)切換工具

那什么是數(shù)據(jù)適配器Adapter呢?如開頭所說,它的作用是把復(fù)雜的數(shù)據(jù)填充在指定視圖界面上。常用兩種Adapter:ArrayAdapter(用于綁定單一的數(shù)據(jù),數(shù)據(jù)源是數(shù)組或集合),SimpleAdapter(用于綁定格式復(fù)雜的數(shù)據(jù),數(shù)據(jù)源是特定的泛型集合)。接下來將以ListView為例,看看這兩種適配器的使用方法和效果。

1.ListView 列表

ListView是最為常用的控件之一,它以列表的形式展示具體內(nèi)容,并且能夠根據(jù)數(shù)據(jù)的長(zhǎng)度自適應(yīng)顯示。下圖是一個(gè)每項(xiàng)數(shù)據(jù)只有一行文本的ListView效果圖,對(duì)于這類單一數(shù)據(jù),用ArrayAdapter加載數(shù)據(jù)再合適不過,接下來一起學(xué)習(xí)一下。

布局界面只需要一個(gè)ListView,設(shè)置好寬高和id就夠了。另外,還常用屬性android:divider設(shè)置列表分割線的顏色,如透明色#00000000.

在MainActivity用id找到布局中的ListView之后,就是加載適配器的過程了:

可以看到使用過程無非三個(gè)步驟:數(shù)據(jù)源準(zhǔn)備->適配器加載數(shù)據(jù)源->控件加載適配器,在關(guān)鍵的第二步對(duì)ArrayAdapter初始化中,提供的三個(gè)參數(shù)完成了在哪里顯示、每一項(xiàng)數(shù)據(jù)如何顯示(這里直接使用安卓提供好一個(gè)布局)、顯示哪些數(shù)據(jù)及有多少項(xiàng)這些任務(wù),再set到ListView上,就實(shí)現(xiàn)了一開始看到的界面效果。所以ListView只負(fù)責(zé)加載和管理視圖,其他顯示內(nèi)容都是交給Adapter去做的。

當(dāng)然ListView的每一項(xiàng)Item都是可以被監(jiān)聽的,監(jiān)聽器是OnItemClickListener,其中返回的參數(shù)position表示被點(diǎn)擊的某項(xiàng)在整個(gè)List中的位置,從0起算,這樣就能用ListView的getItemAtPosition()方法獲取到被點(diǎn)擊項(xiàng)的內(nèi)容:

當(dāng)點(diǎn)擊第一項(xiàng)“wifi”時(shí)效果如下:

接下來再看一個(gè)頁(yè)面效果:

在這個(gè)ListView能看到每個(gè)Item不再是簡(jiǎn)單的一行,有文字也有圖片,這種格式復(fù)雜的數(shù)據(jù)就要用到SimpleAdapter了,還是在main.xml里準(zhǔn)備好ListView控件,再回到MainActivity來學(xué)習(xí)如何用之前學(xué)會(huì)的三步驟來加載SimpleAdapter吧!

第一步準(zhǔn)備數(shù)據(jù)源,可以看到數(shù)據(jù)源dataList是一個(gè)特定的泛型集合,這里String代表文字,Object代表圖片,然后調(diào)用getData()初始化dataList。

每一個(gè)Map對(duì)應(yīng)一項(xiàng)Item,為了方便用for循環(huán)讓每個(gè)Item里圖標(biāo)都一樣,文字內(nèi)容遞增就可以,然后添加到dataList,這樣就完成一個(gè)有20項(xiàng)Item的List。這里注意Map鍵值對(duì)里的鍵名,后面會(huì)需要。

第二步適配器加載數(shù)據(jù)源,在此之前,需要給列表每一項(xiàng)做個(gè)布局item.xml,這個(gè)不難理解,因?yàn)樵贏rrayAdpter例子里我們直接使用系統(tǒng)提供的布局而已。注意要給出TextView和ImageView的id,馬上就會(huì)用到。

現(xiàn)在又到了關(guān)鍵一步,SimpleAdapter初始化比較復(fù)雜,需要用到五個(gè)參數(shù),前三個(gè)容易理解,后兩個(gè)就是之前需要留心的兩個(gè)要點(diǎn)。這一步實(shí)現(xiàn)了控件與數(shù)據(jù)的一一綁定。最后一步加載適配器就大功告成了!

現(xiàn)在再介紹ListView上常用的監(jiān)聽器OnScrollListener,用于監(jiān)聽滾動(dòng)變化,當(dāng)用戶拉到列表最底下的時(shí)候可幫助視圖在滾動(dòng)中加載數(shù)據(jù)?,F(xiàn)在為列表設(shè)置監(jiān)聽器listView.setOnScrollListener(this),并實(shí)現(xiàn)onScrollStateChanged ()、onScroll()方法。

這里重寫第一個(gè)方法,能看到事件會(huì)返回一個(gè)scrollState,它有三個(gè)狀態(tài)值,下圖打印出詳細(xì)描述。因?yàn)樾枰谝晥D一直滑動(dòng)到底端給出新的Item,為dataList增添新的map之后,要用到adpter非常關(guān)鍵的方法notifyDataSetChanged()通知適配器數(shù)據(jù)發(fā)生了變化要重新加載數(shù)據(jù),這再次印證之前所說數(shù)據(jù)的顯示是適配器的工作而不是列表。

效果如下,可以看到當(dāng)用戶看完20項(xiàng)繼續(xù)向下拖時(shí)就會(huì)有源源不斷的新內(nèi)容更新上來。

學(xué)完這兩個(gè)常用適配器使用和適用情況之后,對(duì)比可看出ArrayAdapter使用起來明顯簡(jiǎn)單許多,思考一個(gè)問題,ArrayAdapter的第二個(gè)參數(shù)如果不用系統(tǒng)提供的列表項(xiàng)布局而是自定義布局,是否也能做到圖文并存的效果呢?答案是肯定的,只不過需要自定義一個(gè)適配器繼承ArrayAdapter并重寫一些方法了。下面就來學(xué)習(xí)如何定制一個(gè)ListView界面吧!

這次做一個(gè)更好看的界面,準(zhǔn)備好小動(dòng)物的圖片就可以開始大展身手了!

回憶一下實(shí)例化一個(gè)ArrayAdapter時(shí)需要的三個(gè)參數(shù),其中列表項(xiàng)布局以及適配器的適配類型都是要重新考慮的。那么先就從這開始準(zhǔn)備吧!

每個(gè)Item都是由左邊一張圖片和右邊一行文本組成的,下面代碼中需要解釋的是使用tools:的屬性在我們預(yù)覽能看到效果但不會(huì)出現(xiàn)在運(yùn)行后的布局,方便我們提前看效果又不至于影響后續(xù)工作。

接著需要準(zhǔn)備一個(gè)實(shí)體類Animal作為適配器的適配類型,這個(gè)類里提供動(dòng)物圖片和名稱兩個(gè)屬性、用來初始化屬性的構(gòu)造方法以及對(duì)應(yīng)的get方法即可。

然后到了關(guān)鍵一步,創(chuàng)建一個(gè)自定義的適配器且繼承ArrayAdapter,重寫父類一組含三個(gè)參數(shù)的構(gòu)造函數(shù),并將列表項(xiàng)子布局的id保存下來。接著重寫getView()方法,先用getItem(position)得到當(dāng)前Item項(xiàng)的Animal實(shí)例,再用LayoutInflater系列方法把子布局傳入當(dāng)前布局得到一個(gè)View,接著調(diào)用這個(gè)View的findViewById()找到ImageView和TextView實(shí)例,這樣就可以把從當(dāng)前項(xiàng)對(duì)象get的內(nèi)容設(shè)置到這兩個(gè)控件里去顯示圖片和文字了。

一切準(zhǔn)備就緒之后,后面的步驟基本信手拈來了,相信下面這段代碼你一定沒問題了。

點(diǎn)擊某個(gè)Item也會(huì)有響應(yīng):

這里對(duì)getView()多提幾句,如果我們只是用上面幾行代碼來運(yùn)行ListView的話效率會(huì)非常低,因?yàn)槊看螢榱艘@示每個(gè)子項(xiàng)去調(diào)用getView()方法后都會(huì)將布局重新加載一遍,如果能將顯示過的Item View緩存起來,以后出現(xiàn)直接復(fù)用就能達(dá)到提升ListView運(yùn)行效率的效果了。優(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;
    }
}

到此學(xué)了這么多,相信你對(duì)適配器可以熟練使用了吧!只要三步就搞定。想必在其他控件上應(yīng)用適配器也很容易了,下面快來再認(rèn)識(shí)兩個(gè)高級(jí)控件。

2.Spinner 下拉列表

與ListView類似的,每個(gè)下拉列表項(xiàng)對(duì)應(yīng)一個(gè)Item,列表項(xiàng)內(nèi)容一般是文字,用ArrayAdapter就能做到,觸類旁通,相信做一個(gè)下圖所示的下拉列表已經(jīng)難不倒你了!

選擇系統(tǒng)提供的一個(gè)布局作為Spinnner的菜單樣式,注意是設(shè)置在適配器上,這里給Spinner安裝監(jiān)聽器是OnItemSelectListener,用適配器和列表都可以定位到某Item,完成后效果如下:

3.GridView 網(wǎng)格視圖

從名字中能看出來GridView的特點(diǎn),它使得每個(gè)Item以網(wǎng)格的形式展現(xiàn),除此之外使用方式和ListView非常相似。下面準(zhǔn)備用SimpleAdapter做一個(gè)這樣的Demo:

GirdView本身還有些常用的屬性: android:verticalSpacing(兩列之間的間距),android:horizontalSpacing(兩行之間的間距), android:numColumns(每行顯示多少列,選值為auto_fit表示自動(dòng)適應(yīng)展示幾列)。

接下來就是GridView綁定SimpleAdapter的過程了,不再細(xì)說,需要強(qiáng)調(diào)這里把圖標(biāo)和文字分別放在兩個(gè)數(shù)組中且一一對(duì)應(yīng)以便能通過循環(huán)得到數(shù)據(jù)源dataList。監(jiān)聽器是OnItemClickListener。

最后為了界面美觀,在注冊(cè)該活動(dòng)時(shí)候設(shè)置theme是Black且NoTitleBar,注意被設(shè)置成android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"的活動(dòng)一定繼承的是android.app包下Activity,如果是V7兼容包下的AppCompatActivity會(huì)導(dǎo)致程序崩潰無法打開。點(diǎn)擊運(yùn)行來看看是不是達(dá)到上面的效果了呢?

其實(shí)除了這兩個(gè)常用Adatper,還有一些Adapter也實(shí)用,下面通過ViewPager控件再來認(rèn)識(shí)一個(gè)Adapter。

4.ViewPager 視圖滑動(dòng)切換工具

ViewPager是android擴(kuò)展包v4包中的類,這個(gè)類可以讓用戶左右切換當(dāng)前的視圖(View、Fragment都可以),很多APP都用到這個(gè)功能,可見其重要程度,因此想用這點(diǎn)篇幅詳解ViewPager是完全不夠的,這里就僅僅給大家介紹用來幫助ViewPager管理View數(shù)據(jù)源的適配器PagerAdapter,感受一下風(fēng)格各樣的適配器。

首先在布局里導(dǎo)入v4包兩個(gè)控件,其中PagerTabStrip是ViewPager子標(biāo)簽,包含在ViewPager里,這里用它作標(biāo)題。

由于PagerAdapter是抽象類,使用時(shí)需要自定義子類。初始化時(shí)讓這個(gè)適配器獲取到兩個(gè)數(shù)據(jù)源List:頁(yè)卡List和標(biāo)題List,之后重寫幾個(gè)方法更好的完善這個(gè)適配器的功能。

接著三步驟,在主活動(dòng)準(zhǔn)備好兩個(gè)List,這里用View.inflate ()方法將布局轉(zhuǎn)化成View對(duì)象,數(shù)據(jù)加載到自定義適配器上,adapter加載到ViewPager即可,又給ViewPager設(shè)置監(jiān)聽器OnPageChangeListener監(jiān)聽頁(yè)卡是否發(fā)生變化。另外,我們還獲取到控件PagerTabStrip去給標(biāo)題做些美化工作。

最后效果如圖,手指左右滑動(dòng)就可以實(shí)現(xiàn)頁(yè)面切換了。

其實(shí)所有這些Adapter都是從父類BaseAdapter擴(kuò)展而來的,也就是說我們也可以根據(jù)自己的需要自定義一個(gè)Adapter繼承BaseAdapter,然后具體實(shí)現(xiàn)下面4個(gè)方法:

由于adapter中含有要顯示的數(shù)據(jù)集合,數(shù)據(jù)集合中元素個(gè)數(shù)即可被展示的View個(gè)數(shù),每個(gè)數(shù)據(jù)的獲取、每個(gè)Item View的樣式都由adapter控制,每個(gè)position位置上數(shù)據(jù)都綁定到Item View上,這樣數(shù)據(jù)和視圖也就結(jié)合在一起了。由于篇幅原因不在這里接著具體展開,后續(xù)再深入探究。

本篇先到這里,下一篇還有更多有趣的高級(jí)控件等我們學(xué)習(xí)~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,001評(píng)論 25 709
  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點(diǎn)贊按鈕進(jìn)度條TabLayout圖標(biāo)下拉刷新...
    皇小弟閱讀 47,149評(píng)論 22 665
  • 【今日話題】 如果你被很多人告知這輩子都沒有成功的可能了,你會(huì)怎樣應(yīng)對(duì)接下來的生活?(話題來自貓友付華...
    靜亦境閱讀 178評(píng)論 2 5
  • 午后,窗外陽光正好,風(fēng)輕輕。 屋內(nèi)安靜的只有音樂環(huán)繞的聲音,泡一盞清茶,寂靜處別有一番天地,感覺真好! 寂靜處總能...
    力華閱讀 332評(píng)論 0 0
  • 還是做朋友吧。 簡(jiǎn)單的一句話,道出一段不簡(jiǎn)單的故事。 昨夜下了一場(chǎng)雨,空氣中稍帶寒氣,風(fēng)是冷的,吹得人不禁打了個(gè)寒...
    茶鯉鯉閱讀 403評(píng)論 0 0

友情鏈接更多精彩內(nèi)容