叨叨
listview在开发中经常用到,因此adapter也是经常用到的东西,写多了难免会觉得比较麻烦,每次都写同样的代码。
特别是实现重用这块,经常要写重复的代码,有时还需要在同一个方法只处理复杂的逻辑,这种写法在一定程度上提会影响可读性。
所以抽空写了一个基类的adapter和holder,这里用butterknife注解来实现绑定view,并且解除了holder和adapter之间的耦合性,避免了有些情况下在adapter内部进行的复杂的逻辑处理。实现逻辑处理与view展示的分离。
详细
adapter分离view实例化
通常都是用inflate来实例化view,这里将它抽取出来,子类的adapter只要将其所要实例化的view的布局的资源引用id传过来就可以
@Override
public View getView(int position, View convertView, ViewGroup parent) {
BaseHolder holder=null;
if (convertView == null) {
holder = getHolder(mContext);
convertView = View.inflate(mContext, getView(), null);
ButterKnife.bind(holder, convertView);//用butterKnife绑定
convertView.setTag(holder);
} else {
holder = (BaseHolder) convertView.getTag();
}
holder.setData(position,mData);
return convertView;
}
抽象方法getView()
/**
*
* @return 返回布局的资源文件id
*/
protected abstract int getView();
分离holder
从上面的getView方法中,可以看到,这里依然用的是holder来实现view的数据设置
通过getHolder(Context context)方法来获得需要的holder
这里将holder抽取出来,通过泛型来传递数据
public abstract class BaseHolder<T>
{
/**
* 设置要显示的数据
* @param data 数据,转换成对应的数据对象
* @param position 当前item的位置
*/
public abstract void setData(int position,T data);
}
子类只要继承它,然后传入对应的数据类型的data就可以。
adapter完整代码
基类adapter
public abstract class NewBaseAdapter<T> extends BaseAdapter {
protected Context mContext;
protected T mData;
public NewBaseAdapter(Context context){
mContext=context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
BaseHolder holder=null;
if (convertView == null) {
holder = getHolder(mContext);
convertView = View.inflate(mContext, getView(), null);
ButterKnife.bind(holder, convertView);//用butterKnife绑定
convertView.setTag(holder);
} else {
holder = (BaseHolder) convertView.getTag();
}
holder.setData(position,mData);//将数据传给holder
return convertView;
}
/**
* 返回对应的holder类
* @param context 引用
* @return 返回对应的holder子类,需要继承自BaseHolder
*/
protected abstract BaseHolder getHolder(Context context);
/**
*
* @return 返回布局的资源文件id
*/
protected abstract int getView();
/**
* 设置数据
* @param data 对应的数据
*/
public void setData(T data){
mData=data;
}
}
使用实例
adapter
<pre name="code" class="java">public class HeheAdapter extends NewBaseAdapter<TestBean> {
public HeheAdapter(Context context) {
super(context);
}
@Override
protected BaseHolder getHolder(Context context) {
return new HeheHolder();
}
@Override
protected int getView() {
return R.layout.item_layout;
}
@Override
public int getCount() {
if(mData==null){
return 0;
}
return mData.getSize();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
}
holder:
public class HeheHolder extends BaseHolder<TestBean> {
@Bind(R.id.item_tv)
TextView mTvItem;
@Override
public void setData(int position, TestBean data) {
mTvItem.setText(data.showLog()+":"+position);
}
testBean:
<span style="font-size:10px;">public class TestBean {
public String showLog(){
Log.d("adapterdemo", "testbean");
return "testBean";
}
public int getSize(){
return 10;
}
}</span><span style="font-size:18px;">
</span>
mainactivity:
public class MainActivity extends AppCompatActivity {
@Bind(R.id.listview)
ListView mListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initView();
}
private void initView() {
HeheAdapter adapter=new HeheAdapter(this);
TestBean testBean = new TestBean();
adapter.setData(testBean);
mListView.setAdapter(adapter);
}
}
布局文件就不写了,只有一个listview控件。
虽然看起来需要创建多个类,好像是比在adatper中直接实例复用、设置view显示逻辑复杂了,但是这里只是很简单的给view设置数据,如果碰到不同情况下不同view复用时根据不同的状态值来显示不同的布局或者数据时就有很大的作用了,会简化adapter中的代码量,往往不同的item布局之间只需要一个holder就能切换布局以及设置数据。
放上全部demo代码http://download.csdn.net/detail/chniccs/9499083