RecyclerView 高级用法之 Span

Ummi ·
更新时间:2024-09-20
· 958 次阅读

今天要做一个筛选的列表,大概是一个标题下面有几个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 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

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

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 { 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 { private List contentBeans; private HashMap<String, DrawerStateResponse> drawerHashMap = new HashMap(); public TextAdapter(List 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()); 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 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 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

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

源码Git下载


作者:Small_Wave_Wave



recyclerview span

需要 登录 后方可回复, 如果你还没有账号请 注册新账号