Android—万能ListView适配器
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;
publicabstractclassCommonAdapterextendsBaseAdapter{
/
上下文
/
privateContextmContext;
/
实体类集合
/
privateListmDatas;
privateLayoutInflatermInflater;
/
控件id
/
privateintmlayoutId;
publicCommonAdapter(Contextcontext,Listdatas,intlayoutId){
this.mContext=context;
this.mDatas=datas;
this.mlayoutId=layoutId;
mInflater=LayoutInflater.from(context);
}
@Override
publicintgetCount(){
//TODOAuto-generatedmethodstub
returnmDatas.size();
}
@Override
publicTgetItem(intarg0){
//TODOAuto-generatedmethodstub
returnmDatas.get(arg0);
}
@Override
publiclonggetItemId(intarg0){
//TODOAuto-generatedmethodstub
returnarg0;
}
@Override
publicViewgetView(intarg0,Viewarg1,ViewGrouparg2){
//TODOAuto-generatedmethodstub
ViewHolderholder=ViewHolder.get(mContext,arg1,arg2,mlayoutId,
arg0);
convert(holder,getItem(arg0));
returnholder.getConvertView();
}
publicabstractvoidconvert(ViewHolderholder,Tt);
}
复制代码
以上的抽象方法convert(ViewHolderholder,Tt);就相当于以前通用代码中的
viewHolder.mTextView=(TextView)convertView.findViewById(R.id.id_tv_title);
viewHolder.mTextView.setText(Bean.getName());
找到控件的id再去设施setText等重复的代码方法中的参数ViewHolderholder,Ttholder就相当于以前通用代码中的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;
publicclassViewHolder{
/
SparseArray类存放View集合
/
privateSparseArraymViews;
/
/
privateintmPosition;
/
布局文件
/
privateViewmConvertView;
publicViewgetConvertView(){
returnmConvertView;
}
publicViewHolder(Contextcontext,ViewGroupparent,intlayoutId,
intposition){
this.mViews=newSparseArray();
this.mPosition=position;
this.mConvertView=LayoutInflater.from(context).inflate(layoutId,
parent,false);
this.mConvertView.setTag(this);
}
/
拿到一个ViewHolder对象
@paramcontext
@paramconvertView
@paramparent
@paramlayoutId
@paramposition
@return
/
publicstaticViewHolderget(Contextcontext,ViewconvertView,
ViewGroupparent,intlayoutId,intposition){
if(null==convertView){
returnnewViewHolder(context,parent,layoutId,position);
}else{
ViewHolderholder=(ViewHolder)convertView.getTag();
holder.mPosition=position;
returnholder;
}
}
/
通过控件的id获取对应的控件,如果没有则加入views
@paramviewId
@return
/
publicTgetView(intviewId){
Viewview=mViews.get(viewId);
if(null==view){
view=mConvertView.findViewById(viewId);
mViews.put(viewId,view);
}
return(T)view;
}
/
为TextView设置字符串
@paramviewId
@paramtext
@return
/
publicViewHoldersetText(intviewId,Stringtext){
TextViewtv=getView(viewId);
tv.setText(text);
returnthis;
}
/
为ImageView设置图片
@paramviewId
@paramdrawableId
@return
/
publicViewHoldersetImageResource(intviewId,intdrawableId)
{
ImageViewview=getView(viewId);
view.setImageResource(drawableId);
returnthis;
}
publicintgetPosition()
{
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;
publicclassMyAdapterextendsCommonAdapter{
publicMyAdapter(Contextcontext,Listdatas,intlayoutId){
super(context,datas,layoutId);
//TODOAuto-generatedconstructorstub
}
@Override
publicvoidconvert(ViewHolderholder,finalBeanbean){
//TODOAuto-generatedmethodstub
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混乱
/
finalCheckBoxcBox=(CheckBox)(holder.getView(R.id.cb));
if(cBox!=null)
{
cBox.setChecked(bean.isChecked());
cBox.setOnClickListener(newOnClickListener()
{
@Override
publicvoidonClick(Viewv)
{
bean.setChecked(cBox.isChecked());
}
});
}
}
}
复制代码
优化之后用适配器的时候就简单多了下面是实体类,item和MainActivity.java中的代码:
实体类:
复制代码
packagecom.example.mylistview.domain;
publicclassBean{
privateStringtitle;
privateStringdesc;
privateStringtime;
privateStringphone;
privatebooleanisChecked;
publicbooleanisChecked(){
returnisChecked;
}
publicvoidsetChecked(booleanisChecked){
this.isChecked=isChecked;
}
/
@paramtitle
@paramdesc
@paramtime
@paramphone
/
publicBean(Stringtitle,Stringdesc,Stringtime,Stringphone){
this.title=title;
this.desc=desc;
this.time=time;
this.phone=phone;
}
publicStringgetTitle(){
returntitle;
}
publicvoidsetTitle(Stringtitle){
this.title=title;
}
publicStringgetDesc(){
returndesc;
}
publicvoidsetDesc(Stringdesc){
this.desc=desc;
}
publicStringgetTime(){
returntime;
}
publicvoidsetTime(Stringtime){
this.time=time;
}
publicStringgetPhone(){
returnphone;
}
publicvoidsetPhone(Stringphone){
this.phone=phone;
}
}
复制代码
MainActivity.java:
重点代码:
参数有上下文,集合,和自己对应的item就可以了
adapter=newMyAdapter(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;
publicclassMainActivityextendsActivity{
privateListViewlistView;
privateListmDatas;
/
适配器
/
privateMyAdapteradapter;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
listener();
}
privatevoidlistener(){
//TODOAuto-generatedmethodstub
listView.setOnItemClickListener(newOnItemClickListener(){
@Override
publicvoidonItemClick(AdapterView>arg0,Viewarg1,intarg2,
longarg3){
//TODOAuto-generatedmethodstub
startActivity(newIntent(MainActivity.this,SecondActivity.class));
}
});
}
privatevoidinitData(){
//TODOAuto-generatedmethodstub
mDatas=newArrayList();
Beanbean=newBean("Android新技能Get",
"Android-打造万能的ListView和GridView适配器","2015-08-05","10086");
mDatas.add(bean);
bean=newBean("捡到权志龙一个",
"在星巴克捡到权志龙一个","2015-08-06","10086");
mDatas.add(bean);
bean=newBean("GetTOP一个",
"在韩国首尔捡到TOP一个","2015-08-07","10086");
mDatas.add(bean);
adapter=newMyAdapter(this,mDatas,R.layout.item);
listView.setAdapter(adapter);
}
privatevoidinitView(){
//TODOAuto-generatedmethodstub
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:mawww.baiyuewang.netxLines="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;
publicclassSecondAdapterextendsCommonAdapter |
|