recyclerView 自定义适配器

本文介绍如何在Android 5.0中使用RecyclerView替代GridView和ListView,并且详细阐述了由于RecyclerView缺少内置的点击事件监听器,作者如何自定义适配器来实现点击和长按事件。通过创建一个包含构造函数、初始化、getItemView方法以及可选的OnItemClick和OnItemLongClick接口的适配器,实现了事件监听功能。同时,ViewHolder的自定义也遵循了张鸿洋大神的建议。

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

android 5.0里的recycleView是谷歌最新的组件,是用来取代GridView Listview的,可是我不明白为什么recyclerView 没有setOnItemClickListener 和 setOnItemLongClicKListener. 没事我们自己实现,我自定义了一个适配器,看代码:

import android.content.Context;
import android.graphics.Bitmap;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

public abstract class MyBaseAdapter<T> extends RecyclerView.Adapter<MyBaseAdapter.ViewHolder> {

    private Context mContext;

    private List<T> list;

    private int layoutId;

    public MyBaseAdapter(int layoutId, Context mContext, List<T> list) {

        this.list = list;

        this.mContext = mContext;

        this.layoutId = layoutId;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(layoutId, null);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {

        getItemView(holder, list.get(position));

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                OnItemClick(holder, list.get(holder.getPosition()), holder.getPosition());
            }
        });

        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                OnItemLongClick(holder, list.get(holder.getPosition()), holder.getPosition());
                return true;
            }
        });

    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        private final SparseArray<View> array;

        public ViewHolder(View view) {
            super(view);
            array = new SparseArray<View>();
        }

        public <T extends View> T getView(int viewId) {
            View view = array.get(viewId);
            if (view == null) {
                view = this.itemView.findViewById(viewId);
                array.put(viewId, view);
            }
            return (T) view;
        }

        public void setText(int viewId, String text) {
            TextView textView = getView(viewId);
            textView.setText(text);
        }

        public void setImg(int viewId, int resId) {
            ImageView imageView = getView(viewId);
            imageView.setImageResource(resId);
        }

        public void setImg(int viewId, Bitmap bitmap) {
            ImageView imageView = getView(viewId);
            imageView.setImageBitmap(bitmap);
        }
    }

    public abstract void getItemView(ViewHolder holder, T item);

    public void OnItemClick(ViewHolder holder, T item, int position) {

    }

    public void OnItemLongClick(ViewHolder holder, T item, int position) {

    }

    public List<T> getList() {
        return list;
    }

    @Override
    public int getItemCount() {
        if (list != null) {
            return list.size();
        }
        return 0;
    }

    public void removeItem(int position){
        list.remove(position);
        notifyDataSetChanged();
    }
}


简单说一下:

构造函数:

只有三个参数 layoutId 就是recyclerView中每一条的布局,List 可以是任意类型的,mContent就是上下文。

这里面只初始化

public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)


这里面才是真正实现的地方

public void onBindViewHolder(final ViewHolder holder, int position)


getItemView方法是必须实现的

OnItemClick  和OnItemLongClick 只要继承就可以了,当然你也可以不实现


    public abstract void getItemView(ViewHolder holder, T item);

    public void OnItemClick(ViewHolder holder, T item, int position) {

    }

    public void OnItemLongClick(ViewHolder holder, T item, int position) {

    }



再说说ViewHolder:

自定义的ViewHolder必须继承RecyclerView.ViewHolder

        private final SparseArray<View> array;

        public ViewHolder(View view) {
            super(view);
            array = new SparseArray<View>();
        }

        public <T extends View> T getView(int viewId) {
            View view = array.get(viewId);
            if (view == null) {
                view = this.itemView.findViewById(viewId);
                array.put(viewId, view);
            }
            return (T) view;
        }
其中array就是存储recyclerView每一条布局中的所有子View ,为什么要这么做,是为了在getItemView()中不需要findViewById(); 只需要getView(viewId); 就会返回相应的View对象,setText(), setImg();因为我们的布局中经常会用到所以直接写在ViewHolder里了。

这样使用:

        recyclerView.setAdapter(new MyBaseAdapter<String>(R.layout.item, this, list) {

            @Override
            public void getItemView(final ViewHolder holder, String item) {
                /**第一种方式**/
                ((TextView)holder.getView(R.id.item_text)).setText(item);
                ((ImageView)holder.getView(R.id.item_image)).setImageResource(R.drawable.ic_launcher);

                /**第二种方式**/
                holder.setText(R.id.item_text, item);
                holder.setImg(R.id.item_image, R.drawable.ic_launcher);
            }

            @Override
            public void OnItemClick(ViewHolder holder, String item, int position) {
                removeItem(holder.getPosition());
            }

            @Override
            public void OnItemLongClick(ViewHolder holder, String item, int position) {
                Toast.makeText(MainActivity2.this, String.valueOf(position)+"   long clicked", Toast.LENGTH_SHORT).show();
            }
        });


我是偷懒了,把OnItemClickListener 和 OnItemLongClickListener 在适配器里实现了。


其中适配器里的ViewHolder的实现借鉴了   大神 张鸿洋的大笑

getItemView方法是必须实现的

OnItemClick  和OnItemLongClick 只要继承就可以了,当然你也可以不实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值