溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

android ListView詳解

發(fā)布時(shí)間:2020-07-10 14:09:04 來(lái)源:網(wǎng)絡(luò) 閱讀:421 作者:午飯123 欄目:移動(dòng)開(kāi)發(fā)

    在android開(kāi)發(fā)中ListView是非常重要的控件。我自己也還是一個(gè)小白,把自己的學(xué)習(xí)經(jīng)驗(yàn)分享出來(lái),希望可以幫到初學(xué)Android的朋友們。這也是我第一次寫(xiě)博客,我盡量將結(jié)構(gòu)處理的好一些,也說(shuō)的易懂一些。如果寫(xiě)得不好或者有誤,請(qǐng)指正見(jiàn)諒!

    

簡(jiǎn)介

    ListView特性是批量展示結(jié)構(gòu)一樣或者相似的信息并且可以滑動(dòng)展示。ListView是一個(gè)組合控件,組合控件和普通控件的區(qū)別在于:

    普通控件:內(nèi)容和控件是一起的。
    
組合控件:內(nèi)容跟控件是分開(kāi)的。


    所以使用ListView的時(shí)候要用到適配器,那什么是適配器呢,官方文檔的解釋是控件與數(shù)據(jù)之間的一個(gè)橋梁。如果不好理解,不要糾結(jié),用多了自然就明白了。ListView作為一個(gè)整體的框架,而適配器則決定每一行上的內(nèi)容是什么:


    ListView     框架

    適配器       內(nèi)容


使用

    簡(jiǎn)單介紹過(guò)ListView之后,我們來(lái)說(shuō)下ListView的使用。


    1、在Activity的布局文件中放入Listview,注意listview的高度要是match_parent 或者是固定值,這里不建議使用wrapcontent,因?yàn)檫@樣會(huì)有requestLayout的操作,對(duì)性能有損耗。


    2、準(zhǔn)備好listview的行布局文件listview_item,作為listview每一行的顯示樣式。


    3、準(zhǔn)備listview的適配器,聲明一個(gè)類繼承BaseAdpater,實(shí)現(xiàn)四個(gè)方法:

       //這個(gè)方法決定了listview顯示內(nèi)容的行數(shù)

       public int getCount() 

       //決定listview每一行的布局以及內(nèi)容,position代表是listview上面的行號(hào)。

       public View getView(int position, View convertView, ViewGroup parent)

       注意:·listview上的每一行要顯示在界面上都必須調(diào)用getView()

             ·每一個(gè)已經(jīng)消失在屏幕上的行,重新顯示在界面都必須重新調(diào)用getView()

            ·如果getCount() 返回的結(jié)果為0的話,是不會(huì)調(diào)用getView()


    4、getView()中每一行的布局創(chuàng)建以及內(nèi)容設(shè)置

               //獲取行布局對(duì)象(通過(guò)解析行布局文件)

          LayoutInflater inflater = getLayoutInflater();//得到布局轉(zhuǎn)換器

          View layout = inflater.inflate(R.layout.list_item, null);


        //通過(guò)布局對(duì)象查找它里面控件的索引 (一定要通過(guò)行布局對(duì)象查找)很多初學(xué)者在使用ListView的時(shí)候很容易報(bào)空指針錯(cuò)誤,就是這個(gè)原因。

          TextView textView =(TextView)layout.findViewById(R.id.tv_list_item);


        //通過(guò)行號(hào)查找容器里面對(duì)應(yīng)的內(nèi)容

          String string = arrayList.get(position);


        //把內(nèi)容設(shè)置到布局對(duì)象里面的控件對(duì)象上面

          textView.setText(string);


        //返回行布局對(duì)象(而不是里面某個(gè)控件)

          return layout;

 

    5、查找Listview控件對(duì)象

        ListView listView = (ListView) findViewById(R.id.listView1);


    

    6、創(chuàng)建一個(gè)適配器對(duì)象

          MyAdapter adapter = new MyAdapter();


    7、為listview配置適配器(如果沒(méi)有配置,listview里面是沒(méi)有內(nèi)容的)

          listView.setAdapter(adapter)


    這里再說(shuō)明一下,行布局為多個(gè)控件,就是之前創(chuàng)建的listview_item,每一行都是listview_item。還要注意的是每行數(shù)據(jù)都要封裝到同一個(gè)對(duì)象當(dāng)中,比如都是將數(shù)據(jù)設(shè)置到listview_item里的textview上,這里再重申一遍,每一個(gè)控件的索引都必須通過(guò)行布局對(duì)象去查找。(否則就為null,運(yùn)行時(shí)會(huì)報(bào)空指針異常)。


優(yōu)化    

    講完ListView的使用后,講一下ListView的優(yōu)化。 

    1、復(fù)用行布局

    為什么要優(yōu)化ListView呢,因?yàn)樯厦娴膶?xiě)法,每一次getView()的時(shí)候都創(chuàng)建一個(gè)新的行布局對(duì)象,又因?yàn)锳ndroid的垃圾回收機(jī)制是不定時(shí)回收的,當(dāng)數(shù)據(jù)比較多的時(shí)候,你上下滑動(dòng),ListView就不斷的創(chuàng)建對(duì)象,輕則會(huì)造成卡頓,重則就內(nèi)存溢出了。其實(shí)我們知道,如果屏幕上可以顯示6行,我們準(zhǔn)備7個(gè)布局對(duì)象就可以。如果不明白的童鞋可以想象一下,就像戲臺(tái)上演行軍并不需要那么多人,只要讓前面走出戲臺(tái)的人再?gòu)暮竺娼由蟻?lái)就可以了。

    復(fù)用行布局:

    public View getView(int position, View convertView, ViewGroup parent) 

    {

      View layout = null;

    

      if(convertView == null)

      {

       LayoutInflater inflater = getLayoutInflater();//得到布局轉(zhuǎn)換器

          layout = inflater.inflate(R.layout.list_item, null);

      }else

      {

       layout = convertView;

      }

    return layout;

    }

    說(shuō)明: convertView用來(lái)保存已經(jīng)創(chuàng)建并且消失在界面的那個(gè)行布局對(duì)象的索引。初始為null,當(dāng)行布局對(duì)象消失的時(shí)候才有值


    2、減少查找次數(shù)

    基于復(fù)用行布局的基礎(chǔ)上,如果每一次getView(),都要再去找行布局上的控件也是很麻煩的,因?yàn)榧热皇菑?fù)用,之前肯定是已經(jīng)找過(guò)了。這里的優(yōu)化方法如下:

    聲明一個(gè)類,類里面的成員變量即為 行布局里面的 控件類型   

   a、class ViewHolder

    {

    //將行布局內(nèi)的控件申明為該類的成員變量

         ImageView p_w_picpathView;

         TextView title;

         TextView subTitle;

     }


   b、在getVIew中

        public View getView(int position, View convertView, ViewGroup parent) 

    {

      View layout = null;

      ViewHolder holder = null;

      if(convertView == null)

      {

       holder = new ViewHolder();

       LayoutInflater inflater = getLayoutInflater();//得到布局轉(zhuǎn)換器

       layout = inflater.inflate(R.layout.list_item, null);

       holder.p_w_picpathView = (ImageView) layout.findViewById(R.id.iv_list);

       holder.title = (TextView) layout.findViewById(R.id.tv_list_item);

       holder.subTitle = (TextView) layout.findViewById(R.id.tv_list_sub);

       //標(biāo)簽(口袋)

       layout.setTag(holder);

      }else

      {

       layout = convertView;

       //如果convertView不為空,得到holder,然后得到行布局內(nèi)控件的引用。

       holder = (ViewHolder) layout.getTag();

      }

    當(dāng)然ListView的優(yōu)化在實(shí)際的項(xiàng)目開(kāi)發(fā)中在數(shù)據(jù)請(qǐng)求的過(guò)程中會(huì)有一些bug,這里以后再說(shuō)明解決。


數(shù)據(jù)的更新

    //通知適配器內(nèi)容發(fā)生改變,更新界面

      adapter.notifyDataSetChanged();


lisetview 行點(diǎn)擊事件

    1、設(shè)置行點(diǎn)擊事件

    listView.setOnItemClickListener(new OnItemClickListener() {

   @Override

   public void onItemClick(AdapterView parent, View view,

     int position, long id) {

    Log.e("onItemClick", "position:" + position);

   }

  });

    2、長(zhǎng)按彈出選項(xiàng)菜單

   //為listview注冊(cè)上下文菜單

    registerForContextMenu(listView);

   //長(zhǎng)按事件

    listView.setOnItemLongClickListener(new OnItemLongClickListener() {

   @Override

    public boolean onItemLongClick(AdapterView parent, View view,

     int position, long id) {

    Log.e("onItemLongClick", "position:" + position);

    MainActivity.this.position = position;

    return false;   (返回false的時(shí)候事件還會(huì)向下傳遞,返回true就到此結(jié)束)

   }

  });

    當(dāng)然還需重寫(xiě)onCreateContextMenu和onContextItemSelected方法。listvew長(zhǎng)按彈出選項(xiàng)菜單還有另一種方法:   

    listView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {

    // @Override

    public void onCreateContextMenu(ContextMenu menu, View v,

    ContextMenuInfo menuInfo) {

    

    }

  });


總結(jié)

   好了,ListView就講到這里了,當(dāng)然要做出漂亮的listview還沒(méi)那么簡(jiǎn)單,這些可能會(huì)在后面的博客中說(shuō)道,希望這篇博客對(duì)大家有所幫助,謝謝!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI