ListView 用 MVC 进行封装
在ListView中就是一个很具体的MVC设计思想的使用,主要的方法如下实现
- 创建一个SuperBaseAdapter 继承 BaseAdapter , 实现里面的四个方法,因为SuperBaseAdapter是根据数据来展示UI的,因此在 new SuperBaseAdapter() 的时候需要传入具体的List的数据类型 。
- 而在SuperBaseAdapter 中是因为写的基类,无法确定是哪一种数据类型 ,所有类应该是SuperBaseAdapter extends BaseAdapter{}
- 在构造函数中需要将这个数据进行保存,因此构造函数写为SuperBaseAdapter(List datas);
- getCount() 、getItem(int position) 和 getItemId(int position)实现这三个方法
- 在 getView() 的方法中无非就是做两件事
- 初始化View
- 给View设置数据
- 因此不难看出 在 getView() 中又是一个小的 MVC 了,M –> 给View设置数据,V –> 初始化View , 而 C –> 是Holder,因此,新建一个 BaseHolder 的类,这个类要做的事情就是展示View,设置数据 , 所以里面必定会有两个方法,一个是展示View 的 public View getRootView();和设置数据 的 public void setData(T data)。
- 但是,这个 BaseHolder 的类它是个基类,自己不知道View和data长成啥样,因此在 BaseHolder 的构造其中要调用一个抽象方法,这个方法就是设置View的 protected abstract View initView();构造器得到的View后保存下来(成员变保存即可),在getRootView()方法中返回这个view。而设置数据也一样,调用抽象方法来设置数据,创建的抽象方法为 protected abstract void refreshUI(T data);最后,将这个类设置为抽象类即可
- 在 BaseHolder 设置为抽象类后,就到 SuperBaseAdapter 这个类报错了,因为 new BaseHolder() 是个抽象类,得实现里面的抽象方法;我们知道 SuperBaseAdapter 也是一个基类,它也不知道View和Datas 长成啥样,所以它不能 new BaseHolder();那么,只能让子类去实现咯,谁用谁知道嘛,所以提供一个抽象方法,这个抽象方法就是返回一个 BaseHolder 的子类就行了。
- BaseHolder 的子类获得了,就剩下调用 BaseHolder 的方法来设置View和数据啦,还有,得把 SuperBaseAdapter 设置成抽象类。这下就是子类具体实现了
- 还有一个问题,就是在 SuperBaseAdapter的子类具体实现中可能会用到 Context,因此可以 在 BaseHolder 中设置一个成员变量来获取这个值,将这个Context成员变量设置为 protected 类型即可,这样,在 SuperBaseAdapter 的子类中就可以直接使用啦。当然,获取这个 Context 的方法有很多,也不一定需要这样的
主要的代码实现如下
MainActivity 类
package com.example.listviewmvc;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
public class MainActivity extends Activity {
private ListView mLv;
private List<String> mDatas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLv = (ListView) findViewById(R.id.ls);
mDatas = new ArrayList<String>();
for (int i = 0; i < 30; i++) {
mDatas.add("我是第" + i + "个Item");
}
mLv.setAdapter(new ListAdapter(mDatas));
}
private class ListAdapter extends MyAdapter<String> {
public ListAdapter(List<String> datas) {
super(datas);
}
@Override
public HolderController getInstance() {
return new Holder(getApplicationContext());
}
}
}
Holder 类
package com.example.listviewmvc;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
public class Holder extends BaseHolder<String>{
public Holder(Context context) {
super(context);
}
private TextView tv1;
private TextView tv2;
private TextView tv3;
@Override
public View initView() {
View view = View.inflate(mContext, R.layout.ss, null);
tv1 = (TextView) view.findViewById(R.id.tv1);
tv2 = (TextView) view.findViewById(R.id.tv2);
tv3 = (TextView) view.findViewById(R.id.tv3);
return view;
}
@Override
public void refreshen(String data) {
tv1.setText(data);
tv2.setText(data);
tv3.setText(data);
}
}
SuperBaseAdapter 类
package com.example.listviewmvc;
import java.util.List;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
public abstract class SuperBaseAdapter<T> extends BaseAdapter {
protected List<T> mDatas;
/* 需要展示什么 样的数据我不知道,谁用谁知道 */
public SuperBaseAdapter(List<T> datas) {
this.mDatas = datas;
}
@Override
public int getCount() {
if (mDatas != null) {
return mDatas.size();
}
return 0;
}
@Override
public Object getItem(int position) {
if (mDatas != null) {
return mDatas.get(position);
}
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
BaseHolder holder = null;
//
if (convertView == null) {
// 获取 BaseHolder 的实例
holder = getInstance();
// ############# 1. 初始化View ############################
convertView = holder.getRootView();
// convertView = View.inflate(getApplicationContext(), R.layout.ss,
// null);
// holder.tv1 = (TextView) convertView.findViewById(R.id.tv1);
// holder.tv2 = (TextView) convertView.findViewById(R.id.tv2);
// holder.tv3 = (TextView) convertView.findViewById(R.id.tv3);
// 设置标记
convertView.setTag(holder);
} else {
holder = (BaseHolder) convertView.getTag();
}
// ################ 2. 给view设置数据 #####################
// String str = mDatas.get(position);
// holder.tv1.setText(str);
// holder.tv2.setText(str);
// holder.tv3.setText(str);
holder.setDats(mDatas.get(position));
return convertView;
}
// private class Holder{
// TextView tv1;
// TextView tv2;
// TextView tv3;
// }
/**
** 获取 BaseHolder 的实例
** @return
*/
public abstract BaseHolder getInstance();
}
BaseHolder 类
package com.example.listviewmvc;
import android.content.Context;
import android.view.View;
public abstract class BaseHolder<T> {
protected View mRootView;
protected Context mContext;
public BaseHolder(Context context){
this.mContext = context;
this.mRootView = initView();
}
/**
* 获取 View
* @return
*/
public View getRootView(){
return mRootView;
}
/**
* 给View设置数据
* @param data
*/
public void setDats(T data){
refreshen(data);
}
/**
* 初始化View
* @return
*/
public abstract View initView();
/**
* 刷新 UI
* @param data
*/
public abstract void refreshen(T data);
}