Android中BaseAdapter使用总结(imooc笔记)

来源:互联网 发布:虚拟机 mac 硬盘空间 编辑:程序博客网 时间:2024/05/01 02:13

ListView的显示与缓存机制,需要才显示,显示完就被收回到缓存

BaseAdapter--数据适配器

public int getCount()---适配器中数据集中数据的个数

public Object getItem(int position)---获取数据集中与指定索引对应的数据项

public long getItemId(int position)---获取指定行对应的ID

public View getView(int position, View convertView, ViewGroup parent)---获取每一个Item的显示内容

public class MainActivity extends Activity{protected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);List<ItemBean> itemBeanList = new ArrayList<>();for(int i = 0; i<20; i++){itemBeanList.add(new ItemBean(R.mipmap.ic_launcher, "标题"+i, "内容"+i));}ListView listView = (ListView)findViewById(R.id.lv_main);listView.setAdapter(new MyAdapter(this, itemBeanList));}}public class MyAdapter extends BaseAdapter{private List<ItemBean> mList;private LayoutInflater mInflater;public MyAdapter(Context context, List<ItemBean> list){mList = list;mInflater = LayoutInflater.from(context);}public int getCount(){return mList.size();}public Object getItem(int position){return mList.get(position);}public long getItemId(int position){return position;}public View getView(int position, View convertView, ViewGroup parent){View view = mInflater.inflate(r.layout.item, null);ImageView imageView = (ImageView)view.findViewById(R.id.iv_image);TextView title = (TextView)view.findViewById(r.id.tv_title);TextView content = (TextView)view.findViewById(r.id.tv_content);ItemBean bean = mList.get(position);imageView.setImageResource(bean.ItemImageResid);title.setText(bean.ItemTitle);content.setText(bean.ItemContent);return view;}}
上述方法虽然正确,但是很浪费资源,没有利用ListView的缓存机制,没有任何的优化处理,效率极低。

以下是普通的方法,利用ListView的缓存机制,即使用系统提供的converView,而不是自己创建一个view,若没有缓存再创建一个新的View:

if(convertView == null){convertView = mInflater.inflate(R.layout.item, null)}ImageView imageView = (ImageView)convertView.findViewById(R.id.iv_image);TextView title = (TextView)convertView.findViewById(r.id.tv_title);TextView content = (TextView)convertView.findViewById(r.id.tv_content);ItemBean bean = mList.get(position);imageView.setImageResource(bean.ItemImageResid);title.setText(bean.ItemTitle);content.setText(bean.ItemContent);return convertView;
因为避免了重复的创建converView对象,通过inflate对象将布局转化成一个View的时候很耗时耗资源,是很好的优化,但findViewById仍然会浪费大量时间

还有一种更优化的办法:

class ViewHolder{public ImageView imageView;public TextView title;public TextView content;}ViewHolder viewHolder;if(convertView == null){//通过ViewHolder将需要通用findViewById查找的控件保存到ViewHolder中//通过convertView.setTag将ViewHolder与convertView进行关联//这样每个为空的converView通过inflate对象初始化布局之后,将所有的控件保存在ViewHolder对象中//并通过setTag方法建立起converView与viewHolder的关联//这样通过getTag方法找到converView中的一个viewholder的对象,即找到所声明的控件//从而避免findViewById实例化,以提高效率viewHolder = new ViewHolder();convertView = mInflater.inflate(R.layout.item, null);viewHolder.imageView = (ImageView)convertView.findViewById(R.id.iv_iamgeView);viewHolder.title = (TextView)convertView.findViewById(R.id.tv_title);viewHolder.content = (TextView)convertView.findViewById(R.id.tv_content);convertView.setTag(viewHolder);}else{viewHolder = (ViewHolder)convertView.getTag();}ItemBean bean = mList.get(position);viewHolder.imageView.setImageResource(bean.ItemImageResid);viewHolder.title.setText(bean.ItemTitle);viewHolder.content.setText(bean.ItemContent);return convertView;
上述方法是最为高效和节省资源的方法,避免多次通过findViewById方法查找控件,不仅利用了ListView的缓存,还通过ViewHolder类来实现显示数据的视图缓存
可以通过long start = System.nanoTime();和long end = System.nanoTime();来获取系统纳秒时间,long dValue = end - start; 来计算程序的操作用时,再通过Log.d("系统用时:"+String.valueOf(dValue));打印操作用时

通过ViewHolder优化BaseAdapter的思路:

创建Bean对象,用于封装数据

在构造方法中初始化用于映射的数据List

创建ViewHolder类,创建布局映射关系

判断convertView,为空则创建,并设置tag,否则通过tag来取出ViewHolder

给ViewHolder中的控件设置数据

0 0