标签:
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 }
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 }
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 }
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 }
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 class ViewHolder { 73 ImageView imtemImg; 74 TextView itemTitle; 75 TextView itemCotent; 76 } 77 78 }
使用一个ViewHoder类来存储控件,放在内存中,要用的时候再拿出来。这样做的原因是 View.findViewById(resId) 的执行时间会比较长。
文艺写法等于是在ListView缓冲池之外,我们又自己建立了一个缓冲池。
这种速度是最快的。不服?不服跑个分,看看逗逼、普通和文艺写法哪种速度最快。
来源:http://imooc.com/learn/365,感谢慕课网
标签:
原文地址:http://www.cnblogs.com/stayfoolishstayhungry/p/4424913.html