RecyclerView之瀑布流(三)

来源:互联网 发布:matlab 计算旋转矩阵 编辑:程序博客网 时间:2024/05/21 15:38

概述

RecyclerView(一)使用完全指南RecyclerView(二)之万能分割线RecyclerView之瀑布流(三)

RecyclerView提供了三种布局管理器:

  • LinerLayoutManager 以垂直或者水平列表方式展示Item
  • GridLayoutManager 以网格方式展示Item
  • StaggeredGridLayoutManager 以瀑布流方式展示Item

瀑布流样式

RecyclerView的瀑布流布局管理器是taggeredGridLayoutManager,它最常用的构造函数就一个,StaggeredGridLayoutManager(int spanCount, int orientation),spanCount代表每行或每列的Item个数,orientation代表列表的方向,竖直或者水平。

看在代码中的使用。

// 初始化布局管理器mLayoutManager = new StaggeredGridLayoutManager(2, OrientationHelper.VERTICAL);// 设置布局管理器mRecyclerView.setLayoutManager(mLayoutManager);// 设置adaptermRecyclerView.setAdapter(mAdapter);// 设置间隔样式mRecyclerView.addItemDecoration(new MDStaggeredRvDividerDecotation(this));

要实现瀑布流效果(仅讨论竖直方向的瀑布流样式),每一个Item的高度要有所差别,如果所有的item的高度相同,就和网格样式是一样的展示效果。示例中就实现两中不同高度的Item,一个高度为80dp,一个高度为100dp。

view_rv_staggered_item.xml布局:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              xmlns:tools="http://schemas.android.com/tools"              android:orientation="vertical"              android:layout_width="match_parent"              android:layout_height="80dp">    <TextView        android:id="@+id/item_tv"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        tools:text="item"/></LinearLayout>

view_rv_staggered_item_two.xml布局:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              xmlns:tools="http://schemas.android.com/tools"              android:orientation="vertical"              android:layout_width="match_parent"              android:layout_height="100dp">    <TextView        android:id="@+id/item_tv"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        tools:text="item"/></LinearLayout>

Item不同的布局是在Adapter里面绑定的,看一下Adapter的实现。

public class MDStaggeredRvAdapter extends RecyclerView.Adapter<MDStaggeredRvAdapter.ViewHolder> {    /**     * 展示数据     */    private ArrayList<String> mData;    public MDStaggeredRvAdapter(ArrayList<String> data) {        this.mData = data;    }    public void updateData(ArrayList<String> data) {        this.mData = data;        notifyDataSetChanged();    }    @Override    public int getItemViewType(int position) {        // 瀑布流样式外部设置spanCount为2,在这列设置两个不同的item type,以区分不同的布局        return position % 2;    }    @Override    public MDStaggeredRvAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        // 实例化展示的view        View v;        if(viewType == 1) {            v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_rv_staggered_item, parent, false);        } else {            v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_rv_staggered_item_two, parent, false);        }        // 实例化viewholder        ViewHolder viewHolder = new ViewHolder(v);        return viewHolder;    }    @Override    public void onBindViewHolder(MDStaggeredRvAdapter.ViewHolder holder, int position) {        // 绑定数据        holder.mTv.setText(mData.get(position));    }    @Override    public int getItemCount() {        return mData == null ? 0 : mData.size();    }    public static class ViewHolder extends RecyclerView.ViewHolder {        TextView mTv;        public ViewHolder(View itemView) {            super(itemView);            mTv = (TextView) itemView.findViewById(R.id.item_tv);        }    }}

接下来是设置瀑布流样式的间隔线样式的,上面代码中使用的是MDStaggeredRvDividerDecotation
类,其实是直接拷贝的网格样式的间隔线绘制类。看一下运行效果。

RecyclerView-瀑布流2列.jpg

很奇怪,间隔线并没有按照我们想象中的方式绘制,仔细看瀑布流中Item的分布,发现瀑布流样式的Item分布和网格样式的Item分布有些不同。对比一下两者Item的分布,如下图。

RecyclerView-对比.png

网格样式的Item分布规律很明显,竖直方向的网格,Item是从左向右从上到下依次按顺序排列分布。

瀑布流样式的Item分布也是从上到下,从左到右的顺序排列,但是有一个高度的优先级,如果某一列中有一个高度最低的位置为空,最优先在此处添加Item。看第三张图的3 item,因为该位置最低,优先在此处添加Item。

分析出了瀑布流样式的Item的分布规律,就会发现,按照以往列表样式或者网格样式去设置间隔线是有问题的,因为不知道Item具体的位置,上下左右间隔线是否需要绘制不确定,参考第二张图,其实第三张图的间隔线也有问题,向上滑动就会展示出来。

目前能考虑到的瀑布流添加间隔线的思路:

  • Item布局中设置四周间隔padding/margin
  • 代码中动态修改ItemView的间隔padding/margin

设置间隔有两个方法:

  • 上下左右都设置间隔
  • 相邻两边设置间隔(左上/左下/右上/右下)

第一种设置间隔的方法会导致相邻的Item间距是间隔的两倍,第二种设置间隔的方法会导致Item某一个方向上的与父布局边缘无间隔,但是另一个方向与父布局边缘有间隔,例如左上相邻两边设置了间隔,最左边一列的Item左边与父布局边缘有间隔,但是最右边一列Item右边与父布局无间隔,第一行和最后一行的Item也会出现这种情况。

要解决上面的问题,父布局RecyclerView也需要根据相应的情况设置padding让整个布局的间隔都一致。下面的例子是选择在Item布局中设置间隔,因为可以自己在布局文件中控制颜色比较方便,选择右下两边设置间隔。

首先修改两个Item的布局文件。
view_rv_staggered_item.xml修改背景色和外层间距背景色。

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              xmlns:tools="http://schemas.android.com/tools"              android:orientation="vertical"              android:layout_width="match_parent"              android:layout_height="@dimen/md_common_view_height"              android:background="@color/md_divider"              android:paddingBottom="5dp"              android:paddingRight="5dp">    <TextView        android:id="@+id/item_tv"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        android:background="@color/md_white"        tools:text="item"/></LinearLayout>

同样修改view_rv_staggered_item_two.xml。

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              xmlns:tools="http://schemas.android.com/tools"              android:orientation="vertical"              android:layout_width="match_parent"              android:layout_height="100dp"              android:paddingBottom="5dp"              android:paddingRight="5dp"              android:background="@color/md_divider">    <TextView        android:id="@+id/item_tv"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        android:background="@color/md_white"        tools:text="item"/></LinearLayout>

运行一下,看看最后的效果。

RecyclerView瀑布流.gif

差不多完美的解决了间隔线的问题,有细心的同学可能发现,在RecyclerView滑动的时候上面一直有一条灰色的间隔线,这个可以通过取消xml布局文件中RecyclerView的paddingTop属性去掉顶部灰色的间隔线。

总结

本篇文章主要介绍网格样式和瀑布流样式的RecyclerView,列表样式、网格样式和瀑布流样式在某种程度上是可以转换的。

  • 网格样式的布局管理器的spanCount设置为1,就是列表样式
  • 瀑布流样式如果Item的布局文件是等高,竖直方向,就是竖直方向的网格样式;如果Item是等宽,水平方向,那就是水平方向的网络样式
  • 如果瀑布流样式的布局管理器spanCount设置为1,竖直方向,是竖直方向的列表;水平方向,就是水平方向的列表

RecyclerView(一)使用完全指南

RecyclerView(二)之万能分割线

Android


作者:侯蛋蛋_
链接:https://www.jianshu.com/p/f75f9a73beff
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 荣耀5c忘记密码怎么办 小米之家不退货怎么办 手机号绑定过多小米账户怎么办 耐克黑色鞋褪色怎么办 买广汽传祺7s新车有问题怎么办 华为荣耀10边框掉色了怎么办 网购商家打来无货怎么办 客户拍了不发货怎么办 天猫商家欺骗买家怎么办 阿里买家投诉我发空包怎么办 苹果6s电池坏了怎么办 hm买的单鞋脏了怎么办 微店违规屏蔽搜索怎么办 ios微信支付失效怎么办 京东第三方店铺关闭怎么办 京东店铺关门了怎么办 国美退款不到账怎么办 小米小店通过了怎么办 苹果的发票丢了怎么办 苹果7p开不开机怎么办 申请退款了怎么卖家还发货怎么办 买家申请退款卖家不退款怎么办 卖家恶意不退款怎么办 欠条到期了对方不还钱怎么办 冰箱磕了一坑怎么办 办信用卡没有家庭地址的怎么办 钱付了货没收到怎么办 在苏宁易购上买东西地址错了怎么办 手机分期付款银行卡丢了怎么办 华硕笔记本鼠标不动了怎么办 韵达快递不派送怎么办 中通快递不派送怎么办 农业银行信用卡密码输错三次怎么办 农业银行卡多次输错密码怎么办 想把店长弄走怎么办 济南银座卡过期了怎么办 银座购物卡丢失后怎么办 银座的卡丢了怎么办 银行卡换了旧卡怎么办 大理市民卡丢了怎么办 市民卡内的钱怎么办