物尽其用,偷懒有理(来封装一个ListView)

来深圳一个星期,终于安定下来了,一片新的土地上我准备迎接一个新的开始,刚刚坐在床上想,工作了那么久,却很少有记录的习惯,导致新的东西一直在迭代,旧的事物快被想不起来,真是应了那句老话:茕茕白兔,东走西顾,衣不如新,人不如故。

好了不伤感了,开始今天的主题:ListView;
开始之前先说一点废话,之前带过两个实习生:只知道埋头苦干,做什么都不求甚解,跟刚毕业时候的我真是别无二样,比如,我问他们,你们是怎么理解ListView的? 居然支支吾吾答不上来,我说说我的理解吧,

我觉得得先从字面上解释,ListView就是一个以列表方式呈现的视图,它由一排透明的盒子组成,如果盒子里没有东西,那它就是透明的显示在屏幕上,而至于装什么东西,完全取决于你,装一个文本框,装一张图片,装一个复选框,甚至装一个fragment都随便你,而这些盒子,就是我们说的items,紧接着,我们要考虑一下,怎么装,装的数量,装的东西从哪儿来,于是就用到了适配器,适配器就是帮助你有序的解决这些问题的。

在日常的开发中,ListView基本是最常用的控件之一了,我们经常要写,至于ListView的优化,这里就不多讲了,很多人都能倒背如流了吧?
重点来了,既然ListView每天要用,是不是就会产生很多重复代码?
你在写的时候,有没有想过,把ListView的适配过程封装起来,让代码显得更简洁,自己也少做一点无用功。

反正我想过,先贴一段正常的ListView适配代码,观察一下哪里有封装的余地。

引用 Ctpublic class MyListViewAdapter extends BaseAdapter {
List data = new ArrayList();
Context context;
boolean idRefush = false;

public MyListViewAdapter(List<GiftInfo> data, Context context) {
    super();
    this.data = data;
    this.context = context;
}


public void setData(List<GiftInfo> data) {
    if (idRefush) {
        this.data.clear();
    }
    this.data.addAll(data);
    notifyDataSetChanged();
}


@Override
public int getCount() {
    return data.size();
}

@Override
public Object getItem(int position) {
    return data.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View view, ViewGroup parent) {
    if (view == null) {
        view = LayoutInflater.from(context).inflate(R.layout.items, parent,
                false);
        ImageView imageView = (ImageView) view
                .findViewById(R.id.imageView1);
        TextView textView = (TextView) view.findViewById(R.id.textView1);
        TextView remain=(TextView) view.findViewById(R.id.remain);
        TextView content=(TextView) view.findViewById(R.id.content);

        ViewHolder holder = new ViewHolder(imageView, textView, remain, content);
        view.setTag(holder);
    }
    GiftInfo giftInfo = data.get(position); // 加载文字
    ViewHolder holder = (ViewHolder) view.getTag();
    holder.textView.setText(giftInfo.getName());
    holder.remain.setText(giftInfo.getRemain()+"");
    holder.content.setText(giftInfo.getContent());

    ImageListener listener = ImageLoader.getImageListener(
            holder.imageView,// 加载图片
            R.drawable.checkbox_uncheck,
            R.drawable.vpi__tab_selected_pressed_holo);
    MyApp.loader.get(giftInfo.getIcon(), listener);

    return view;
}

public class ViewHolder {
    ImageView imageView;
    TextView textView,remain,content;



    public ViewHolder(ImageView imageView, TextView textView,
            TextView remain, TextView content) {
        super();
        this.imageView = imageView;
        this.textView = textView;
        this.remain = remain;
        this.content = content;
    }



    public ViewHolder() {
    }

}

}rl + Q

看完头昏脑涨有没有,先看看我写的封装类和平时的有什么不同

Ctpublic abstract class AbsBaseAdapter extends BaseAdapter{
private Context context;
private List datas;
private int resid;

public AbsBaseAdapter(Context context, int resid){
    this.context = context;
    this.resid = resid;
    datas = new ArrayList<>();
}

public void setDatas(List<T> datas){
    this.datas.clear();
    addDatas(datas);
}

public void addDatas(List<T> datas){
    this.datas.addAll(datas);
    this.notifyDataSetChanged();
}


@Override
public int getCount() {
    return datas.size();
}

@Override
public Object getItem(int position) {
    return datas.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder = null;
    if(convertView != null){
        viewHolder = (ViewHolder) convertView.getTag();
    } else {
        convertView = LayoutInflater.from(context).inflate(resid, null);
        viewHolder = new ViewHolder(convertView);
        convertView.setTag(viewHolder);
    }

    //从数据源中获得数据,依次放入ViewHodler中的控件里
    bindDatas(viewHolder, datas.get(position));
    return convertView;
}

public abstract void bindDatas(ViewHolder viewHolder, T data);

/**
 * ViewHolder主要是用来缓存布局页面中的子控件,避免下一次使用时还需要findViewById
 */
class ViewHolder{
    View layoutView;
    Map<Integer, View> mapCache = new HashMap<>();

    public ViewHolder(View layoutView) {
        this.layoutView = layoutView;
    }

    public View getView(int id){
        View view = null;
        if(mapCache.containsKey(id)){
            view = mapCache.get(id);
        } else {
            view = layoutView.findViewById(id);
            mapCache.put(id, view);
        }
        return view;
    }
}

}rl + Q

看到了吗?我把我的封装类写成了一个抽象类,还指定泛型为任意,
再看到我在构造方法里放的两个参数:
第一是上下文对象,第二个我放的是你的资源ID,也就是你的items的位置
然后我加了一个setData方法,我们在这个方法里添加和刷新数据

最重要的一步到了,看到了我的抽象方法:bindData()没有?
然后你跟我说说,里面的参数有什么?是什么viewHolder对象和你每一个view的位置?
接下来我们要做的是什么,你可以告诉我吗?
对,我们用一个类去继承我们的封装类,,在构造方法里传进你的资源id,然后复写他的抽象方法,就可以了。
那些listview的优化,你还用去考虑吗?
送佛送到西,贴一个实现的封装的例子,看看什么是简洁代码
Ct`public class MyAdapter extends AbsBaseAdapter{

public MyAdapter(Context context) {
    super(context, R.layout.item_layout);
}

@Override
public void bindDatas(ViewHolder viewHolder, NewsEntity data) {
    ImageView iv = (ImageView) viewHolder.getView(R.id.iv_id);
    iv.setImageResource(R.mipmap.ic_launcher);

    TextView tv = (TextView) viewHolder.getView(R.id.tv_id);
    tv.setText(data.getTitle());
}

}`rl + Q

这里用到了一点java的继承思想,不知道有人犯迷糊了没有,如果有,欢迎一起讨论,千万别憋着。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值