适配器模式 对 BaseAdapter 抽取封装,减少代码冗余。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lijia1201900857/article/details/79129189

 BaseAdapter 适配器,是我们经常使用的。可能一个项目中都有十几甚至几十个。细心的同学可能会发现,每一个适配器的结构基本相同,这就让我们想到了代码抽取。

 BaseAdater 本身使用的就是适配器模式。相信大家对这种模式都很了解,所以今天就使用适配器模式对BaseAdapter 的代码进行抽取封装。接下来会对比普通写法和封装完之后的写法:

首先:通常的写法

ListView 的 item.xml 布局

<?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">

    <TextView
        android:padding="10dp"
        android:text="姓名"
        android:id="@+id/item_name_tv"
        android:layout_width="match_parent"
        android:layout_height="40dp" />

</LinearLayout>
ListView 的适配器:MyAdapter.class

public class MyAdapter extends BaseAdapter {
	private Context mContext;
	private List<String> mList;

	public MyAdapter(Context mContext,List<String> mList) {
		this.mContext=mContext;
		this.mList=mList;
	}

	@Override
	public int getCount() {
		return mList != null ? mList.size() : 0;
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return mList != null ? mList.get(position) : null;
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder=null;
		if(convertView==null){
			convertView=LayoutInflater.from(mContext).inflate(R.layout.item, parent,false);
			holder=new ViewHolder(convertView);
			convertView.setTag(holder);
		}else{
			holder=(ViewHolder)convertView.getTag();
		}
		holder.nameTv.setText("姓名:"+mList.get(position));
		return convertView;
	}
	
	private class ViewHolder{
		private TextView nameTv;
		public ViewHolder(View view) {
			if(view==null)
				return;
			nameTv=(TextView)view.findViewById(R.id.item_name_tv);
		}
	}
}
数据展示:

public class MainActivity extends Activity {
	private ListView mListView;
	private List<String> mList=new ArrayList<String>();
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mListView=(ListView)findViewById(R.id.listview);
		getData();
		MyAdapter adapter=new MyAdapter(this, mList);
		mListView.setAdapter(adapter);
	}
	//获取数据
	private void getData() {
		for (int i = 0; i < 10; i++) {
			mList.add("小明:"+i);
		}
	}
}
效果:


这是常用的写法。但是适配器多了你会发现

@Override
 public int getCount() {}

@Override
 public Object getItem(int position) { }

@Override
 public long getItemId(int position) {}

@Override
 public View getView(int position, View convertView, ViewGroup parent) {
}

这几个方法一直在不断的重复编写,这样写我是看不下去的。所以封装之路刻不容缓。

但是:要对试用多有的Adapter 需要解决以下问题

 1、数据对象基本都不相同,不能写死

 2、展示的View 布局基本不相同,不能写死

所以,这里就需要使用泛型


上代码:

AbsBaseAdapter.class

 T 对象泛型 ; H ViewHolder 泛型

public abstract class AbsBaseAdapter<T,H extends AbsBaseAdapter.IViewHolder> extends BaseAdapter {
	public Context mContext;
	public List<T> mList;
	private LayoutInflater mInflater;
	private int layoutId;// 布局id
	public AbsBaseAdapter(Context mContext,int layoutId) {
		this.mContext = mContext;
		this.layoutId=layoutId;
		mInflater = LayoutInflater.from(mContext);
		mList=new ArrayList<T>();
	}

    /**
     * 设置数据
     * */
    public boolean addElements(List<T> mList) {
        if (this.mList != null)
            return this.mList.addAll(mList);
        else
            return false;
    }

	@Override
	public int getCount() {
		return mList != null ? mList.size() : 0;
	}

	@Override
	public T getItem(int position) {
		return mList != null ? mList.get(position) : null;
	}

	@Override
	public long getItemId(int position) {
		return position;
	}
	
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		H holder = null;
		if (convertView == null) {
			convertView = mInflater.inflate(layoutId, parent, false);
			holder = createViewHolder(convertView);
			convertView.setTag(holder);
		} else {
			holder = (H) convertView.getTag();
		}
		
		convertView(mList.get(position), position, holder);
		return convertView;
	}
	// 创建ViewHoler
	public abstract H createViewHolder(View view); 
	// 给布局设置数据
	public abstract void convertView(T bean,int position,H holder);
	
	//所有 ViewHolder 都需要实现该接口
	public interface IViewHolder{
	}
}

然后让 MyAdapter 继承 AbsBaseAdapter 。

在看MyAdapter的代码    MyAdapter.class

public class MyAdapter extends AbsBaseAdapter<String, MyAdapter.ViewHolder> {
	
	public MyAdapter(Context mContext) {
		super(mContext, R.layout.item);
	}

	@Override
	public ViewHolder createViewHolder(View view) {
		return new ViewHolder(view);
	}
	
	@Override
	public void convertView(String bean, int position, ViewHolder holder) {
		holder.nameTv.setText("姓名:"+bean);
	}
	
	class ViewHolder implements AbsBaseAdapter.IViewHolder{
		private TextView nameTv;
		public ViewHolder(View view) {
			if(view==null)
				return;
			nameTv=(TextView)view.findViewById(R.id.item_name_tv);
		}
	}


}
是不是非常的简洁,清晰!!!

然后 在Activity 中使用:

public class MainActivity extends Activity {
	private ListView mListView;
	private List<String> mList=new ArrayList<String>();
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mListView=(ListView)findViewById(R.id.listview);
		getData();
		MyAdapter adapter=new MyAdapter(this);
		adapter.addElements(mList);
		mListView.setAdapter(adapter);
	}
	//获取数据
	private void getData() {
		for (int i = 0; i < 10; i++) {
			mList.add("小明:"+i);
		}
	}
}
到这里 就大功告成。

以后再写Adapter 时,可以直接继承AbsAdapter 这个类。

你还可以在AbsAdapter 中继续扩展一些可能用到的方法。例如

/**
	 * 添加单个数据
	 */
	public boolean addElement(T bean) {
		if (mList != null)
			return mList.add(bean);
		else
			return false;
	}

	/**
	 * 添加数据到指定位置
	 */
	public void addElement(int position, T bean) {
		if (mList != null)
			mList.add(position, bean);
	}

	/**
	 * 根据position添加数据
	 */
	public boolean addElements(int position, List<T> mList) {
		if (this.mList != null)
			return this.mList.addAll(position, mList);
		else
			return false;
	}

	/**
	 * 根据postion 删除数据
	 */
	public T removeElement(int position) {
		if (mList != null)
			return mList.remove(position);
		else
			return null;
	}

	/**
	 * 删除
	 */
	public boolean removeElement(T bean) {
		if (mList != null)
			return mList.remove(bean);
		else
			return false;
	}









猜你喜欢

转载自blog.csdn.net/lijia1201900857/article/details/79129189