整理总结自鸿洋的博客:http://blog.youkuaiyun.com/lmj623565791/article/details/38902805/
一、利用普通的Adapter实现ListView列表——这是最基础的适配器
以下代码是最普通的实现方法:
1、MainActiviy.java
public class MainActivity extends Activity {
private List<String> mData = new ArrayList<String>(Arrays.asList("HongYang", "GuoLin", "RenYuGang", "Jiatao"));
private Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listview);
MyAdapter mAdapter = new MyAdapter(context, mData);
listView.setAdapter(mAdapter);
}
}
2、activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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=".act.MainActivity">
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
3、MyAdapter.java
/**
* Created by jiatao on 2016/6/10.
* 这是最普通的适配器:
* MyAdapter继承BaseAdapter,然后getView里面使用ViewHolder模式;
* 一般情况下,我们的写法是这样的:对于不同布局的ListView,我们会有一个对应的Adapter,在Adapter中又会有一个ViewHolder类来提高效率。
* 这样出现ListView就会出现与之对应的Adapter类、ViewHolder类;
* 那么有没有办法减少我们的编码呢?第二部分中将初步实现
*/
public class MyAdapter extends BaseAdapter {
private LayoutInflater mLayoutInflater;
private Context mContext;
private List<String> mData;
public MyAdapter(Context mContext, List<String> mData) {
mLayoutInflater = LayoutInflater.from(mContext);
this.mContext = mContext;
this.mData = mData;
}
@Override
public int getCount() {
return mData == null ? 0 : mData.size();
}
@Override
public Object getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mLayoutInflater.inflate(R.layout.item_string_listview, parent, false);
holder.tv_title = (TextView) convertView.findViewById(R.id.tv_title);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tv_title.setText(mData.get(position));
return convertView;
}
class ViewHolder {
private TextView tv_title;
}
}
4、item_string_listview.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#aa111111"
android:gravity="center_vertical"
android:paddingLeft="15dp"
android:text="hello"
android:textColor="#ffffff"
android:textSize="20sp"
android:textStyle="bold">
</TextView>
二、打造通用的ViewHolder——使能在外部获得ViewHolder、相关View控件、convertView
1、MainActiviy.java
同上
2、activity_main.xml
同上
3、ViewHolder.java
/**
* Created by jiatao on 2016/6/11.
* 通用的ViewHolder
* 1、ViewHolder的作用是通过convertView.setTag与convertView进行绑定,然后当convertView复用时,直接从与之对于的ViewHolder(getTag)中拿到convertView布局中的控件,省去了findViewById的时间;
* 2、也就是说,实际上们每个convertView会绑定一个ViewHolder对象,这个viewHolder主要用于帮convertView存储布局中的控件;
* 3、那么我们只要写出一个通用的ViewHolder,然后对于任意的convertView,提供一个对象让其setTag即可;
* 4、既然是通用,那么我们这个ViewHolder就不可能含有各种控件的成员变量了,因为每个Item的布局是不同的,最好的方式是什么呢?
* 5、提供一个容器,专门存每个Item布局中的所有控件,而且还要能够查找出来;既然需要查找,那么ListView肯定是不行了,需要一个键值对进行保存,键为控件的Id,值为控件的引用;
* 6、相信大家立刻就能想到Map;但是我们不用Map,因为有更好的替代类,就是我们android提供的SparseArray这个类,和Map类似,但是比Map效率,不过键只能为Integer.
*/
public class ViewHolder {
private SparseArray<View> mViews;
private View mConvertView;
//构造函数
private ViewHolder(Context context, int resLayoutId, ViewGroup parent) {
this.mViews &