RecyclerView实现瀑布流效果
  Op9yysgqYUmV 2023年11月02日 39 0


在上一节,我们已经简单说过StaggeredGridLayoutManager的使用,这一节给出个具体的例子,我们利用他做一个照片墙的功能,先看下效果

RecyclerView实现瀑布流效果_瀑布流


首先是Item的布局item_recycler_layout.xml

<?xml version="1.0" encoding="utf-8"?>
 
 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 
 
    android:layout_width="match_parent"
 
 
    android:layout_height="wrap_content"
 
 
    android:orientation="vertical" >
 
 
    <ImageView
 
 
        android:id="@+id/iv_item_img"
 
 
        android:layout_width="match_parent"
 
 
        android:layout_height="wrap_content"
 
 
        android:adjustViewBounds="true"
 
 
        android:scaleType="centerCrop"/>
 
 
    <TextView
 
 
        android:id="@+id/tv_item_text"
 
 
        android:layout_width="match_parent"
 
 
        android:layout_height="wrap_content"
 
 
        android:gravity="center"
 
 
        android:padding="5dp"
 
 
        android:text="Text数据显示..."
 
 
        android:textSize="16sp" />
 
 

 
 
</LinearLayout>
 

 
给每张照片写一个实体类
 
public class Photo {
 
 
    private int img;
 
 
    private String title;
 
 

 
 
    public Photo() {
 
 
        super();
 
 
    }
 
 

 
 
    public Photo(int img, String title) {
 
 
        this.img = img;
 
 
        this.title = title;
 
 
    }
 
 

 
 
    public int getImg() {
 
 
        return img;
 
 
    }
 
 

 
 
    public void setImg(int img) {
 
 
        this.img = img;
 
 
    }
 
 

 
 
    public String getTitle() {
 
 
        return title;
 
 
    }
 
 

 
 
    public void setTitle(String title) {
 
 
        this.title = title;
 
 
    }
 
 
}

自定义一个MyRecyclerAdapter


public class MyRecyclerAdapter extends Adapter<MyRecyclerAdapter.ViewHolder> {
 
 
    private List<Photo> photoList;
 
 

 
 
    public MyRecyclerAdapter(List<Photo> list) {
 
 
        super();
 
 
        this.photoList = list;
 
 
    }
 
 

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

 
 
    @Override
 
 
    public void onBindViewHolder(ViewHolder holder, int position) {
 
 
        holder.item_tv.setText(photoList.get(position).getTitle());
 
 
        holder.item_iv.setBackgroundResource(photoList.get(position).getImg());
 
 
    }
 
 

 
 
    @Override
 
 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int arg1) {
 
 
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
 
 
        View view = inflater.inflate(R.layout.item_recycler_layout, parent, false);
 
 
        //view.setBackgroundColor(Color.RED);  
 
 
        ViewHolder viewHolder = new ViewHolder(view);
 
 
        return viewHolder;
 
 
    }
 
 

 
 
    public static class ViewHolder extends RecyclerView.ViewHolder {
 
 
        public TextView item_tv;
 
 
        public ImageView item_iv;
 
 

 
 
        public ViewHolder(View view) {
 
 
            super(view);
 
 
            item_tv = (TextView) view.findViewById(R.id.tv_item_text);
 
 
            item_iv = (ImageView) view.findViewById(R.id.iv_item_img);
 
 
        }
 
 
    }
 
 
}


可以看出,MyRecyclerAdapter功能很简单,只实现了组件的加载和数据绑定




看下MainActivity

public class MainActivity extends Activity {
 
 
    private RecyclerView mRecyclerView;
 
 
    private LinearLayoutManager mLayoutManager;
 
 
    private MyRecyclerAdapter mAdapter;
 
 
    private List<Photo> mPhotoList;
 
 
    private int[] indexs = new int[]{R.mipmap.a, R.mipmap.b,
 
 
            R.mipmap.c, R.mipmap.e, R.mipmap.f, R.mipmap.g};
 
 

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

 
 
        //瀑布流式布局
 
 
        StaggeredGridLayoutManager staggeredGridLayoutManager =
 
 
                new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
 
 
        mRecyclerView.setLayoutManager(staggeredGridLayoutManager);
 
 
        initData();
 
 
        // 创建适配器,并且设置
 
 
        mAdapter = new MyRecyclerAdapter(mPhotoList);
 
 
        // 设置adapter
 
 
        mRecyclerView.setAdapter(mAdapter);
 
 
        // 设置Item增加、移除动画
 
 
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
 
 
        // 设置间距
 
 
        mRecyclerView.addItemDecoration(new SpaceItemDecoration(5));
 
 

 
 
    }
 
 

 
 
    private void initData() {
 
 
        mPhotoList = new ArrayList<>();
 
 
        for (int i = 0; i < indexs.length; i++) {
 
 
            Photo photo = new Photo();
 
 
            photo.setImg(indexs[i]);
 
 
            photo.setTitle("图片" + i);
 
 
            mPhotoList.add(photo);
 
 
        }
 
 
    }
 
 

 
 
}

在MainActivity中进行了数据的初始化,实际应用中,我们应该是从网络获取数据了,这也只是个model而已,前面我们说过给瀑布流加分割线的方法,但是分割线可能并不是我们想要的,例如我们只想有点间距就行了,无奈,RecyclerView并没有相关方法,我们通过改造分割线来实现下


public class SpaceItemDecoration extends RecyclerView.ItemDecoration {
 
 

 
 

 
 
    private int space;
 
 

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

 
 
    private int getSpanCount(RecyclerView parent) {
 
 
        // 列数
 
 
        int spanCount = -1;
 
 
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
 
 
        if (layoutManager instanceof GridLayoutManager) {
 
 
            spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
 
 
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
 
 
            spanCount = ((StaggeredGridLayoutManager) layoutManager)
 
 
                    .getSpanCount();
 
 
        }
 
 
        return spanCount;
 
 
    }
 
 
    private boolean isLastColum(RecyclerView parent, int pos, int spanCount,
 
 
                                int childCount) {
 
 
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
 
 
        if (layoutManager instanceof GridLayoutManager) {
 
 
            if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
 
 
            {
 
 
                return true;
 
 
            }
 
 
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
 
 
            int orientation = ((StaggeredGridLayoutManager) layoutManager)
 
 
                    .getOrientation();
 
 
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
 
 
                if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
 
 
                {
 
 
                    return true;
 
 
                }
 
 
            } else {
 
 
                childCount = childCount - childCount % spanCount;
 
 
                if (pos >= childCount)// 如果是最后一列,则不需要绘制右边
 
 
                    return true;
 
 
            }
 
 
        }
 
 
        return false;
 
 
    }
 
 

 
 
    private boolean isLastRow(RecyclerView parent, int pos, int spanCount,
 
 
                              int childCount) {
 
 
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
 
 
        if (layoutManager instanceof GridLayoutManager) {
 
 
            childCount = childCount - childCount % spanCount;
 
 
            if (pos >= childCount)// 如果是最后一行,则不需要绘制底部
 
 
                return true;
 
 
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
 
 
            int orientation = ((StaggeredGridLayoutManager) layoutManager)
 
 
                    .getOrientation();
 
 
            // StaggeredGridLayoutManager 且纵向滚动
 
 
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
 
 
                childCount = childCount - childCount % spanCount;
 
 
                // 如果是最后一行,则不需要绘制底部
 
 
                if (pos >= childCount)
 
 
                    return true;
 
 
            } else
 
 
            // StaggeredGridLayoutManager 且横向滚动
 
 
            {
 
 
                // 如果是最后一行,则不需要绘制底部
 
 
                if ((pos + 1) % spanCount == 0) {
 
 
                    return true;
 
 
                }
 
 
            }
 
 
        }
 
 
        return false;
 
 
    }
 
 

 
 
    @Deprecated
 
 
    public void getItemOffsets(Rect outRect, int itemPosition,View view,
 
 
                               RecyclerView parent, RecyclerView.State state) {
 
 
        int spanCount = getSpanCount(parent);
 
 
        int childCount = parent.getAdapter().getItemCount();
 
 
        if (isLastRow(parent, itemPosition, spanCount, childCount)) {// 如果是最后一行,则不需要绘制底部
 
 
            outRect.set(0, 0, space, 0);
 
 
        } else if (isLastColum(parent, itemPosition, spanCount, childCount)) {// 如果是最后一列,则不需要绘制右边
 
 
            outRect.set(0, 0, 0, space);
 
 
        } else {
 
 
            outRect.set(0, 0, space, space);
 
 
        }
 
 

 
 
    }
 
 
}


哈哈,其实和分割线差别不大,只是我们的分割线是透明的罢了,在这里我们要判断是否是最后一行,如果是,就不再绘制下面的分割线;判断是否是最后一列,如果是,就不再绘制右边的分割线 ,好了,效果实现!


参考:



http://www.bubuko.com/infodetail-999014.html

http://www.2cto.com/kf/201511/450814.html



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
Op9yysgqYUmV