封装RecycleView的Adapter并实现列表展示

来源:互联网 发布:大数据清洗工具 编辑:程序博客网 时间:2024/05/14 20:06
**RecyclerView基本使用方法**,需为其添加的数据适配器是需要继承Recycle.Adapter,并指定泛型一个继承自RecyclerView.ViewHolder的类,并添加构造方法对Item中的子控件进行初始化。同时重写onCreateViewHolder()onBindViewHolder()getItemCount()3个方法。

此次封装简化了RecycleView的使用,不在需要考虑ViewHolder中的多个控件属性,我们只需要自定义一个Adapter(如下面的TestBeanAdapter)继承自SimpleAdapter类,并加载自身的构造函数,同时实现其中的bindData()方法即可,即为每个Item对应的View控件绑定数据。原理及实现均参看视频。

1.声明一个类BaseAdapter继承RecyclerView。ViewHolder。

指定泛型<T,H extends BaseViewHolder>,BaseViewHolder是继承RecyclerView.ViewHolder, T使我们无须关注使用者自定义的每个Item控件的类型,他会根据我们在初始化Adapter时传入的参数(ItemView对象化成Bean)来确定绑定数据bindDataa()方法中的参数, H extends BaseViewHolder是为了提供给使用者使用新的类型,我们可自定义ViewHolder来继承BaseViewHolder来作为新的参数类型。

public abstract class BaseAdapter<T,H extends BaseViewHolder> extends RecyclerView.Adapter<BaseViewHolder>{    //1.数据使用泛型    protected List<T> mDatas;    protected LayoutInflater mInflater;    protected Context mContext;    protected int mLayoutResId;    private OnItemClickListener listener;    public interface OnItemClickListener{        void OnClick(View view, int position);    }    public void setOnItemClickListener(OnItemClickListener listener){        this.listener = listener;    }    public BaseAdapter(Context context, List<T> datas, int layoutResId){        this.mDatas = datas;        this.mContext = context;        this.mLayoutResId = layoutResId;        mInflater = LayoutInflater.from(context);    }    @Override    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = mInflater.inflate(mLayoutResId,null,false);        return new BaseViewHolder(view, listener);    }    @Override    public void onBindViewHolder(BaseViewHolder holder, int position) {        T t = getItem(position);        bindData(holder,t);    }    @Override    public int getItemCount() {        return mDatas.size();    }    public T getItem(int postion){        return mDatas.get(postion);    }    public abstract  void bindData(BaseViewHolder viewHolder, T t);}

2.新建一个BaseViewHolder继承自RecyclerView.ViewHolder并实现OnclickListener.

public class BaseViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{    private BaseAdapter.OnItemClickListener listener;    private SparseArray<View> views;    public BaseViewHolder(View itemView, BaseAdapter.OnItemClickListener listener) {        super(itemView);        //mItemView = itemView;        views = new SparseArray<>();        this.listener = listener;        itemView.setOnClickListener(this);    }
    public View getView(int id){        return findView(id);    }    public TextView getTextView(int id){        return findView(id);    }    public ImageView getImageView(int id){        return findView(id);    }    public Button getButtonView(int id){        return findView(id);    }    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;    }    @Override    public void onClick(View v) {        listener.OnClick(v,getLayoutPosition());    }}

3.SimpleAdapter继承BaseAdapter

为了减少一个泛型参数。并添加构造函数,初始化参数。
public abstract class SimpleAdapter<T> extends BaseAdapter<T,BaseViewHolder>{    public SimpleAdapter(Context context, List<T> datas, int layoutResId) {        super(context, datas, layoutResId);    }}

4.新建一个TestBeanAdapter 继承自SimpleAdapter对象即。

添加构造函数,并覆写bindData()方法,即在此方法中为每个Item中的View进行初始化赋值。

public class TestBeanAdapter extends SimpleAdapter<TestBean>{      //新建的TestBeanAdapter就直接使用定好的布局文件    public TestBeanAdapter(Context context, List<TestBean> datas) {        super(context, datas, R.layout.test_adapter_item);    }    @Override    public void bindData(BaseViewHolder viewHolder, TestBean testBean) {    //为每个Item添加并绑定数据        TextView tv_test_item_left = (TextView) viewHolder.getView(R.id.tv_test_item_left);       //条目布局文件中的子控件        TextView tv_test_item_right = viewHolder.getTextView(R.id.tv_test_item_right);  //直接用在ViewHolder中封装好的函数        tv_test_item_left.setText(testBean.getName());        tv_test_item_right.setText(testBean.getSex());    }}

5.使用方法

使用时需新建步骤(12)或(1234)中的类文件,对应使用下面(1)或(2)的使用方法。注意:在使用LinearLayoutManager时会出现每个Item只能占据一部分,即不能适配Item的布局(原因暂时未知,有人解释是RecyclerView的bug),将其改为GridLayoutManager就能进行适配布局。其中参数datas,为TestBean的一个数组,而TestBean是一个将Item中的View进行赋值而保存的JavaBean。
rl_test = (RecyclerView)mView.findViewById(R.id.rl_test);        GridLayoutManager layoutManager = new GridLayoutManager(getContext(),1);          //用LinearLayoutManager会出现问题,每个Item只会占据有内容的一部分        //LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());        rl_test.setLayoutManager(layoutManager);
for(int i = 0;i<10;i++){            TestBean bean = new TestBean("sannas"+ i,"man");            datas.add(bean);        }
public class TestBean {    private String name;    private String sex;    public TestBean(String name, String sex) {        this.name = name;        this.sex = sex;    }    public String getSex() {        return sex;    }    public void setSex(String sex) {        this.sex = sex;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}

(1)直接使用BaseAdapter。

BaseAdapter<TestBean,BaseViewHolder> mAdatper = new BaseAdapter<TestBean,BaseViewHolder>(getContext(),datas,R.layout.test_adapter_item) {            //R.layout.test_adapter_item为每个条目的布局文件            @Override            public void bindData(BaseViewHolder viewHolder, TestBean testBean) {                TextView tv_test_item_left = (TextView) viewHolder.getView(R.id.tv_test_item_left);       //条目布局文件中的子控件                TextView tv_test_item_right = viewHolder.getTextView(R.id.tv_test_item_right);  //直接用在ViewHolder中封装好的函数                tv_test_item_left.setText(testBean.getName());                tv_test_item_right.setText(testBean.getSex());            }        };        mAdatper.setOnItemClickListener(new BaseAdapter.OnItemClickListener() {            @Override            public void OnClick(View view, int position) {                //                Toast.makeText(getActivity(),"点击了第"+ position +"个Item",Toast.LENGTH_SHORT).show();            }        });                rl_test.setAdapter(mAdatper);

(2)使用将Item的View对象的值实例化成为一个Bean对象之后并进行初始化之后的TestBeanAdapter。

TestBeanAdapter mAdatper = new TestBeanAdapter(getContext(),datas); mAdatper.setOnItemClickListener(new BaseAdapter.OnItemClickListener() {            @Override            public void OnClick(View view, int position) {                Toast.makeText(getActivity(),"点击了第"+ position +"个Item",Toast.LENGTH_SHORT).show();            }        });        rl_test.setAdapter(mAdatper);

6.实现效果

0 0