RecyclerView 高级用法之 Span

今天要做一个筛选的列表,大概是一个标题下面有几个item 然后这样有好几组,一般来说 上手就是 listview嵌套gradview或者 recyclerview嵌套recyclerview,处理嵌套高度计算问题就OK了!

但是今天,我不想搞那些嵌套了,只用一个 RecyclerView搞定它,最后有Git 下载链接

上图!

不好意思放错了!!!

是这张

原理就是通过 

GridLayoutManager 的 setSpanSizeLookup 监听来设置每行显示的数量

        mRecyclerView = findViewById(R.id.mRecyclerView);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);

        contentBeanList.add(new ContentBean(1, "标题1(单选)"));
        contentBeanList.add(new ContentBean(2, "内容1", "标题1(单选)"));
        contentBeanList.add(new ContentBean(2, "内容2", "标题1(单选)"));
        contentBeanList.add(new ContentBean(2, "内容3", "标题1(单选)"));
        contentBeanList.add(new ContentBean(2, "内容4", "标题1(单选)"));


        contentBeanList.add(new ContentBean(1, "标题2(单选)"));
        contentBeanList.add(new ContentBean(2, "内容1", "标题2(单选)"));
        contentBeanList.add(new ContentBean(2, "内容2", "标题2(单选)"));
        contentBeanList.add(new ContentBean(2, "内容3", "标题2(单选)"));
        contentBeanList.add(new ContentBean(2, "内容4", "标题2(单选)"));
        contentBeanList.add(new ContentBean(2, "内容5", "标题2(单选)"));
        contentBeanList.add(new ContentBean(2, "内容6", "标题2(单选)"));

        contentBeanList.add(new ContentBean(1, "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容1", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容2", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容3", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容4", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容5", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容6", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容7", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容8", "标题3(多选)"));


        final TextAdapter textAdapter = new TextAdapter(contentBeanList);
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                switch (textAdapter.getItemViewType(position)) {
                    // 返回的宽度为3, item满屏
                    case 1:
                        return 3;
                    case 2:
                        return 1;
                    case 3:
                        return 1;
                }
                return 0;
            }
        });
        mRecyclerView.setLayoutManager(gridLayoutManager);

        mRecyclerView.setAdapter(textAdapter);

然后在 Adapter 里面根据 type 设置点击事件和显示效果就可以了!

上完整代码

MainActivity.java

package com.wavewave.recyclerviewspan;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.view.View;

import com.wavewave.recyclerviewspan.adapter.TextAdapter;
import com.wavewave.recyclerviewspan.bean.ContentBean;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private List<ContentBean> contentBeanList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        mRecyclerView = findViewById(R.id.mRecyclerView);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);

        contentBeanList.add(new ContentBean(1, "标题1(单选)"));
        contentBeanList.add(new ContentBean(2, "内容1", "标题1(单选)"));
        contentBeanList.add(new ContentBean(2, "内容2", "标题1(单选)"));
        contentBeanList.add(new ContentBean(2, "内容3", "标题1(单选)"));
        contentBeanList.add(new ContentBean(2, "内容4", "标题1(单选)"));


        contentBeanList.add(new ContentBean(1, "标题2(单选)"));
        contentBeanList.add(new ContentBean(2, "内容1", "标题2(单选)"));
        contentBeanList.add(new ContentBean(2, "内容2", "标题2(单选)"));
        contentBeanList.add(new ContentBean(2, "内容3", "标题2(单选)"));
        contentBeanList.add(new ContentBean(2, "内容4", "标题2(单选)"));
        contentBeanList.add(new ContentBean(2, "内容5", "标题2(单选)"));
        contentBeanList.add(new ContentBean(2, "内容6", "标题2(单选)"));

        contentBeanList.add(new ContentBean(1, "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容1", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容2", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容3", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容4", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容5", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容6", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容7", "标题3(多选)"));
        contentBeanList.add(new ContentBean(3, "内容8", "标题3(多选)"));


        final TextAdapter textAdapter = new TextAdapter(contentBeanList);
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                switch (textAdapter.getItemViewType(position)) {
                    // 返回的宽度为3, item满屏
                    case 1:
                        return 3;
                    case 2:
                        return 1;
                    case 3:
                        return 1;
                }
                return 0;
            }
        });
        mRecyclerView.setLayoutManager(gridLayoutManager);

        mRecyclerView.setAdapter(textAdapter);
    }
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/mRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

数据控制类(当然真正数据可以自己修改)

ContentBean.java
package com.wavewave.recyclerviewspan.bean;

/**
 * @author wavewave
 * @CreateDate: 2020-03-24 11:11
 * @Description:
 * @Version: 1.0
 */
public class ContentBean {
    /**
     * 类型 1-> 标题 2->单选 3->多选
     */
    public int type;
    public String content;
    /**
     * 用于区分是哪一组的
     */
    public String isTitle;
    public boolean isSelect;

    public ContentBean(int type, String content) {
        this.type = type;
        this.content = content;
    }

    public ContentBean(int type, String content, String isTitle) {
        this.type = type;
        this.content = content;
        this.isTitle = isTitle;
    }
}

DrawerStateResponse.java

package com.wavewave.recyclerviewspan.bean;

import android.widget.TextView;

/**
 * @author wavewave
 * @CreateDate: 2020-01-21 16:38
 * @Description: 用于记录选中的view
 * @Version: 1.0
 */
public class DrawerStateResponse<T> {
    public TextView oldTextView;
    public T oldData;
}

TextAdapter.java

package com.wavewave.recyclerviewspan.adapter;

import android.graphics.Color;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.wavewave.recyclerviewspan.R;
import com.wavewave.recyclerviewspan.bean.ContentBean;
import com.wavewave.recyclerviewspan.bean.DrawerStateResponse;

import java.util.HashMap;
import java.util.List;

/**
 * @author wavewave
 * @CreateDate: 2020-03-24 11:10
 * @Description:
 * @Version: 1.0
 */
public class TextAdapter extends RecyclerView.Adapter<TextAdapter.TextViewHolder> {
    private List<ContentBean> contentBeans;

    private HashMap<String, DrawerStateResponse<ContentBean>> drawerHashMap = new HashMap<>();

    public TextAdapter(List<ContentBean> contentBeans) {
        this.contentBeans = contentBeans;
    }

    @Override
    public int getItemViewType(int position) {
        if (contentBeans.get(position) != null) {
            return contentBeans.get(position).type;
        }
        return super.getItemViewType(position);
    }

    @NonNull
    @Override
    public TextViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new TextViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_text, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull final TextViewHolder holder, final int position) {
        if (holder != null) {
            switch (contentBeans.get(position).type) {
                case 1://标题
                    //在标题这记录
                    holder.mTextTitle.setTextColor(Color.parseColor("#748098"));
                    holder.mTextTitle.setBackgroundColor(Color.parseColor("#F8F8F8"));
                    drawerHashMap.put(contentBeans.get(position).content, new DrawerStateResponse<ContentBean>());
                    holder.mTextTitle.setBackgroundColor(Color.WHITE);
                    holder.mTextTitle.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
                    break;
                case 2://单选
                    if (contentBeans.get(position).isSelect) {
                        holder.mTextTitle.setTextColor(Color.parseColor("#FFFFFF"));
                        holder.mTextTitle.setBackgroundColor(Color.parseColor("#62A5FE"));

                        DrawerStateResponse<ContentBean> drawerView = drawerHashMap.get(contentBeans.get(position).isTitle);
                        if (drawerView == null) {
                            drawerView = new DrawerStateResponse<>();
                        }
                        drawerView.oldData = contentBeans.get(position);
                        drawerView.oldTextView = holder.mTextTitle;

                    } else {
                        holder.mTextTitle.setTextColor(Color.parseColor("#748098"));
                        holder.mTextTitle.setBackgroundColor(Color.parseColor("#F8F8F8"));
                    }
                    holder.mTextTitle.setGravity(Gravity.CENTER);
                    holder.mTextTitle.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            DrawerStateResponse<ContentBean> drawerView = drawerHashMap.get(contentBeans.get(position).isTitle);
                            if (drawerView == null) {
                                drawerView = new DrawerStateResponse<>();
                            }
                            if (drawerView.oldData != null && drawerView.oldTextView != null) {
                                drawerView.oldData.isSelect = false;
                                drawerView.oldTextView.setTextColor(Color.parseColor("#748098"));
                                drawerView.oldTextView.setBackgroundColor(Color.parseColor("#F8F8F8"));
                            }
                            contentBeans.get(position).isSelect = true;

                            holder.mTextTitle.setTextColor(Color.parseColor("#FFFFFF"));
                            holder.mTextTitle.setBackgroundColor(Color.parseColor("#62A5FE"));

                            drawerView.oldData = contentBeans.get(position);
                            drawerView.oldTextView = holder.mTextTitle;
                            Log.d("RecyclerView", "选择了:" + contentBeans.get(position).content);
                        }
                    });
                    break;
                case 3://多选
                    if (contentBeans.get(position).isSelect) {
                        holder.mTextTitle.setTextColor(Color.parseColor("#FFFFFF"));
                        holder.mTextTitle.setBackgroundColor(Color.parseColor("#62A5FE"));
                    } else {
                        holder.mTextTitle.setTextColor(Color.parseColor("#748098"));
                        holder.mTextTitle.setBackgroundColor(Color.parseColor("#F8F8F8"));
                    }
                    holder.mTextTitle.setGravity(Gravity.CENTER);
                    holder.mTextTitle.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            contentBeans.get(position).isSelect = !contentBeans.get(position).isSelect;
                            if (contentBeans.get(position).isSelect) {
                                holder.mTextTitle.setTextColor(Color.parseColor("#FFFFFF"));
                                holder.mTextTitle.setBackgroundColor(Color.parseColor("#62A5FE"));
                            } else {
                                holder.mTextTitle.setTextColor(Color.parseColor("#748098"));
                                holder.mTextTitle.setBackgroundColor(Color.parseColor("#F8F8F8"));
                            }
                            Log.d("RecyclerView", "多选:" + contentBeans.get(position).content + " 选中?" + contentBeans.get(position).isSelect);
                        }
                    });
                    break;
            }
            holder.mTextTitle.setText(contentBeans.get(position).content);
        }
    }

    @Override
    public int getItemCount() {
        return contentBeans == null ? 0 : contentBeans.size();
    }

    class TextViewHolder extends RecyclerView.ViewHolder {

        public final TextView mTextTitle;

        public TextViewHolder(@NonNull View itemView) {
            super(itemView);
            mTextTitle = itemView.findViewById(R.id.mTextTitle);
        }
    }
}

adapter_text.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="44dp"
    android:layout_marginTop="10dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/mTextTitle"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="10dp"
        android:gravity="center_vertical"
        android:text="我是标题哦" />
</LinearLayout>

好了,大功告成!以后就不用再有嵌套的痛苦了。开心开心

源码Git下载

发布了20 篇原创文章 · 获赞 5 · 访问量 9471

猜你喜欢

转载自blog.csdn.net/Small_Wave_Wave/article/details/105070897
今日推荐