Android RecyclerView适配器封装

一、上代码

1、创建CommonAdapter.java

/**
 * description: RecyclerView万能的Adapter
 */
public class CommonAdapter<T> extends RecyclerView.Adapter<CommonViewHolder> {

    private List<T> mList;

    // 声明绑定数据接口
    private OnBindDataListener<T> onBindDataListener;
    // 声明绑定多类型的数据接口
    private OnMoreBindDataListener<T> onMoreBindDataListener;

    /**
     * 构造方法
     * @param mList
     * @param onBindDataListener
     */
    public CommonAdapter(List<T> mList, OnBindDataListener<T> onBindDataListener) {
        this.mList = mList;
        this.onBindDataListener = onBindDataListener;
    }

    /**
     * 构造方法
     * @param mList
     * @param onMoreBindDataListener
     */
    public CommonAdapter(List<T> mList, OnMoreBindDataListener<T> onMoreBindDataListener) {
        this.mList = mList;
        this.onBindDataListener = onMoreBindDataListener;
        this.onMoreBindDataListener = onMoreBindDataListener;
    }

    /**
     * 绑定数据接口
     * @param <T>
     */
    public interface OnBindDataListener<T>{
        // 绑定ViewHolder
        void onBindViewHolder(T model,CommonViewHolder viewHolder,int type,int position);
        // 获取布局Id
        int getLayoutId(int type);
    }

    /**
     * 绑定多类型的数据接口
     * @param <T>
     */
    public interface OnMoreBindDataListener<T> extends OnBindDataListener<T>{
        // 获取项目类型
        int getItemType(int position);
    }

    /**
     * 返回位置处项目的视图类型,以便进行视图循环。
     * @param position
     * @return
     */
    @Override
    public int getItemViewType(int position) {
        if (onMoreBindDataListener != null) {
            return onMoreBindDataListener.getItemType(position);
        }
        return 0;
    }

    /**
     * 每当 RecyclerView 需要创建新的 ViewHolder 时,它都会调用此方法。
     * 此方法会创建并初始化 ViewHolder 及其关联的 View,但不会填充视图的内容,
     * 因为 ViewHolder 此时尚未绑定到具体数据。
     * @param parent
     * @param viewType
     * @return
     */
    @NonNull
    @NotNull
    @Override
    public CommonViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
        int layoutId = onBindDataListener.getLayoutId(viewType);
        CommonViewHolder viewHolder = CommonViewHolder.getViewHolder(parent, layoutId);
        return viewHolder;
    }

    /**
     * RecyclerView 调用此方法将 ViewHolder 与数据相关联。
     * 此方法会提取适当的数据,并使用该数据填充 ViewHolder 的布局。
     * 例如,如果 RecyclerView 显示的是一个名称列表,该方法可能会在列表中查找适当的名称,
     * 并填充 ViewHolder 的 TextView widget。
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(@NonNull @NotNull CommonViewHolder holder, int position) {
        onBindDataListener.onBindViewHolder(mList.get(position),holder,getItemViewType(position),position);
    }

    /**
     * RecyclerView 调用此方法来获取数据集的大小。
     * 例如,在通讯簿应用中,这可能是地址总数。
     * RecyclerView 使用此方法来确定什么时候没有更多的列表项可以显示。
     * @return
     */
    @Override
    public int getItemCount() {
        return mList == null ? 0 : mList.size();
    }
}

2、创建CommonViewHolder.java

/**
 * description: RecyclerView万能的ViewHolder
 */
public class CommonViewHolder extends RecyclerView.ViewHolder {

    // 子View的集合,使用SparseArray保存View是比较高效的
    private SparseArray<View> mView;
    private View mContentView;

    public CommonViewHolder(@NonNull @NotNull View itemView) {
        super(itemView);
        mView = new SparseArray<>();
        mContentView = itemView;
    }

    /**
     * 获取CommonViewHolder实体
     * @param parent
     * @param layoutId
     * @return
     */
    public static CommonViewHolder getViewHolder(ViewGroup parent, int layoutId){
        return new CommonViewHolder(View.inflate(parent.getContext(), layoutId,null));
    }

    /**
     * 提供给外部访问View的方法
     * @param viewId
     * @param <T>
     * @return
     */
    public <T extends View>T getView(int viewId){
        View view = mView.get(viewId);
        if (view == null) {
            view = mContentView.findViewById(viewId);
            mView.put(viewId,view);
        }
        return (T) view;
    }

    /**
     * 设置文本
     * @param viewId
     * @param text
     * @return
     */
    public CommonViewHolder setText(int viewId,String text){
        TextView tv = getView(viewId);
        tv.setText(text);
        return this;
    }

    /**
     * 设置图片链接
     * @param viewId
     * @param url
     * @return
     */
    public CommonViewHolder setImageUrl(Context context,int viewId, String url){
        ImageView iv = getView(viewId);
        GlideHelper.loadUrl(context,url,iv);
        return this;
    }

    /**
     * 设置图片
     * @param viewId
     * @param resId
     * @return
     */
    public CommonViewHolder setImageResource(int viewId,int resId){
        ImageView iv = getView(viewId);
        iv.setImageResource(resId);
        return this;
    }

    /**
     * 设置图片
     * @param viewId
     * @param visibility
     * @return
     */
    public CommonViewHolder setVisibility(int viewId,int visibility){
        LinearLayout ll = getView(viewId);
        ll.setVisibility(visibility);
        return this;
    }
}

二、使用

1、创建RecyclerView条目的布局

layout_search_user_item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:background="@android:color/white"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:paddingLeft="15dp"
        android:paddingRight="15dp">

        <RelativeLayout
            android:layout_width="60dp"
            android:layout_height="60dp">

            <de.hdodenhof.circleimageview.CircleImageView
                android:id="@+id/iv_photo"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@mipmap/ic_launcher" />

            <ImageView
                android:id="@+id/iv_sex"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_alignParentBottom="true"
                android:src="@drawable/img_boy_icon" />

        </RelativeLayout>

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginLeft="10dp"
            android:layout_weight="1"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center_vertical"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/tv_nickname"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_vertical"
                    android:maxLines="1"
                    android:text="NickName"
                    android:textColor="@color/colorPrimary"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/tv_age"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="20dp"
                    android:gravity="center_vertical"
                    android:maxLines="1"
                    android:text="Age" />

            </LinearLayout>

            <LinearLayout
                android:visibility="gone"
                android:id="@+id/ll_contact_info"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:id="@+id/tv_contact_name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="name" />

                <TextView
                    android:id="@+id/tv_contact_phone"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:text="phone" />

            </LinearLayout>

            <TextView
                android:id="@+id/tv_desc"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:ellipsize="marquee"
                android:gravity="center_vertical"
                android:marqueeRepeatLimit="marquee_forever"
                android:singleLine="true"
                android:text="Desc" />

        </LinearLayout>

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/img_right_arrow" />

    </LinearLayout>

</RelativeLayout>

layout_search_title_item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:textSize="16sp"
        android:textColor="@android:color/white"
        android:paddingLeft="15dp"
        android:gravity="center_vertical"
        android:background="@color/colorAccent"
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

</RelativeLayout>

2、创建RecyclerView的数据模型

AddFriendModel.java

/**
 * description: 数据模型
 */
public class AddFriendModel {
    //类型
    private int type;

    //标题
    private String title;

    //内容
    private String userId;
    private String photo;
    private boolean sex;
    private int age;
    private String nickName;
    private String desc;

    //联系人
    private boolean isContact = false;
    private String contactName;
    private String contactPhone;

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getPhoto() {
        return photo;
    }

    public void setPhoto(String photo) {
        this.photo = photo;
    }

    public boolean isSex() {
        return sex;
    }

    public void setSex(boolean sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public boolean isContact() {
        return isContact;
    }

    public void setContact(boolean contact) {
        isContact = contact;
    }

    public String getContactName() {
        return contactName;
    }

    public void setContactName(String contactName) {
        this.contactName = contactName;
    }

    public String getContactPhone() {
        return contactPhone;
    }

    public void setContactPhone(String contactPhone) {
        this.contactPhone = contactPhone;
    }

}

3、在布局文件中添加RecyclerView控件

activity_add_friend.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/mSearchResultView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>

4、开始使用

4.2、单个类型

// RecyclerView适配器
private CommonAdapter<AddFriendModel> mCommonAdapter;
// RecyclerView数据源
private List<AddFriendModel> mList = new ArrayList<>();

@Override
protected void initView() {
    // RecyclerView设置布局管理器
    binding.mContactView.setLayoutManager(new LinearLayoutManager(this));
    // 添加列表项下划线
    binding.mContactView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));
    // 设置适配器
    mCommonAdapter = new CommonAdapter<>(mList, new CommonAdapter.OnBindDataListener<AddFriendModel>() {
        @Override
        public void onBindViewHolder(AddFriendModel model, CommonViewHolder viewHolder, int type, int position) {
            // 设置头像
            viewHolder.setImageUrl(ContactFriendActivity.this,R.id.iv_photo,model.getPhoto());
            // 设置性别
            viewHolder.setImageResource(R.id.iv_sex,model.isSex() ? R.drawable.img_boy_icon : R.drawable.img_girl_icon);
            // 设置昵称
            viewHolder.setText(R.id.tv_nickname,model.getNickName());
            //点击事件
            viewHolder.itemView.setOnClickListener(v -> {});
        }
        @Override
        public int getLayoutId(int type) {
            return R.layout.layout_search_user_item;
        }
    });
    binding.mContactView.setAdapter(mCommonAdapter);
}

4.1、多个类型

// 标题
public static final int TYPE_TITLE = 0;
// 内容
public static final int TYPE_CONTENT = 1;
// RecyclerView适配器
private CommonAdapter<AddFriendModel> mAddFriendAdapter;
// RecyclerView数据源
private List<AddFriendModel> mList = new ArrayList<>();


@Override
protected void initView() {
    // 列表的实现
    // RecyclerView设置布局管理器
    binding.mSearchResultView.setLayoutManager(new LinearLayoutManager(this));
    // 添加列表项下划线
    binding.mSearchResultView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));
    // 设置适配器
    mAddFriendAdapter = new CommonAdapter<AddFriendModel>(mList, new CommonAdapter.OnMoreBindDataListener<AddFriendModel>() {
        @Override
        public int getItemType(int position) {
            return mList.get(position).getType();
        }
        @Override
        public void onBindViewHolder(AddFriendModel model, CommonViewHolder viewHolder, int type, int position) {
            if (model.getType() == TYPE_TITLE){
                // 设置标题
                viewHolder.setText(R.id.tv_title,model.getTitle());
            }else if (model.getType() == TYPE_CONTENT){
                // 设置头像
                viewHolder.setImageUrl(AddFriendActivity.this,R.id.iv_photo,model.getPhoto());
                // 设置性别
                viewHolder.setImageResource(R.id.iv_sex,model.isSex() ? R.drawable.img_boy_icon : R.drawable.img_girl_icon);
                // 设置昵称
                viewHolder.setText(R.id.tv_nickname,model.getNickName());
                //点击事件
                viewHolder.itemView.setOnClickListener(v -> {});
            }
        }
        @Override
        public int getLayoutId(int type) {
            if (type == TYPE_TITLE) {
                return R.layout.layout_search_title_item;
            }else if (type == TYPE_CONTENT){
                return R.layout.layout_search_user_item;
            }
            return 0;
        }
    });
    // 添加适配器
    binding.mSearchResultView.setAdapter(mAddFriendAdapter);
}

三、效果图

1、单个类型

在这里插入图片描述

2、多个类型

在这里插入图片描述

四、注意事项

1、ViewBinding官方教程:链接

2、RecyclerView官方教程:链接

3、TYPE_TITLE 和 TYPE_CONTENT 在使用前就设置到AddFriendModel里了,所以直接使用getType()方法是有数据的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Android Hai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值