ListView是开发中最常用的控件了,但是总是会写重复的代码,浪费时间又没有意义。
最近参考一些资料,发现一个万能ListView适配器,代码量少,节省时间,总结一下分享给大家。
首先有一个自定义的Adapter继承于BaseAdapter,下面是自定义的Adapter,精华在getView()方法中
packagecom.example.mylistview.util;importjava.util.List;importandroid.content.Context;importandroid.view.LayoutInflater;importandroid.view.View;importandroid.view.ViewGroup;importandroid.widget.BaseAdapter;public abstract class CommonAdapter extendsBaseAdapter {/*** 上下文*/
privateContext mContext;/*** 实体类集合*/
private ListmDatas;privateLayoutInflater mInflater;/*** 控件id*/
private intmlayoutId;public CommonAdapter(Context context, List datas, intlayoutId) {this.mContext =context;this.mDatas =datas;this.mlayoutId =layoutId;
mInflater=LayoutInflater.from(context);
}
@Overridepublic intgetCount() {//TODO Auto-generated method stub
returnmDatas.size();
}
@Overridepublic T getItem(intarg0) {//TODO Auto-generated method stub
returnmDatas.get(arg0);
}
@Overridepublic long getItemId(intarg0) {//TODO Auto-generated method stub
returnarg0;
}
@Overridepublic View getView(intarg0, View arg1, ViewGroup arg2) {//TODO Auto-generated method stub
ViewHolder holder =ViewHolder.get(mContext, arg1, arg2, mlayoutId,
arg0);
convert(holder, getItem(arg0));returnholder.getConvertView();
}public abstract voidconvert(ViewHolder holder, T t);
}
以上的抽象方法convert(ViewHolder holder, T t);就相当于以前通用代码中的
viewHolder.mTextView = (TextView) convertView .findViewById(R.id.id_tv_title);
viewHolder.mTextView.setText(Bean.getName());
找到控件的id再去设施setText等重复的代码方法中的参数ViewHolder holder, T t holder就相当于以前通用代码中的viewHolder,t就相当于一个自己定义的实体类Bean。
以上代码中getView()方法中有一个ViewHolder是需要自己声明的,以下是代码以及详细注释:
packagecom.example.mylistview.util;importandroid.content.Context;importandroid.graphics.Bitmap;importandroid.renderscript.Type;importandroid.util.SparseArray;importandroid.view.LayoutInflater;importandroid.view.View;importandroid.view.ViewGroup;importandroid.widget.ImageView;importandroid.widget.TextView;public classViewHolder {/*** SparseArray类存放View集合*/
private SparseArraymViews;/****/
private intmPosition;/*** 布局文件*/
privateView mConvertView;publicView getConvertView() {returnmConvertView;
}public ViewHolder(Context context, ViewGroup parent, intlayoutId,intposition) {this.mViews = new SparseArray();this.mPosition =position;this.mConvertView =LayoutInflater.from(context).inflate(layoutId,
parent,false);this.mConvertView.setTag(this);
}/*** 拿到一个ViewHolder对象
*@paramcontext
*@paramconvertView
*@paramparent
*@paramlayoutId
*@paramposition
*@return
*/
public staticViewHolder get(Context context, View convertView,
ViewGroup parent,int layoutId, intposition) {if (null ==convertView) {return newViewHolder(context, parent, layoutId, position);
}else{
ViewHolder holder=(ViewHolder) convertView.getTag();
holder.mPosition=position;returnholder;
}
}/*** 通过控件的id获取对应的控件,如果没有则加入views
*@paramviewId
*@return
*/
public T getView(intviewId) {
View view=mViews.get(viewId);if (null ==view) {
view=mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}return(T) view;
}/*** 为TextView设置字符串
*@paramviewId
*@paramtext
*@return
*/
public ViewHolder setText(intviewId, String text) {
TextView tv=getView(viewId);
tv.setText(text);return this;
}/*** 为ImageView设置图片
*
*@paramviewId
*@paramdrawableId
*@return
*/
public ViewHolder setImageResource(int viewId, intdrawableId)
{
ImageView view=getView(viewId);
view.setImageResource(drawableId);return this;
}public intgetPosition()
{returnmPosition;
}
}
再写一个Adapter继承于万能适配器CommonAdapter,还是要写一个自己的Adapter,因为一个项目可能会有多个ListView,但是每个的item元素,布局都会有所不同的,这个泪用来区分不同的ListView与自己所对应的item.这个代码量较少完全可以写成内部类在Activity.java中.
packagecom.example.mylistview.adapter;importjava.util.List;importandroid.content.Context;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.CheckBox;importcom.example.mylistview.R;importcom.example.mylistview.domain.Bean;importcom.example.mylistview.util.CommonAdapter;importcom.example.mylistview.util.ViewHolder;public class MyAdapter extends CommonAdapter{public MyAdapter(Context context, List datas, intlayoutId) {super(context, datas, layoutId);//TODO Auto-generated constructor stub
}
@Overridepublic void convert(ViewHolder holder, finalBean bean) {//TODO Auto-generated method stub
holder.setText(R.id.tv_title, bean.getTitle())
.setText(R.id.tv_desc, bean.getDesc())
.setText(R.id.tv_time, bean.getTime())
.setText(R.id.tv_phone, bean.getPhone());/*** 防止CheckBox混乱*/
final CheckBox cBox =(CheckBox)(holder.getView(R.id.cb));if (cBox != null)
{
cBox.setChecked(bean.isChecked());
cBox.setOnClickListener(newOnClickListener()
{
@Overridepublic voidonClick(View v)
{
bean.setChecked(cBox.isChecked());
}
});
}
}
}
优化之后用适配器的时候就简单多了下面是实体类,item和MainActivity.java中的代码:
实体类:
packagecom.example.mylistview.domain;public classBean {privateString title;privateString desc;privateString time;privateString phone;private booleanisChecked;public booleanisChecked() {returnisChecked;
}public void setChecked(booleanisChecked) {this.isChecked =isChecked;
}/***@paramtitle
*@paramdesc
*@paramtime
*@paramphone*/
publicBean(String title, String desc, String time, String phone) {this.title =title;this.desc =desc;this.time =time;this.phone =phone;
}publicString getTitle() {returntitle;
}public voidsetTitle(String title) {this.title =title;
}publicString getDesc() {returndesc;
}public voidsetDesc(String desc) {this.desc =desc;
}publicString getTime() {returntime;
}public voidsetTime(String time) {this.time =time;
}publicString getPhone() {returnphone;
}public voidsetPhone(String phone) {this.phone =phone;
}
}
MainActivity.java:
重点代码:
参数有上下文,集合,和自己对应的item就可以了
adapter =new MyAdapter(this, mDatas, R.layout.item);
packagecom.example.mylistview.ui;importjava.util.ArrayList;importjava.util.List;importandroid.app.Activity;importandroid.content.Intent;importandroid.os.Bundle;importandroid.view.View;importandroid.widget.AdapterView;importandroid.widget.AdapterView.OnItemClickListener;importandroid.widget.ListView;importcom.example.mylistview.R;importcom.example.mylistview.adapter.MyAdapter;importcom.example.mylistview.domain.Bean;public class MainActivity extendsActivity {privateListView listView;private ListmDatas;/*** 适配器*/
privateMyAdapter adapter;
@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
listener();
}private voidlistener() {//TODO Auto-generated method stub
listView.setOnItemClickListener(newOnItemClickListener() {
@Overridepublic void onItemClick(AdapterView> arg0, View arg1, intarg2,longarg3) {//TODO Auto-generated method stub
startActivity(new Intent(MainActivity.this, SecondActivity.class));
}
});
}private voidinitData() {//TODO Auto-generated method stub
mDatas = new ArrayList();
Bean bean= new Bean("Android新技能 Get","Android-打造万能的ListView和GridView适配器", "2015-08-05", "10086");
mDatas.add(bean);
bean= new Bean("捡到权志龙一个","在星巴克捡到权志龙一个", "2015-08-06", "10086");
mDatas.add(bean);
bean= new Bean("GetTOP一个","在韩国首尔捡到TOP一个", "2015-08-07", "10086");
mDatas.add(bean);
adapter= new MyAdapter(this, mDatas, R.layout.item);
listView.setAdapter(adapter);
}private voidinitView() {//TODO Auto-generated method stub
listView =(ListView) findViewById(R.id.listView);
}
}
item布局:
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp" >
android:focusable="false"
android:id="@+id/cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerInParent="true" />
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:singleLine="true"
android:text="Android新技能 Get" />
android:id="@+id/tv_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tv_title"
android:layout_marginTop="10dp"
android:layout_toLeftOf="@id/cb"
android:maxLines="2"
android:text="Android-打造万能的ListView和GridView适配器"
android:textColor="#898989" />
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_desc"
android:layout_marginTop="10dp"
android:text="2015-08-05"
android:textColor="#898989"
android:textSize="12sp" />
android:id="@+id/tv_phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@id/tv_desc"
android:layout_marginTop="10dp"
android:background="#20793D"
android:maxLines="1"
android:text="10086"
android:padding="4dp"
android:textColor="#FFF" />
效果图:
用这个去适配另一个不同的布局:
新布局的Adapter一样继承自己的万能adapter:CommonAdapter
packagecom.example.mylistview.adapter;importjava.util.List;importjava.util.Map;importandroid.content.Context;importcom.example.mylistview.R;importcom.example.mylistview.util.CommonAdapter;importcom.example.mylistview.util.ViewHolder;public class SecondAdapter extends CommonAdapter>{public SecondAdapter(Context context, List>datas,intlayoutId) {super(context, datas, layoutId);//TODO Auto-generated constructor stub
}
@Overridepublic void convert(ViewHolder holder, Mapt) {//TODO Auto-generated method stub
holder.setText(R.id.tv_item2values, t.get("values"));
}
}
Activity.java代码:
packagecom.example.mylistview.ui;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importandroid.app.Activity;importandroid.os.Bundle;importandroid.widget.ListView;importcom.example.mylistview.R;importcom.example.mylistview.adapter.MyAdapter;importcom.example.mylistview.adapter.SecondAdapter;public class SecondActivity extendsActivity {privateListView listView_second;privateSecondAdapter secondAdapter;private List> lists = new ArrayList>();
@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
initView();
initData();
}private voidinitData() {//TODO Auto-generated method stub
for (int i = 0; i < 4; i++) {
Map map= new HashMap();
map.put("values", "条目" +i);
lists.add(map);
}
secondAdapter= new SecondAdapter(this, lists, R.layout.item2);
listView_second.setAdapter(secondAdapter);
}private voidinitView() {//TODO Auto-generated method stub
listView_second =(ListView) findViewById(R.id.listView_second);
}
}
item:
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
android:id="@+id/tv_item2values"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="ffffff"
android:layout_margin="16dp"
android:gravity="center" />
效果图:
备忘,希望能给大家带来帮助。