BaseAdapter的封装

本文详细介绍RecyclerView的使用方法,包括自定义Adapter与ViewHolder的过程,并进一步封装BaseAdapter与BaseViewHolder以简化开发流程,提升代码复用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码如下:

首先介绍一下RecyclerView的常规用法:

package com.crs.demo.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.crs.demo.R;

import java.util.ArrayList;

/**
 * Created on 2016/9/8.
 * Author:crs
 * Description:RecyclerView的adapter
 * 1)自定义Adapter继承自RecyclerView.Adapter 记住是哪个包下的adapter.RecyclerView.Adapter是抽象类,必须实现其中的抽象方法.
 * 2)给RecyclerView.Adapter设置泛型类型,为<自定义adapter.自定义Viewholder>(固定格式)
 * 3)自定义ViewHolder继承自RecyclerView.ViewHolder,记住是RecyclerView下的ViewHolder
 * 4)onCreateViewHolder()方法的返回值类型为<自定义adapter.自定义Viewholder> onBindViewHolder()方法里面的holder类型也是<自定义adapter.自定义Viewholder>
 * 要不然找不到控件的
 * 5)定义的ViewHolder是一个内部类,RecyclerView.Adapter在继承时需要指定泛型.要制定ViewHolder是谁的内部类.
 * 6)记住这三个方法onCreateViewHolder() onBindViewHolder() getItemCount() LinearLayoutManager RecyclerView.Adapter  RecyclerView.ViewHolder
 * 7)itemView 指代当前条目。需要一个ViewHolder,就创建并返回。
 * 8)RecyclerView的使用,先设置布局管理器,在设置适配器。
 */
public class TestRecyclerAdapter extends RecyclerView.Adapter<TestRecyclerAdapter.ViewHolder> {
    private ArrayList<String> list;
    private LayoutInflater mInflate;

    public TestRecyclerAdapter(Context context, ArrayList<String> list) {
        this.list = list;
        mInflate = LayoutInflater.from(context);
    }

    @Override
    public TestRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mInflate.inflate(R.layout.item_test_recycler, null);
        ViewHolder myHolder = new ViewHolder(view);
        return myHolder;
    }

    @Override
    public void onBindViewHolder(TestRecyclerAdapter.ViewHolder holder, int position) {
        String title = list.get(position);
        holder.tv.setText(title);
    }

    @Override
    public int getItemCount() {
        return list.size();
    }


    class ViewHolder extends RecyclerView.ViewHolder {
        TextView tv;

        public ViewHolder(View itemView) {
            super(itemView);
            tv = (TextView) itemView.findViewById(R.id.tv);
        }
    }
}

BaseAdapter的封装:

主要有两大功能:

1)通过抽象方法绑定数据

2)通过接口回调设置点击事件


对RecyclerView.Adapter进行封装

对RecyclerView.ViewHolder进行封装

package com.crs.demo.base;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

/**
 * Created on 2016/9/8.
 * Author:crs
 * Description:BaseAdapter
 * 1)在创建继承自BaseAdapter的类的时候,指定传递的数据类型和ViewHolder类型
 * 2)抽象方法中为什么药传递holder参数,因为要实例化控件.
 * 3)定义接口,添加条目点击事件的公共回调方法,接口里面的抽象方法什么时候调用? 条目点击的时候,条目点击在BaseViewHolder里面
 * 所以必须通过构造函数传递过去.
 * 4)在不确定类型的时候,使用泛型来标识.每次传递的数据类型不确定,所以使用泛型。
 * 5)抽取公共的事情,让父类来做,比如:根据id创建view,条目的点击事件,绑定数据.
 * 6)基类里面提供常用的方法。
 * 7)抽取与封装是不一样的。 向上抽去基类。(子类原来越少,而父类越来越多)
 */
public abstract class BaseAdapter<T, H extends BaseViewHolder> extends RecyclerView.Adapter<BaseViewHolder> {
    //由于需要让子类继承,所以不能私有.
    public List<T> list;
    public LayoutInflater mInflate;
    public int mLayoutResId;

    //初始化父类的构造方法,让子类创建对象的时候,调用
    public BaseAdapter(List<T> list, Context context, int mLayoutResId) {
        this.list = list;
        this.mInflate = LayoutInflater.from(context);
        this.mLayoutResId = mLayoutResId;
    }


    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mInflate.inflate(mLayoutResId, null);
        //在构造方法里面传递接口对象
        BaseViewHolder baseViewHolder = new BaseViewHolder(view, onItemClickListener);
        return baseViewHolder;
    }

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        //获取数据对象
        T t = list.get(position);
        //通过抽象方法对调进行对外暴露,用于绑定数据,让子类实现(数据、holder代表控件)
        bindData(t, holder);
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    //定义一个抽象方法,让子类实现
    public abstract void bindData(T t, BaseViewHolder holder);

    //条目点击事件,接口回调。
    private OnItemClickListener onItemClickListener;
    public interface OnItemClickListener {
        void OnItemClick(View view, int position);
    }
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

}
BaseViewHolder的封装:

package com.crs.demo.base;

import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.View;

/**
 * Created on 2016/9/8.
 * Author:crs
 * Description:BaseViewHolder
 * 1)如何去获取控件以及确定控件类型,现在不清楚控件的类型以及数量.不能把控件写死,通过View数组来实现
 * 2)<T extends View> T 定义返回值的泛型类型;在返回的时候,进行强转
 */
public class BaseViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    //用于存储条目中的控件
    private final SparseArray<View> views;
    private BaseAdapter.OnItemClickListener onItemClickListener;

    //父类中只有有构造函数,子类在继承父类时,必须添加对应的构造函数
    public BaseViewHolder(View itemView, BaseAdapter.OnItemClickListener onItemClickListener) {
        super(itemView);
        this.onItemClickListener = onItemClickListener;
        views = new SparseArray<>();
        //为条目设置点击事件
        itemView.setOnClickListener(this);
    }

    //实例化控件
    private <T extends View> T findView(int id) {
        View view = views.get(id);
        if (view == null) {
            view = itemView.findViewById(id);
            views.put(id, view);
        }
        return (T) view;
    }

    //对外提供公共的方法,去实例化控件
    public View getViews(int id) {
        return findView(id);
    }

    @Override
    public void onClick(View v) {
        if (onItemClickListener != null) {
            onItemClickListener.OnItemClick(v,getLayoutPosition());
        }
    }
}

使用:TextAdapter继承自BaseAdapter

package com.crs.demo.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

import com.crs.demo.R;
import com.crs.demo.base.BaseAdapter;
import com.crs.demo.base.BaseViewHolder;

import java.util.List;

/**
 * Created on 2016/9/8.
 * Author:crs
 * Description:TestAdapter
 * 1)在继承的时候指定数据类型和BaseViewHolder类型
 * 2)在自定义的adapter中哪些是变化的: 条目布局、集合里面存放的数据类型、控件数量以及控件类型
 * 3)让自定义的Adapter实现抽象方法(数据绑定通过抽象方法来实现)
 */
public class TestAdapter extends BaseAdapter<String, BaseViewHolder> {


    public TestAdapter(List<String> list, Context context) {
        //需要传递一个条目布局进去
        super(list, context, R.layout.item_test_adapter);
    }


    @Override
    public void bindData(String s, BaseViewHolder holder) {
        TextView tv = (TextView) holder.getViews(R.id.tv);
        tv.setText(s);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值