BaseAdapter的逗逼、普通、文艺写法

ListView-Adapter-dataSource的关系

这其实就是MVC的关系

ListView负责表现数据,Adapter负责表现与数据源之间的沟通,dataSource就是要显示的数据。是不是很想一种模式?没错,就是MVC模式。

 

ListView的缓冲机制

Android中的ListView是有缓存机制的,也就是缓冲池。
比如LiteView中有100条数据,而屏幕大小只能显示其中的10条。那么先从缓存池中取出10条数据,显示到屏幕上。
向上滑动屏幕时,屏幕上方的第1条消失,回收到了缓冲池中去。并从缓冲池中取出第11条数据。以此类推。

当屏幕滑动回到前10条的时候,就会从缓冲池中取出前10条数据。
这就是ListView的缓冲机制。

 

现在来用ListView和BaseAdapter来实现一个类似于下图的应用:

 

需要3个类:Bean,Activity,BaseAdapter

 1 package com.owen.baseadapterdemo.bean;
 2 
 3 /**
 4  * ListeItem的model类
 5  * 
 6  * @author Owen
 7  */
 8 public class Item {
 9 
10     private int itemImgResId;
11     private String itemTitle;
12     private String itemContent;
13 
14     public Item() {
15     }
16 
17     public Item(int itemImgResId, String itemTitle, String itemContent) {
18         this.itemImgResId = itemImgResId;
19         this.itemTitle = itemTitle;
20         this.itemContent = itemContent;
21     }
22 
23     public int getItemImgResId() {
24         return itemImgResId;
25     }
26 
27     public void setItemImgResId(int itemImgResId) {
28         this.itemImgResId = itemImgResId;
29     }
30 
31     public String getItemTitle() {
32         return itemTitle;
33     }
34 
35     public void setItemTitle(String itemTitle) {
36         this.itemTitle = itemTitle;
37     }
38 
39     public String getItemContent() {
40         return itemContent;
41     }
42 
43     public void setItemContent(String itemContent) {
44         this.itemContent = itemContent;
45     }
46 
47 }
View Code
 1 package com.owen.baseadapterdemo.adapter;
 2 
 3 import java.util.List;
 4 
 5 import android.content.Context;
 6 import android.view.LayoutInflater;
 7 import android.view.View;
 8 import android.view.ViewGroup;
 9 import android.widget.BaseAdapter;
10 
11 import com.owen.baseadapterdemo.bean.Item;
12 
13 /**
14  * BaseAdapter
15  * 
16  * @author Owen
17  */
18 public class MyBaseAdapter extends BaseAdapter {
19 
20     private LayoutInflater inflater;
21     private List<Item> items;
22     
23     public MyBaseAdapter(Context context, List<Item> items) {
24         this.items = items;
25         inflater = (LayoutInflater) context
26                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
27     }
28 
29     @Override
30     public int getCount() {
31         return items.size();
32     }
33 
34     @Override
35     public Object getItem(int position) {
36         return items.get(position);
37     }
38 
39     @Override
40     public long getItemId(int position) {
41         return position;
42     }
43 
44     @Override
45     public View getView(int position, View convertView, ViewGroup parent) {
46         // TODO
47         return null;
48     }
49     
50 }
View Code
 1 package com.owen.baseadapterdemo;
 2 
 3 import java.util.List;
 4 
 5 import android.app.Activity;
 6 import android.os.Bundle;
 7 import android.widget.ListView;
 8 
 9 import com.owen.baseadapterdemo.adapter.MyBaseAdapter;
10 import com.owen.baseadapterdemo.bean.Item;
11 
12 
13 public class MainActivity extends Activity {
14 
15     private List<Item> items;
16     private ListView listView;
17     private MyBaseAdapter adapter;
18     
19     @Override
20     protected void onCreate(Bundle savedInstanceState) {
21         super.onCreate(savedInstanceState);
22         setContentView(R.layout.activity_main);
23     }
24 
25 }
View Code

 

1、首先生成数据,将Activity类完善

 1 package com.owen.baseadapterdemo;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 import android.app.Activity;
 7 import android.os.Bundle;
 8 import android.widget.ListView;
 9 
10 import com.owen.baseadapterdemo.adapter.MyBaseAdapter;
11 import com.owen.baseadapterdemo.bean.Item;
12 
13 
14 public class MainActivity extends Activity {
15 
16     private List<Item> items;
17     private ListView listView;
18     private MyBaseAdapter adapter;
19     
20     @Override
21     protected void onCreate(Bundle savedInstanceState) {
22         super.onCreate(savedInstanceState);
23         setContentView(R.layout.activity_main);
24         
25         items = new ArrayList<Item>();
26         for (int i = 0; i < 20; i++) {
27             Item item = new Item(R.drawable.ic_launcher, "我是标题" + i, "我是内容" + i);
28             items.add(item);
29         }
30         
31         adapter = new MyBaseAdapter(this, items);
32         listView = (ListView) findViewById(R.id.list);
33         listView.setAdapter(adapter);
34     }
35 
36 }
View Code

2、接着完善BaseAdapter类,采用逗逼写法

 1 package com.owen.baseadapterdemo.adapter;
 2 
 3 import java.util.List;
 4 
 5 import android.content.Context;
 6 import android.view.LayoutInflater;
 7 import android.view.View;
 8 import android.view.ViewGroup;
 9 import android.widget.BaseAdapter;
10 import android.widget.ImageView;
11 import android.widget.TextView;
12 
13 import com.owen.baseadapterdemo.R;
14 import com.owen.baseadapterdemo.bean.Item;
15 
16 /**
17  * BaseAdapter
18  * 
19  * @author Owen
20  */
21 public class MyBaseAdapter extends BaseAdapter {
22 
23     private LayoutInflater inflater;
24     private List<Item> items;
25     
26     public MyBaseAdapter(Context context, List<Item> items) {
27         this.items = items;
28         inflater = (LayoutInflater) context
29                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
30     }
31 
32     @Override
33     public int getCount() {
34         return items.size();
35     }
36 
37     @Override
38     public Object getItem(int position) {
39         return items.get(position);
40     }
41 
42     @Override
43     public long getItemId(int position) {
44         return position;
45     }
46 
47     @Override
48     public View getView(int position, View convertView, ViewGroup parent) {
49         // 逗逼式
50         View view = inflater.inflate(R.layout.list_item, null);
51         Item item = items.get(position);
52         
53         ImageView imtemImg = (ImageView) view.findViewById(R.id.iv_img);
54         TextView itemTitle = (TextView) view.findViewById(R.id.tv_title);
55         TextView itemCotent = (TextView) view.findViewById(R.id.tv_content);
56         
57         imtemImg.setImageResource(item.getItemImgResId());
58         itemTitle.setText(item.getItemTitle());
59         itemCotent.setText(item.getItemContent());
60         
61         return view;
62     }    
63 }

逗逼写法完全没有用到ListView的缓存机制,每次都生成一个View对象,而没有使用convertView对象。造成了内存浪费和速度降低。

 

接着使用ListView缓存机制,采用普通写法:

 1 package com.owen.baseadapterdemo.adapter;
 2 
 3 import java.util.List;
 4 
 5 import android.content.Context;
 6 import android.view.LayoutInflater;
 7 import android.view.View;
 8 import android.view.ViewGroup;
 9 import android.widget.BaseAdapter;
10 import android.widget.ImageView;
11 import android.widget.TextView;
12 
13 import com.owen.baseadapterdemo.R;
14 import com.owen.baseadapterdemo.bean.Item;
15 
16 /**
17  * BaseAdapter
18  *
19  * @author Owen
20  */
21 public class MyBaseAdapter extends BaseAdapter {
22 
23     private LayoutInflater inflater;
24     private List<Item> items;
25     
26     public MyBaseAdapter(Context context, List<Item> items) {
27         this.items = items;
28         inflater = (LayoutInflater) context
29                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
30     }
31 
32     @Override
33     public int getCount() {
34         return items.size();
35     }
36 
37     @Override
38     public Object getItem(int position) {
39         return items.get(position);
40     }
41 
42     @Override
43     public long getItemId(int position) {
44         return position;
45     }
46 
47     @Override
48     public View getView(int position, View convertView, ViewGroup parent) {
49         // 普通式
50         if (convertView == null) {
51             convertView = inflater.inflate(R.layout.list_item, null);
52         }
53         Item item = items.get(position);
54         
55         ImageView imtemImg = (ImageView) convertView.findViewById(R.id.iv_img);
56         TextView itemTitle = (TextView) convertView.findViewById(R.id.tv_title);
57         TextView itemCotent = (TextView) convertView.findViewById(R.id.tv_content);
58         
59         imtemImg.setImageResource(item.getItemImgResId());
60         itemTitle.setText(item.getItemTitle());
61         itemCotent.setText(item.getItemContent());
62         
63         return convertView;
64     }
65     
66 }

这种写法是不是很熟悉,一直都是我们都在用的方法。但是,就是但是,这种方法还是不够快。

 

如何改进?就要采取一个思想:空间换时间,使用内存作为缓存来加快速度。上代码:

 1 package com.owen.baseadapterdemo.adapter;
 2 
 3 import java.util.List;
 4 
 5 import android.content.Context;
 6 import android.view.LayoutInflater;
 7 import android.view.View;
 8 import android.view.ViewGroup;
 9 import android.widget.BaseAdapter;
10 import android.widget.ImageView;
11 import android.widget.TextView;
12 
13 import com.owen.baseadapterdemo.R;
14 import com.owen.baseadapterdemo.bean.Item;
15 
16 /**
17  * BaseAdapter
18  *
19  * @author Owen
20  */
21 public class MyBaseAdapter extends BaseAdapter {
22 
23     private LayoutInflater inflater;
24     private List<Item> items;
25     
26     public MyBaseAdapter(Context context, List<Item> items) {
27         this.items = items;
28         inflater = (LayoutInflater) context
29                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
30     }
31 
32     @Override
33     public int getCount() {
34         return items.size();
35     }
36 
37     @Override
38     public Object getItem(int position) {
39         return items.get(position);
40     }
41 
42     @Override
43     public long getItemId(int position) {
44         return position;
45     }
46 
47     @Override
48     public View getView(int position, View convertView, ViewGroup parent) {
49         // 文艺式
50         ViewHolder viewHolder = new ViewHolder();
51         if (convertView == null) {
52             convertView = inflater.inflate(R.layout.list_item, null);
53             
54             viewHolder.imtemImg = (ImageView) convertView.findViewById(R.id.iv_img);
55             viewHolder.itemTitle = (TextView) convertView.findViewById(R.id.tv_title);
56             viewHolder.itemCotent = (TextView) convertView.findViewById(R.id.tv_content);
57             
58             convertView.setTag(viewHolder);
59         } else {
60             viewHolder = (ViewHolder) convertView.getTag();
61         }
62         
63         Item item = items.get(position);
64         
65         viewHolder.imtemImg.setImageResource(item.getItemImgResId());
66         viewHolder.itemTitle.setText(item.getItemTitle());
67         viewHolder.itemCotent.setText(item.getItemContent());
68         
69         return convertView;
70     }
71 
72     private static class ViewHolder {
73         ImageView imtemImg;
74         TextView itemTitle;
75         TextView itemCotent;
76     }
77     
78 }

使用一个ViewHoder类来存储控件,放在内存中,要用的时候再拿出来。这样做的原因是 View.findViewById(resId) 的执行时间会比较长。

文艺写法等于是在ListView缓冲池之外,我们又自己建立了一个缓冲池。

这种速度是最快的。不服?不服跑个分,看看逗逼、普通和文艺写法哪种速度最快。

 

来源:http://imooc.com/learn/365,感谢慕课网

posted @ 2015-04-14 15:05  红尘炼心  阅读(286)  评论(0编辑  收藏  举报