学习Android的第八天

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

前言

昨天我们使用RecyclerView 实现了网格布局,通过你的举一反三天赋,你成功的被窝读书中的签到样式,今天我们就来学习如何利用RecyclerView实现实际开发中经常遇到的瀑布流布局

老样子,先来看看现在app中的使用场景吧

瀑布1.gif

看着很复杂对吧,有的高,有的矮,其实简单的实现并不是很难,我们现在就开始吧

还是老样子,xml声明recyclerview

<?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"
    tools:context=".StaggerActivity">

    <androidx.recyclerview.widget.RecyclerView
    //控件id
        android:id="@+id/rv_stagger"
        //距离左侧距离,防止贴边
        android:layout_marginLeft="15dp"
        //充满父布局
        android:layout_width="match_parent"
        //高度自适应
        android:layout_height="wrap_content"
        //设置约束条件
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
复制代码

Activity

private RecyclerView mRvStagger;

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

private void initView() {
    //初始化布局
    mRvStagger = findViewById(R.id.rv_stagger);
    //设置瀑布流专属布局管理器;不会限制item的宽高
    mRvStagger.setLayoutManager(new StaggeredGridLayoutManager(2,RecyclerView.VERTICAL));
    //模拟真实数据环境
    List<StaggerBean> list = new ArrayList<>();
    for (int i = 0; i < 20; i++) {
        list.add(new StaggerBean("测试"+i));
    }
        //实例化适配器
    StaggerAdapter staggerAdapter = new StaggerAdapter(this, list);
    //设置适配器
    mRvStagger.setAdapter(staggerAdapter);
}
复制代码

StaggerBean

public class StaggerBean {
//需要显示的商品名称
    public String content;
    //每个item的高度
    public int height;
    //构造函数,必填商品名称
    public StaggerBean(String content) {
        this.content = content;
    }
}
复制代码

适配器

public class StaggerAdapter extends RecyclerView.Adapter<StaggerAdapter.ViewHolder> {
    private final Context context;
    private final List<StaggerBean> list;


    public StaggerAdapter(Context context, List<StaggerBean> list) {
        this.context = context;
        this.list = list;
    }

    @NonNull
    @NotNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
    //加载布局
        View root = LayoutInflater.from(context).inflate(R.layout.item_stagger, parent, false);
        return new ViewHolder(root);
    }

    @Override
    public void onBindViewHolder(@NonNull @NotNull StaggerAdapter.ViewHolder holder, int position) {
    //获取当前下标应该渲染的数据
        StaggerBean staggerBean = list.get(position);
        ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) holder.mItemIv.getLayoutParams();
        //如果实体类中的高度是0就代表是第一次加载,我们要随机一个数值给他,模拟我们的高度不等效果
        if (staggerBean.height == 0) {
        //设置一个随机数,值为100-300随机
            Random random = new Random();
            int i = random.nextInt(ImageUtil.dp2px(context, 300) - ImageUtil.dp2px(context, 100)) + ImageUtil.dp2px(context, 100);
            //存到当前实体类
            staggerBean.height = i;
            //先给图片设置上高度
     
            layoutParams.height = i;
        } else {
        //如果已经有高度说明是第二个加载当前数据,直接使用实体类的数据即可
            layoutParams.height = staggerBean.height;
        }
        //设置图片高度
        holder.mItemIv.setLayoutParams(layoutParams);
        //渲染商品名称
        holder.mItemTv.setText(staggerBean.content);
    }

    @Override
    public int getItemCount() {
    //数量
        return list.size();
    }


    public class ViewHolder extends RecyclerView.ViewHolder {
    //初始化控件
        private final ImageView mItemIv;
        private final TextView mItemTv;

        public ViewHolder(@NonNull @NotNull View convertView) {
            super(convertView);
            mItemIv = convertView.findViewById(R.id.item_iv);
            mItemTv = convertView.findViewById(R.id.item_tv);
        }
    }
}
复制代码

item

<?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"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/item_iv"
        //宽度设定一个值,一般根据设计图来确定
        android:layout_width="150dp"
        //随便给个背景,好识别
        android:background="@color/teal_200"
        //高度随便,反正是动态设置,这里面-100都行
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/item_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        //距离上方距离
        android:layout_marginTop="10dp"
        //内部距离父布局距离
        android:padding="10dp"
        //约束条件
        app:layout_constraintLeft_toLeftOf="@id/item_iv"
        app:layout_constraintRight_toRightOf="@id/item_iv"
        app:layout_constraintTop_toBottomOf="@id/item_iv" />

</androidx.constraintlayout.widget.ConstraintLayout>
复制代码

效果

瀑布2.gif

很完美,如果你要做刷新,你可能会碰到许许多多的bug,嘎嘎嘎嘎嘎

猜你喜欢

转载自juejin.im/post/7031566892376522782