Android开发秘籍学习笔记(五)
16lz
2022-03-08
该笔记为Android中关于适配器Adapter的使用。
Adapter的介绍:
Adapter是用来帮助填充数据间的中间桥梁,比如通过它将数据填充到ListView,GridView,Gallery。而Android也提供了多种Adapter:ArrayAdapter,BaseAdapter,CursorAdapter,HeaderViewListAdapter, ListAdapter, ResourceCursorAdapter, SimpleAdapter, SimpleCursorAdapter, SpinnerAdapter, WrapperListAdapter.
Adapter的用途:
ListView,GridView等视图展示数据的格式有一定的要求,数据适配器就是建立数据源和ListView它们之间的适配关系,将数据源的数据转化成ListVIew能够ixanshide数据格式,从而将数据的来源和数据的显示进行解耦,降低了程序的耦合性,让程序更容易扩展。下面这张图就能清晰告诉你Adapter的用途ListView的显示和缓存机制:
由于适配器的种类繁多,不需要每种都掌握,常用的有ListView的数据填充采用的适配器BaseAdapter,在介绍如何使用BaseAdapter前,先学习下ListView的显示和缓存机制。转载自http://blog.csdn.net/deng0zhaotai/article/details/38943475下面简单说下上图的原理:
1、如果你有几千几万甚至更多的选项(item)时,其中只有可见的项目(满屏显示的Item数目)存在内存(说的优化就是说在内存中的优化!)中,其他的在Recycler(View的缓存池)中
2、ListView先请求一个type1视图(getView)然后请求其他可见的项目。convertView在getView中是空(null)的,第一次都是为空的,只要显示过了convertView都不为空,会保存在Recycler中
3、当item1滚出屏幕,并且一个新的项目从屏幕低端上来时,ListView再请求一个type1视图。convertView此时不是空值了,它的值是item1。你只需设定新的数据然后返回convertView,不必重新创建一个视图,省去了inflate和findViewById的时间,性能就得到了优化。
Adapter模式的应用:
接下来就结合例子讲解下BaseAdapter的使用。首先是MainActivity的布局文件---activity_main.xml<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="${relativePackage}.${activityClass}" > <ListView android:id="@+id/lv_view" android:layout_width="match_parent" android:layout_height="match_parent" /></RelativeLayout>一个ListView控件即可。
再来我们需要自己构造数据源,定义一个数据源的类-----ItemBean
public class ItemBean {public int iamgeSouceId;public String itemTitle;public String itemContent;public ItemBean(int iamgeSouceId, String itemTitle, String itemContent) {this.iamgeSouceId = iamgeSouceId;this.itemTitle = itemTitle;this.itemContent = itemContent;}}然后在MainActivity中给数据源赋值
List<ItemBean> itemlist = new ArrayList<ItemBean>();for (int i = 0; i < 20; i++){itemlist.add(new ItemBean(R.drawable.ic_launcher, "我是标题" + i, "我是内容" + i));}
数据源的数据已经准备好了,接下来就是自定义适配器了。
import java.util.List;import android.annotation.SuppressLint;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;@SuppressLint("InflateParams")public class MyAdapter extends BaseAdapter {List<ItemBean> itemlist;LayoutInflater inflater;public MyAdapter(Context context,List<ItemBean> itemlist) {this.itemlist = itemlist;inflater = LayoutInflater.from(context);}@Overridepublic int getCount() {return itemlist.size();}@Overridepublic Object getItem(int position) {return itemlist.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {/*****************普通式**********************//*if(convertView == null){convertView = inflater.inflate(R.layout.item, null);}ImageView imageView = (ImageView) convertView.findViewById(R.id.item_image);TextView titleView = (TextView) convertView.findViewById(R.id.item_title);TextView contentView = (TextView) convertView.findViewById(R.id.item_content);imageView.setImageResource(itemlist.get(position).iamgeSouceId);titleView.setText(itemlist.get(position).itemTitle);contentView.setText(itemlist.get(position).itemContent);return convertView;*/ViewHolder viewHolder = new ViewHolder();if(convertView == null){convertView = inflater.inflate(R.layout.item, null);viewHolder.imageView = (ImageView) convertView.findViewById(R.id.item_image);viewHolder.titleView = (TextView) convertView.findViewById(R.id.item_title);viewHolder.contentView = (TextView) convertView.findViewById(R.id.item_content);convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag();}viewHolder.imageView.setImageResource(itemlist.get(position).iamgeSouceId);viewHolder.titleView.setText(itemlist.get(position).itemTitle); viewHolder.contentView.setText(itemlist.get(position).itemContent);return convertView;}class ViewHolder{private ImageView imageView;private TextView titleView;private TextView contentView;}}
可以看到我们自定义的MyAdapte继承自BaseAdapter,那么上面代码的四个函数必须重写----getCount(),getItem(),getItemId(),getView()。 其中getView()方法是BaseAdapter的精髓。有3种方式来写getView(),第一种直接创建一个新的View,完全没有利用到ListView的缓存机制,会对资源造成极大的浪费,效率极其低下,所以我这里测试都没测试。第二种是利用了ListView的convertView,它利用到了ListView的缓存机制,如果没有缓存才创建新的View,但findViewById会浪费掉系统大量的时间。最后一种利用ViewHolder,它不仅利用到ListView的缓存机制,更通过ViewHolder类来实现数据视图的缓存,避免了多次findViewById寻找控件。
最后就是给ListView添加上适配器
ListView lv_view = (ListView) findViewById(R.id.lv_view);lv_view.setAdapter(new MyAdapter(this, itemlist));
大功告成,看看效果图:
SimpleAdapter的使用:
让我们先来看看SimpleAdapter的构造函数吧:public SimpleAdapter (Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)这里解释下各个参数: Context: SimpleAdapter关联的View的运行环境即"上下文 List<? extends Map<String, ?>> data: 一个Map组成的List。在列表中的每个条目对应列表中的一行,每一个map中应该包含所有在from参数中指定的键,即导入ListView或者GridView的数据源。 resource: 一个定义列表项的布局文件的资源ID。布局文件将至少应包含那些在to中定义了的ID(子布局) from: 一个将被添加到Map映射上的键名 to: 将绑定数据的视图的ID,跟from参数对应,这些应该全是TextView
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView lv = (ListView) findViewById(R.id.listView1); String[] from = { "Text", "Button" }; int[] to = { R.id.text, R.id.button }; List<Map<String, ?>> list = new ArrayList<Map<String, ?>>(); for (int i = 0; i < 10; i++) { Map<String, String> m = new HashMap<String, String>(); m.put("Text", "Text" + i); m.put("Button", "Button" + i); list.add(m); } SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.listitem, from, to); lv.setAdapter(adapter);}来个最简单的例子,上面这个例子中定义了数据源----list,是一个Map的集合。而Map中有两个键值--“Text”和“Button”因此我们可以看到参数“from”就是这两个值组成的字符数组,而参数“to”中的int[] to = { R.id.text, R.id.button };应该是参数“source”=R.layout.listitem里两个控件的ID。
更多相关文章
- 使用Javaweb开发的WebService部署到Tomcat,使用Android调用的遇到
- Android(安卓)中的单元测试(使用AndroidTestCase 进行 Content P
- WebKit – WebKit For Android
- Android(安卓)学习笔记
- 在Android中实现全屏显示的方法
- 自定义圆形进度条ProgressBar的三种方式
- 【Android】Android清除本地数据缓存代码
- android mediaStore
- mybatisplus的坑 insert标签insert into select无参数问题的解决