RecyclerView的多种布局

本文介绍如何使用RecyclerView实现复杂的网格布局效果,包括不同类型的项及自定义跨度调整。通过实例代码展示了如何配置GridLayoutManager并实现多类型视图的自定义ViewHolder。

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

我感觉最近RecyclerView很多,我也研究了下,希望和大家一起分享探讨,多多学习吧。

今天我就写一下复杂布局,上下刷新下拉加载还有分割线我就不写了,我还是提一下吧。

其实上下刷新加载在Github中有相关的代码,我们只需要导入就可以了,分割线github中也有,如果你想实现不一样的分割线,就可以自己动手在代码中实现了。

首先我们看下效果图:

                                                                           


其实这个布局很简单的,我们来分析下,我们可以看出来这个有点类似表格布局。

我就是用GridlayoutManager分配的布局格式,我们也可以用LinearLayout写实现的布局。看你的需求。

首先我们拿到项目的需要我们不应该盲目的就写代码,我们些需要分析一些功能和实现的方法,这样才更加快速有效的完成我们的任务。

首先我们需要导入RecyckeView的包


废话有点多了 下面我们解析下代码

MainActivity中的代码

package com.qiangshijituan.recyclerviewdemo;

import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    int[] colors = {android.R.color.holo_red_dark,
            android.R.color.holo_blue_dark,
            android.R.color.holo_green_dark,};
    private List<DataModel> lists;
    private DemoAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        final GridLayoutManager gridLayoutManager = new GridLayoutManager(this,2);
        // 这个是设置Grridlayout样式  因为我有3种布局这个就是设置这3中布局的样式
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                // 需要每一个Item的type 根据type取出横跨值
                int type = recyclerView.getAdapter().getItemViewType(position);
                if (type == DataModel.TYPE_THREE){
                    // gridLayoutManager.getSpanCount 其实就是上面的那个2 
                    return  gridLayoutManager.getSpanCount();
                }else {
                    return  1;
                }
            }
        });
        recyclerView.setLayoutManager(gridLayoutManager);


        adapter = new DemoAdapter(this);
        recyclerView.setAdapter(adapter);
        // 这个方法是每一个item设置横跨度
        recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                // 拿到Recycler当前行数的第几个SpanSize 我们需要判断SpanSize是1还是2
                GridLayoutManager.LayoutParams layoutParams =  (GridLayoutManager.LayoutParams)view.getLayoutParams();
                int spanSize = layoutParams.getSpanSize();
                int spanIndex = layoutParams.getSpanIndex();
                outRect.top = 20;
                if (spanIndex == 1){
                    outRect.left = 10;
                }else {
                    outRect.right = 10;
                }

            }
        });
        initData();
    }

    private void initData() {
        lists = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            int type ;
            // 随意写的就是为了体现视图
            if (i<5||i>15&&i<20){
                type =1 ;
            }else if (i<10 || i>26){
                type =2;
            }else {
                type = 3 ;
            }
            DataModel data = new DataModel();
            //tepe是一到三的数组是零到二的所以还需要减一
            data.avatarColor = colors[type-1];
            data.type = type;
            data.name = "name: "+i;
            data.content = "content: "+i ;
            data.contentColor = colors[(type+1)%3];
            lists.add(data);
        }

        adapter.addList(lists);
        adapter.notifyDataSetChanged();
    }
}

我们创建一个数据类DataModel

public class DataModel {
    public static final int TYPE_ONE = 1 ;
    public static final int TYPE_TW0 = 2 ;
    public static final int TYPE_THREE = 3 ;
    public int type ;
    public int avatarColor ;
    public String name ;
    public String content ;
    public int contentColor;
}

我们上面谁有三个布局的所以我们需要创建3个布局

第一个:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@android:color/white"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:orientation="horizontal">

    <ImageView
        android:layout_gravity="center"
        android:layout_marginLeft="20dp"
        android:id="@+id/avatar"
        android:layout_width="0dp"
        android:layout_weight="2"
        android:layout_height="40dp" />


    <TextView
        android:layout_gravity="center_horizontal"
        android:id="@+id/name"
        android:text="Able_强"
        android:layout_width="0dp"
        android:layout_weight="8"
        android:gravity="center"
        android:layout_height="match_parent" />


</LinearLayout>

第二个和第3个我就不复制粘贴了根据自己需求


适配器中的代码如下:

package com.qiangshijituan.recyclerviewdemo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;


public class DemoAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
    private Context context ;
    private List<DataModel> mList = new ArrayList<>();
    private LayoutInflater mLayoutInflater ;
    public DemoAdapter(Context context ) {

        mLayoutInflater = LayoutInflater.from(context);
    }

    public void addList(List<DataModel> list){
        mList.addAll(list);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType){
            case DataModel.TYPE_ONE:
                return new TypeOneViewHolder(mLayoutInflater.inflate(R.layout.item_type_one,parent,false));
            case DataModel.TYPE_TW0:
                return new TypeTwoViewHolder(mLayoutInflater.inflate(R.layout.item_type_two,parent,false));
            case DataModel.TYPE_THREE:
                return new TypeThreeViewHolder(mLayoutInflater.inflate(R.layout.item_type_three,parent,false));
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        // 没有viewType 我们需要取出来
        int viewType = getItemViewType(position);
        // 因为继承了 直接调用binHolder就ok了
        ((TypeAbstactViewHolder)holder).binHolder(mList.get(position));
    }

    @Override
    public int getItemViewType(int position) {
        return mList.get(position).type;
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }
}


我们还需要创建3个类分别实现xml :one,two,three里面的布局

里面有一个相同的方法,我抽取出来当成一个工具类

先写父类

import android.support.v7.widget.RecyclerView;
import android.view.View;


public abstract class TypeAbstactViewHolder extends RecyclerView.ViewHolder {

    public TypeAbstactViewHolder(View itemView) {
        super(itemView);
    }
    //基类  都需要实现这个方法
    public abstract void binHolder(DataModel model);
}
其他的需要继承我这个父类的抽象方法

package com.qiangshijituan.recyclerviewdemo;

import android.graphics.Color;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;



public class TypeOneViewHolder extends TypeAbstactViewHolder{

    private final TextView name;
    private final ImageView avatar;

    public TypeOneViewHolder(View itemView) {
        super(itemView);
        name = (TextView) itemView.findViewById(R.id.name);
        avatar = (ImageView) itemView.findViewById(R.id.avatar);
        itemView.setBackgroundColor(Color.WHITE);
    }

    @Override
    public void binHolder(DataModel model) {
        avatar.setBackgroundResource(model.avatarColor);
        name.setText(model.name);
    }

那两个就是复制粘贴了



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值