Android-RecyclerView多布局封装

对多布局的封装,开发时主要处理 数据绑定接口,视图布局返回接口,数据绑定:在holder类提供了个tag属性,初始化holder会将视图布局返回的viewtype作为标识,这样在bindData方法时switch(holder.gettag())来判断holder类型,继而拿到holder的itemview,继而findviewById,绑定数据。视图布局返回:主要是多布局的逻辑处理,什么情况下返回什么样的布局

adapter:封装adapter用于生成通用holder;同时向在onCreateViewHolder方法中有参数view和layout布局的id,这个id是后续在holder类添加的属性tag:用来标识不同的布局holder;

public abstract class RecycleViewAdapterUtil extends RecyclerView.Adapter<ViewHolder>{
    List list;
    Context context;
    public RecycleViewAdapterUtil(Context context, List list){
        this.list = list;
        this.context = context;
    }
    @Override
    public int getItemViewType(int position) {
        return this.get_ItemViewType(position);
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        ViewHolder holder = new ViewHolder(LayoutInflater.from(context).inflate(i, viewGroup, false),i);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
       bindData(holder,position);
    }

    @Override
    public int getItemCount() {
        return get_ItemCount();
    }
    public abstract int get_ItemCount();//此抽象方法用来返回自定义的item总个数
    public abstract int get_ItemViewType(int position);//此抽象方法是用来抽象出去让开发者自己定义返回的layout的对应Id
    public abstract void bindData(ViewHolder holder, int i);//因为自定义复杂布局所以不知道当前的item布局,需要抽象出去让开发者自己根据当前布局处理数据
}

holder类:在holder类中加了几个辅助方法getview,set***;毕竟在activity里写的话,显得太多。SaprseArray稀疏数组在Android中比map更能节约内存。

public class ViewHolder extends RecyclerView.ViewHolder {
    private SparseArray<View> Views;
    View myItemView;
    int tag;//viewholder标识符,来标识不同的viewholder
    private View.OnClickListener onItemClickLitener;
    private View.OnLongClickListener onLongClickListener;

    public ViewHolder(@NonNull View itemView, int tag) {
        super(itemView);
        this.myItemView = itemView;
        this.tag = tag;
        this.Views = new SparseArray<View>();
    }

    public int getTag() {
        return tag;
    }

    public View getView(int viewID) {
        View view = Views.get(viewID);
        if (view == null)
        {
            view = myItemView.findViewById(viewID);
            Views.put(viewID, view);
        }
        return view;
    }

    //设置监听的方法
    public void setOnItemClickLitener(View.OnClickListener onItemClickLitener) {
        myItemView.setOnClickListener(onItemClickLitener);
    }

    //设置长按监听
    public void setOnLongClickListener(View.OnLongClickListener onLongClickListener) {
        myItemView.setOnLongClickListener(onLongClickListener);
    }

    public ViewHolder setText(int viewID, String str) {
        TextView textView = (TextView) this.getView(viewID);
        textView.setText(str);
        return this;
    }

    public ViewHolder setImage(int viewID, String imgStr, Context context) {
        ImageView imageView = (ImageView) this.getView(viewID);
        Glide.with(context).load(imgStr).into(imageView);//这里用了Glide框架我用来连接网络图片
        return this;
    }

调用:对于多布局,最重要的就是返回布局类型的逻辑处理,也就是get_ItemViewType方法返回的布局(R.layout.bujuitem),在get_ItemViewType方法具体实现中可以根据自己想要实现的布局逻辑来返回不同的布局itemId。下面这个只是底部加了个加载栏,item总数为list.size()+1;如果是那种布局混用的,可以将数据都放进list中,list中存放数据类型,例如list<user>,user类中可以有list类型的属性type1,2,3(例如这个type1,2,3:学生群体,老师群体,学校群体可以假定是不同布局的标识,type1.size()就是这个布局1的数量,,,)

至于数据绑定,只要根据holder.getTag()方法来获得当前holder的布局,直接填数据就行了。

ryviewdapter = new RecycleViewAdapterUtil(cookActivity.this, list) {

            @Override
            public int get_ItemViewType(int position) {//返回布局
                if (position == list.size()) {
                    return R.layout.viewfooter;
                }
                return R.layout.cook_namelist;
            }

            @Override
            public int get_ItemCount() {
                return list.size() + 1;
            }

            @Override
            public void bindData(final ViewHolder holder, int position) {
                switch (holder.getTag()) {
                    case R.layout.cook_namelist:
                        JsonObject jsonObject = list.get(position);
                        holder.setImage(R.id.list_cook_image, jsonObject.get("pic").getAsString(), cookActivity.this)
                                .setText(R.id.list_cook_name, "《" + jsonObject.get("name").getAsString() + "》" + "(" + jsonObject.get("peoplenum").getAsString() + ")(" + jsonObject.get("cookingtime").getAsString() + ")")
                                .setText(R.id.list_cook_content, jsonObject.get("content").getAsString())
                                .setText(R.id.list_cook_tag, "饮食标签:" + jsonObject.get("tag").getAsString() + position)
                                .setOnItemClickListener(new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        Intent intent = new Intent(cookActivity.this, cook_detail.class);
                                        Bundle bundle = new Bundle();
                                        bundle.putString("cook_selected", new Gson().toJson(list.get(holder.getAdapterPosition())));
                                        intent.putExtras(bundle);
                                        cookActivity.this.startActivity(intent);
                                    }
                                });
                        break;
                    case R.layout.viewfooter:
                        if (data.ishavemore && data.isloadmore) {
                            holder.getView(R.id.view_foot_progressbar).setVisibility(View.VISIBLE);
                            ((TextView) holder.getView(R.id.view_foot_more)).setText("加载中");
                        } else if (data.isloadmore) {
                            holder.getView(R.id.view_foot_progressbar).setVisibility(View.GONE);
                            ((TextView) holder.getView(R.id.view_foot_more)).setText("无结果");
                        }
                        break;
                }

            }
        };

附上一个对话布局类似客服那种

再附上代码:

写了机器人的xml在左边显示,人在右边显示(至于需要图片显示为圆形的,自行在网上找CircleImageView)

robot:xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/eyeopen"
        android:background="@color/colorAccent"/>
    <TextView
        android:id="@+id/robot_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_marginLeft="10dp"
        android:background="#d1d1d1"
        android:layout_gravity="center_vertical"
        android:text="robot的回复消息"/>
</LinearLayout>

people:xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="right">

    <TextView
        android:id="@+id/people_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="10dp"
        android:layout_gravity="center_vertical"
        android:background="#d1d1d1"
        android:text="你在吗?" />

    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/primary"
        android:src="@drawable/eyeclose"/>
</LinearLayout>

adapterutil:

        adapterUtil = new RecycleViewAdapterUtil(this,list) {
            @Override
            public int get_ItemCount() {
                return list.size();
            }

            @Override
            public int get_ItemViewType(int position) {
                if (list.get(position).getRole()==0){
                    return R.layout.robot_robot_item;
                }
                return R.layout.robot_people_item;
            }

            @Override
            public void bindData(ViewHolder holder, int i) {
                   switch (holder.getTag()){
//图片我都是在xml里写死的,毕竟人的图片,客服的图片又不会变
                       case R.layout.robot_robot_item:
                           holder.setText(R.id.robot_text,list.get(i).getText());
                           break;
                       case R.layout.robot_people_item:
                           holder.setText(R.id.people_text,list.get(i).getText());
                           break;
                   }
            }
        };
       recyclerView.setAdapter(adapterUtil);

实体类:

public class role {
    int role = 0;//初始为0:机器人;1:人
    String text = "";//说的话
    public role(int role,String text){
        this.role = role;
        this.text = text;
    }
    public int getRole() {
        return role;
    }

    public void setRole(int role) {
        this.role = role;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }


}
发布了3 篇原创文章 · 获赞 3 · 访问量 2239

猜你喜欢

转载自blog.csdn.net/qq_38858754/article/details/104200867
今日推荐