深入淺出ListView

1 簡單使用ListView:

在布局文件中添加ListView控件
通過適配器將數(shù)據(jù)傳遞給ListView:

private String[] data={"zhangsan","lisi","wangwu","dengdeng"};
ArrayAdapter adapter=new ArrayAdapter (MainActivity.this,
               android.R.layout.simple_list_item_1, data);
ListView listView=(ListView)findViewById(R.id.list_view);
listView.setAdapter(adapter);

其中android.R.layout.simple_list_item_1是為ListView指定的子項布局的id

2 定制ListView界面

通俗的說:將兩種原料(容器中裝的數(shù)據(jù)集和ListView的子項的布局文件)在加工器(適配器Adapter)的加工下一一匹配(布局文件中控件要顯示的內(nèi)容和數(shù)據(jù)集中的各個數(shù)據(jù)項一一對應(yīng))澜薄。

本例中是將水果和對應(yīng)的名稱作為數(shù)據(jù)顯示在ListView中

2.1 數(shù)據(jù)集

自定義一個類暖侨,將要顯示的數(shù)據(jù)作為對象屬性封裝在類中

public class Fruit {
   private String name;
   private int imageId;
   public Fruit(String name, int imageId) {
       this.name = name;
       this.imageId = imageId;
   }
   public String getName() {
       return name;
   }
   public int getimageId() {
       return imageId;
   }
}

2.2 子項布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="horizontal"
   android:layout_width="match_parent"
   android:layout_height="match_parent">
   <ImageView
   android:id="@+id/fruit_image"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content" />
   <TextView
       android:id="@+id/fruit_name"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center_vertical"
       android:layout_margin="10dp"/>
</LinearLayout>

2.3 自定義適配器

public class FruitAdapter extends ArrayAdapter<Fruit> {
 private int resourceId;
 public FruitAdapter(Context context, int resource, List<Fruit> objects) {
     super(context, resource, objects);
     resourceId=resource;
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
     Fruit fruit=getItem(position);
     View view= LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
     ImageView fruitImage=(ImageView)view.findViewById(R.id.fruit_image);
     TextView fruitName=(TextView)view.findViewById(R.id.fruit_name);
     fruitImage.setImageResource(fruit.getimageId());
     fruitName.setText(fruit.getName());
     return view;
 }
}

2.4 為ListView設(shè)定適配器柜砾,顯示數(shù)據(jù)

public class MainActivity extends AppCompatActivity {

 private List<Fruit> fruitList=new ArrayList<>();
 @Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     initFruits();
     FruitAdapter adapter=new FruitAdapter(MainActivity.this,
             R.layout.fruit_item,fruitList);
     ListView listView=(ListView)findViewById(R.id.list_view);
     listView.setAdapter(adapter);
 }
 private void initFruits(){
     for(int i=0;i<4;i++) {
         Fruit apple = new Fruit("蘋果", R.drawable.apple);
         fruitList.add(apple);
         Fruit caomei = new Fruit("草莓", R.drawable.caomei);
         fruitList.add(caomei);
         Fruit migua = new Fruit("蜜瓜", R.drawable.migua);
         fruitList.add(migua);
         Fruit orange = new Fruit("橘子", R.drawable.orange);
         fruitList.add(orange);
         Fruit putao = new Fruit("葡萄", R.drawable.putao);
         fruitList.add(putao);
         Fruit qiyiguo = new Fruit("奇異果", R.drawable.qiyiguo);
         fruitList.add(qiyiguo);
     }
 }
}

3 優(yōu)化,提升ListView效率

  • 為避免快速滑動時重復(fù)加載布局重新加載,注意到自定義的適配器中g(shù)etView()方法中有一個參數(shù)convertView唬渗,這個參數(shù)用于將之前加載好的布局進行緩存堰酿,以便之后可以進行重用良狈,所以修改FruitAdapter中的代碼如下:
@Override
   public View getView(int position, View convertView, ViewGroup parent) {
       Fruit fruit=getItem(position);
       View view;
       if(convertView==null){
           view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
       }
       else{
           view=convertView;
       }
       ImageView fruitImage=(ImageView)view.findViewById(R.id.fruit_image);
       TextView fruitName=(TextView)view.findViewById(R.id.fruit_name);
       fruitImage.setImageResource(fruit.getimageId());
       fruitName.setText(fruit.getName());
       return view;    
   }

可以看到徒像,現(xiàn)在我們在getView()方法中進行了判斷黍特,如果convertView為null,則使用Layout工nflater去加載布局锯蛀,如果不為null則直接對convertView進行重用灭衷。這樣就大大提高了ListView的運行效率,在快速滾動的時候也可以表現(xiàn)出更好的性能旁涤。

  • 不過翔曲,目前我們的這份代碼還是可以繼續(xù)優(yōu)化的,雖然現(xiàn)在已經(jīng)不會再重復(fù)去加載布局劈愚,但是每次在getView()方法中還是會調(diào)用View的findViewById()方法來獲取一次控件的實例瞳遍,我們可以借助一個ViewHolder來對這部分性能進行優(yōu)化,修改FruitAdapter中的代碼菌羽,如下所示:
@Override
   public View getView(int position, View convertView, ViewGroup parent) {
       Fruit fruit=getItem(position);
       View view;
       ViewHolder viewHolder;
       if(convertView==null){
           view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
           viewHolder=new ViewHolder();
           viewHolder.fruitImage=(ImageView)view.findViewById(R.id.fruit_image);
           viewHolder.fruitName=(TextView)view.findViewById(R.id.fruit_name);
           view.setTag(viewHolder);//將viewHolder存儲在view中
       }
       else{
           view=convertView;
           viewHolder=(ViewHolder) view.getTag();
       }
       viewHolder.fruitImage.setImageResource(fruit.getimageId());
       viewHolder.fruitName.setText(fruit.getName());
       return view;
   }
   class ViewHolder{
       ImageView fruitImage;
       TextView fruitName;
   }

我們新增了一個內(nèi)部類ViewHolder掠械,用于對控件的實例進行緩存。當(dāng)convertView為null 的時候注祖,創(chuàng)建一個ViewHolder對象猾蒂,并將控件的實例都存放在ViewHolder里,然后調(diào)用View 的setTag()方法是晨,將ViewHolder對象存儲在View中肚菠。當(dāng)convertView不為null的時候,
則調(diào)用View的getTag()方法罩缴,把ViewHolder重新取出案糙。這樣所有控件的實例都緩存在了 ViewHolder里,就沒有必要每次都通過findViewBy工do方法來獲取控件實例了靴庆。
通過這兩步優(yōu)化之后时捌,我們ListView的運行效率就已經(jīng)非常不錯了。

4 ListView的點擊事件

  • 為ListView設(shè)置子項監(jiān)聽器炉抒,修改代碼如下:
public class MainActivity extends AppCompatActivity {
   private List<Fruit> fruitList=new ArrayList<>();
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       ActionBar actionBar=getSupportActionBar();
       if(actionBar!=null){
           actionBar.hide();
       }
       initFruits();
       FruitAdapter adapter=new FruitAdapter(MainActivity.this,
               R.layout.fruit_item,fruitList);
       ListView listView=(ListView)findViewById(R.id.list_view);
       listView.setAdapter(adapter);
       listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
           @Override
           public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
               Fruit fruit=fruitList.get(position);
               Toast.makeText(MainActivity.this,fruit.getName(),Toast.LENGTH_SHORT).show();
           }
       });
   }
   private void initFruits(){
       for(int i=0;i<10;i++) {
           Fruit apple = new Fruit("蘋果", R.drawable.apple);
           fruitList.add(apple);
           Fruit caomei = new Fruit("草莓", R.drawable.caomei);
           fruitList.add(caomei);
           Fruit migua = new Fruit("蜜瓜", R.drawable.migua);
           fruitList.add(migua);
           Fruit orange = new Fruit("橘子", R.drawable.orange);
           fruitList.add(orange);
           Fruit putao = new Fruit("葡萄", R.drawable.putao);
           fruitList.add(putao);
           Fruit qiyiguo = new Fruit("奇異果", R.drawable.qiyiguo);
           fruitList.add(qiyiguo);
       }
   }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奢讨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子焰薄,更是在濱河造成了極大的恐慌拿诸,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件塞茅,死亡現(xiàn)場離奇詭異亩码,居然都是意外死亡,警方通過查閱死者的電腦和手機野瘦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門描沟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來飒泻,“玉大人,你說我怎么就攤上這事吏廉∨⒁牛” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵席覆,是天一觀的道長史辙。 經(jīng)常有香客問我,道長佩伤,這世上最難降的妖魔是什么聊倔? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮生巡,結(jié)果婚禮上耙蔑,老公的妹妹穿的比我還像新娘。我一直安慰自己障斋,他們只是感情好纵潦,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著垃环,像睡著了一般邀层。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上遂庄,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天寥院,我揣著相機與錄音,去河邊找鬼涛目。 笑死秸谢,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的霹肝。 我是一名探鬼主播估蹄,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼沫换!你這毒婦竟也來了臭蚁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤讯赏,失蹤者是張志新(化名)和其女友劉穎垮兑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體漱挎,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡系枪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了磕谅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片私爷。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡雾棺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出当犯,到底是詐尸還是另有隱情垢村,我是刑警寧澤割疾,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布嚎卫,位于F島的核電站,受9級特大地震影響宏榕,放射性物質(zhì)發(fā)生泄漏拓诸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一麻昼、第九天 我趴在偏房一處隱蔽的房頂上張望奠支。 院中可真熱鬧,春花似錦抚芦、人聲如沸倍谜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尔崔。三九已至,卻和暖如春褥民,著一層夾襖步出監(jiān)牢的瞬間季春,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工消返, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留载弄,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓撵颊,卻偏偏與公主長得像宇攻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子倡勇,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容