Welcome

首页 / 移动开发 / Android / Android ListView万能适配器实例代码

ListView是开发中最常用的控件了,但是总是会写重复的代码,浪费时间又没有意义。
最近参考一些资料,发现一个万能ListView适配器,代码量少,节省时间,总结一下分享给大家。
首先有一个自定义的Adapter继承于BaseAdapter,下面是自定义的Adapter,精华在getView()方法中
package com.example.mylistview.util;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;public abstract class CommonAdapter<T> extends BaseAdapter { /*** 上下文*/ private Context mContext; /*** 实体类集合*/ private List<T> mDatas; private LayoutInflater mInflater; /*** 控件id*/ private int mlayoutId; public CommonAdapter(Context context, List<T> datas, int layoutId) {this.mContext = context;this.mDatas = datas;this.mlayoutId = layoutId;mInflater = LayoutInflater.from(context); } @Override public int getCount() {// TODO Auto-generated method stubreturn mDatas.size(); } @Override public T getItem(int arg0) {// TODO Auto-generated method stubreturn mDatas.get(arg0); } @Override public long getItemId(int arg0) {// TODO Auto-generated method stubreturn arg0; } @Override public View getView(int arg0, View arg1, ViewGroup arg2) {// TODO Auto-generated method stubViewHolder holder = ViewHolder.get(mContext, arg1, arg2, mlayoutId,arg0);convert(holder, getItem(arg0));return holder.getConvertView(); } public abstract void convert(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是需要自己声明的,以下是代码以及详细注释:
package com.example.mylistview.util;import android.content.Context;import android.graphics.Bitmap;import android.renderscript.Type;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;public class ViewHolder { /*** SparseArray类存放View集合*/ private SparseArray<View> mViews; /*** */ private int mPosition; /*** 布局文件*/ private View mConvertView; public View getConvertView() {return mConvertView; } public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) {this.mViews = new SparseArray<View>();this.mPosition = position;this.mConvertView = LayoutInflater.from(context).inflate(layoutId,parent, false);this.mConvertView.setTag(this); } /*** 拿到一个ViewHolder对象* @param context* @param convertView* @param parent* @param layoutId* @param position* @return*/ public static ViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId, int position) {if (null == convertView) { return new ViewHolder(context, parent, layoutId, position);} else { ViewHolder holder = (ViewHolder) convertView.getTag(); holder.mPosition = position; return holder;} } /*** 通过控件的id获取对应的控件,如果没有则加入views* @param viewId* @return*/ public <T extends View> T getView(int viewId) {View view = mViews.get(viewId);if (null == view) { view = mConvertView.findViewById(viewId); mViews.put(viewId, view);}return (T) view; } /*** 为TextView设置字符串 * @param viewId* @param text* @return*/ public ViewHolder setText(int viewId, String text) {TextView tv = getView(viewId);tv.setText(text);return this; } /** * 为ImageView设置图片 * * @param viewId * @param drawableId * @return */public ViewHolder setImageResource(int viewId, int drawableId){ ImageView view = getView(viewId); view.setImageResource(drawableId); return this;}public int getPosition(){ return mPosition;} }
再写一个Adapter继承于万能适配器CommonAdapter,还是要写一个自己的Adapter,因为一个项目可能会有多个ListView,但是每个的item元素,布局都会有所不同的,这个泪用来区分不同的ListView与自己所对应的item.这个代码量较少完全可以写成内部类在Activity.java中.
package com.example.mylistview.adapter;import java.util.List;import android.content.Context;import android.view.View;import android.view.View.OnClickListener;import android.widget.CheckBox;import com.example.mylistview.R;import com.example.mylistview.domain.Bean;import com.example.mylistview.util.CommonAdapter;import com.example.mylistview.util.ViewHolder;public class MyAdapter extends CommonAdapter<Bean> { public MyAdapter(Context context, List<Bean> datas, int layoutId) {super(context, datas, layoutId);// TODO Auto-generated constructor stub } @Override public void convert(ViewHolder holder, final Bean bean) {// TODO Auto-generated method stubholder.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(new OnClickListener() {@Overridepublic void onClick(View v){ bean.setChecked(cBox.isChecked());} });} }}
优化之后用适配器的时候就简单多了下面是实体类,item和MainActivity.java中的代码:
实体类:
package com.example.mylistview.domain;public class Bean { private String title; private String desc; private String time; private String phone; private boolean isChecked; public boolean isChecked() {return isChecked; } public void setChecked(boolean isChecked) {this.isChecked = isChecked; } /*** @param title* @param desc* @param time* @param phone*/ public Bean(String title, String desc, String time, String phone) {this.title = title;this.desc = desc;this.time = time;this.phone = phone; } public String getTitle() {return title; } public void setTitle(String title) {this.title = title; } public String getDesc() {return desc; } public void setDesc(String desc) {this.desc = desc; } public String getTime() {return time; } public void setTime(String time) {this.time = time; } public String getPhone() {return phone; } public void setPhone(String phone) {this.phone = phone; }}
MainActivity.java:
重点代码:
参数有上下文,集合,和自己对应的item就可以了
 adapter = new MyAdapter(this, mDatas, R.layout.item);


package com.example.mylistview.ui;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ListView;import com.example.mylistview.R;import com.example.mylistview.adapter.MyAdapter;import com.example.mylistview.domain.Bean;public class MainActivity extends Activity { private ListView listView; private List<Bean> mDatas; /*** 适配器*/ private MyAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();initData();listener(); } private void listener() {// TODO Auto-generated method stublistView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {// TODO Auto-generated method stubstartActivity(new Intent(MainActivity.this, SecondActivity.class)); }}); } private void initData() {// TODO Auto-generated method stubmDatas = new ArrayList<Bean>();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 void initView() {// TODO Auto-generated method stublistView = (ListView) findViewById(R.id.listView); }}
item布局:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" > <CheckBoxandroid:focusable="false"android:id="@+id/cb"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_centerInParent="true" /> <TextViewandroid: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" /> <TextViewandroid: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" /> <TextViewandroid: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" /> <TextViewandroid: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" /></RelativeLayout>
效果图:

用这个去适配另一个不同的布局:
新布局的Adapter一样继承自己的万能adapter:CommonAdapter
package com.example.mylistview.adapter;import java.util.List;import java.util.Map;import android.content.Context;import com.example.mylistview.R;import com.example.mylistview.util.CommonAdapter;import com.example.mylistview.util.ViewHolder;public class SecondAdapter extends CommonAdapter<Map<String, String>> { public SecondAdapter(Context context, List<Map<String, String>> datas, int layoutId) {super(context, datas, layoutId);// TODO Auto-generated constructor stub } @Override public void convert(ViewHolder holder, Map<String, String> t) {// TODO Auto-generated method stubholder.setText(R.id.tv_item2values, t.get("values")); }}
Activity.java代码:
package com.example.mylistview.ui;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import android.app.Activity;import android.os.Bundle;import android.widget.ListView;import com.example.mylistview.R;import com.example.mylistview.adapter.MyAdapter;import com.example.mylistview.adapter.SecondAdapter;public class SecondActivity extends Activity { private ListView listView_second; private SecondAdapter secondAdapter; private List<Map<String, String>> lists = new ArrayList<Map<String, String>>(); @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_second);initView();initData(); } private void initData() {// TODO Auto-generated method stubfor (int i = 0; i < 4; i++) { Map map = new HashMap<String, String>(); map.put("values", "条目" + i); lists.add(map);}secondAdapter = new SecondAdapter(this, lists, R.layout.item2);listView_second.setAdapter(secondAdapter); } private void initView() {// TODO Auto-generated method stublistView_second = (ListView) findViewById(R.id.listView_second); }}
item:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" ><TextViewandroid: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" /></LinearLayout>
效果图:

以上就是对Android ListView 的资料整理,希望能给大家带来帮助!