RecyclerView配合StaggeredGridLayoutManager实现瀑布流效果

1.前言

利用RecyclerView配合StaggeredGridLayoutManager可以实现类似于淘宝和京东的商品瀑布流效果,下面是一个简单的使用例子。
示例图片

2.例子

就不多讲了,直接上示例代码。

  1. 在页面的布局文件使用RecyclerView。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp"
    android:orientation="vertical" >
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_staggered"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ffffaa"/>
</LinearLayout>
  1. 定义RecyclerView中每个item的布局文件。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_item"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorWhite"
    android:orientation="vertical" >
    <ImageView
        android:id="@+id/iv_pic"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:scaleType="centerCrop" />
    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textColor="@color/colorBlack"
        android:textSize="17sp" />
</LinearLayout>
  1. 编写item的bean(图片素材自找)。
package xyz.strasae.androidlearn.myapplication.bean;

import java.util.ArrayList;

import xyz.strasae.androidlearn.myapplication.R;

public class ItemInfo {
    public int pic_id;
    public String title;
    public String desc;

    public ItemInfo(int pic_id, String title, String desc) {
        this.pic_id = pic_id;
        this.title = title;
        this.desc = desc;
    }

    public static int[] defaultItemImageArray = {R.drawable.pic1, R.drawable.pic2, R.drawable.pic3, R.drawable.pic4,
            R.drawable.pic5, R.drawable.pic6, R.drawable.pic7, R.drawable.pic8, R.drawable.pic9,
            R.drawable.pic10, R.drawable.pic11};

    public static String[] defaultItemTitleArray = {"图片1", "图片2", "图片3", "图片4", "图片5", "图片6", "图片7", "图片8"
    , "图片9", "图片10", "图片11"};

    public static ArrayList<ItemInfo> getDefaultStag() {
        ArrayList<ItemInfo> itemInfos = new ArrayList<ItemInfo>();
        for(int i = 0; i < defaultItemImageArray.length; i++) {
            itemInfos.add(new ItemInfo(defaultItemImageArray[i], defaultItemTitleArray[i], null));
        }
        return itemInfos;
    }
}
  1. 编写适配器。根据item的布局文件编写ItemHolder;继承自RecyclerView.Adapter<RecyclerView.ViewHolder>,重写onCreateViewHolder方法和绑定持有者方法。
  • 回调接口
package xyz.strasae.androidlearn.myapplication.widget;

import android.view.View;

public class RecyclerExtras {
    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }

    public interface OnItemLongClickListener {
        void onItemLongClick(View view, int position);
    }

    public interface OnItemDeleteClickListener {
        void onItemDeleteClick(View view, int position);
    }
}
  • 适配器
package xyz.strasae.androidlearn.myapplication.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

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

import java.util.ArrayList;

import xyz.strasae.androidlearn.myapplication.R;
import xyz.strasae.androidlearn.myapplication.bean.ItemInfo;
import xyz.strasae.androidlearn.myapplication.widget.RecyclerExtras;

public class StaggeredAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements RecyclerExtras.OnItemClickListener, RecyclerExtras.OnItemLongClickListener {
    private Context context;//设备上下文
    private LayoutInflater inflater;//代码中获取控件
    private ArrayList<ItemInfo> itemInfos;//item容器


    public StaggeredAdapter(Context context, ArrayList<ItemInfo> itemInfos) {
        this.context = context;
        this.itemInfos = itemInfos;
        inflater = LayoutInflater.from(context);
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        RecyclerView.ViewHolder holder;
        //获取布局文件
        view = inflater.inflate(R.layout.item_staggered, parent, false);
        holder = new ItemHolder(view);
        return holder;
    }

    @Override
    /**
     * 绑定持有者
     */
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
        ItemHolder itemHolder = (ItemHolder)holder;
        itemHolder.iv_pic.setImageResource(itemInfos.get(position).pic_id);
        itemHolder.tv_title.setText(itemInfos.get(position).title);
        itemHolder.ll_item.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onItemClickListener != null) {
                    onItemClickListener.onItemClick(v, position);
                }
            }
        });
        itemHolder.ll_item.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                onItemLongClickListener.onItemLongClick(v, position);
                return true;
            }
        });
    }

    private RecyclerExtras.OnItemLongClickListener onItemLongClickListener;
    private RecyclerExtras.OnItemClickListener onItemClickListener;

    public void setOnItemLongClickListener(RecyclerExtras.OnItemLongClickListener onItemLongClickListener) {
        this.onItemLongClickListener = onItemLongClickListener;
    }

    public void setOnItemClickListener(RecyclerExtras.OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    @Override
    //获取列表项类型
    public int getItemViewType(int position) {
        return 0;
    }

    @Override
    //获取列表项编号
    public long getItemId(int position) {
        return position;
    }

    @Override
    //获取列表项个数
    public int getItemCount() {
        return itemInfos.size();
    }

    @Override
    public void onItemClick(View view, int position) {
        Toast.makeText(context, "你点击了" + (position + 1) + " " + itemInfos.get(position).title, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onItemLongClick(View view, int position) {
        Toast.makeText(context, "你长按了" + (position + 1) + " " + itemInfos.get(position).title, Toast.LENGTH_SHORT).show();
    }

    /**
     * 持有者 按照item的布局文件写
     */
    private class ItemHolder extends RecyclerView.ViewHolder {
        public LinearLayout ll_item;
        public ImageView iv_pic;
        public TextView tv_title;

        public ItemHolder(View v) {
            super(v);
            ll_item = v.findViewById(R.id.ll_item);
            iv_pic = v.findViewById(R.id.iv_pic);
            tv_title = v.findViewById(R.id.tv_title);
        }

    }
}
  1. 页面中RecyclerView配合StaggeredGridLayoutManager使用。
  • 装饰RecyclerView(item的空白间隔)。
package com.example.group.widget;

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

public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
    private int space; // 空白间隔

    public SpacesItemDecoration(int space) {
        this.space = space;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.left = space; // 左边空白间隔
        outRect.right = space; // 右边空白间隔
        outRect.bottom = space; // 上方空白间隔
        outRect.top = space; // 下方空白间隔
    }
}
  • 代码中RecyclerView配合StaggeredGridLayoutManager。
package xyz.strasae.androidlearn.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import android.os.Bundle;
import android.widget.LinearLayout;

import xyz.strasae.androidlearn.myapplication.adapter.StaggeredAdapter;
import xyz.strasae.androidlearn.myapplication.bean.ItemInfo;
import xyz.strasae.androidlearn.myapplication.widget.SpacesItemDecoration;

public class MainActivity extends AppCompatActivity {
    private RecyclerView  rv_staggered;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rv_staggered = findViewById(R.id.rv_staggered);

		//第一个参数是每行(列)item的个数 第二个参数是横向排列还是纵向排列
        StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(3, LinearLayout.VERTICAL);
        rv_staggered.setLayoutManager(manager);

        StaggeredAdapter adapter = new StaggeredAdapter(this, ItemInfo.getDefaultStag());
        adapter.setOnItemClickListener(adapter);//adapter本身就实现了这两个接口
        adapter.setOnItemLongClickListener(adapter);

        rv_staggered.setAdapter(adapter);
        //设置动画
        rv_staggered.setItemAnimator(new DefaultItemAnimator());
        //设置装饰(这里这设置了间隔)
        rv_staggered.addItemDecoration(new SpacesItemDecoration(3));
    }
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值