RecyclerView 流式布局

RecyclerView 流式布局的一个demo,从网上下载的,我稍微改了一下,随手记下来备用.
另外这个demo的代码忘记是从哪个blog下载的了,后续找到了我会补上link
效果图

主要有几个类:
Activity


public class MainActivity extends Activity {
    RecyclerView mRecyclerView;
    ArrayList<Product> mProductList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRecyclerView = (RecyclerView) findViewById(R.id.recycleview);
        //设置layoutManager
        mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
        //设置adapter
        initData();
        MasonryAdapter adapter = new MasonryAdapter(mProductList);
        mRecyclerView.setAdapter(adapter);
        //设置item之间的间隔
        SpacesItemDecoration decoration = new SpacesItemDecoration(16);
        mRecyclerView.addItemDecoration(decoration);

    }

    private int getRandomInt(int size) {
        Random random = new Random();
        return random.nextInt(size);
    }

    int[] ids = {R.drawable.img0, R.drawable.img1, R.drawable.img2, R.drawable.img3};
    String title = "asdasdasdasdasdasdasd";
    String[] titles = {title + title, title + title + title, title, title + title + title + title};

    void initData() {
        if (mProductList == null) {
            mProductList = new ArrayList<Product>();
        }
        for (int i = 0; i < 40; i++) {
            Product p = new Product(ids[getRandomInt(4)], titles[getRandomInt(4)]);
            mProductList.add(p);
        }
    }
}

Adapter

public class MasonryAdapter extends RecyclerView.Adapter<MasonryAdapter.MasonryView>{
    private List<Product> products;


    public MasonryAdapter(List<Product> list) {
        products=list;
    }

    @Override
    public MasonryView onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
        return new MasonryView(view);
    }

    @Override
    public void onBindViewHolder(MasonryView masonryView, int position) {
        masonryView.imageView.setImageResource(products.get(position).getImg());
        masonryView.textView.setText(products.get(position).getTitle()+"----"+String.valueOf(position));
//        masonryView.textView.setText(String.valueOf(position));
    }

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

    public static class MasonryView extends  RecyclerView.ViewHolder{

        ImageView imageView;
        TextView textView;

        public MasonryView(View itemView){
            super(itemView);
            imageView= (ImageView) itemView.findViewById(R.id.img );
            textView= (TextView) itemView.findViewById(R.id.title);
        }

    }

}

还有这个比较重要

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;
        //第一个不设置间隔,否则顶部有空白
        if (parent.getChildPosition(view) == 0 || parent.getChildPosition(view) == 1) {
            outRect.top = space;
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RecyclerView本身并不支持流式布局,但是可以通过自定义LayoutManager来实现流式布局。下面是一个简单的实现步骤: 1. 创建一个继承自RecyclerView.LayoutManager的自定义LayoutManager。 2. 在自定义LayoutManager中重写onLayoutChildren方法,实现流式布局的摆放。 3. 在onMeasure方法中计算RecyclerView的宽高。 4. 在RecyclerView.Adapter中根据需要调整item的宽高,以适配流式布局。 以下是一个简单的示例代码: ```java public class FlowLayoutManager extends RecyclerView.LayoutManager { private int mTotalHeight; @Override public RecyclerView.LayoutParams generateDefaultLayoutParams() { return new RecyclerView.LayoutParams( RecyclerView.LayoutParams.WRAP_CONTENT, RecyclerView.LayoutParams.WRAP_CONTENT); } @Override public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { if (state.getItemCount() == 0) { return; } detachAndScrapAttachedViews(recycler); int offsetX = getPaddingLeft(); int offsetY = getPaddingTop(); int lineMaxHeight = 0; int width = getWidth(); for (int i = 0; i < getItemCount(); i++) { View child = recycler.getViewForPosition(i); addView(child); measureChildWithMargins(child, 0, 0); int childWidth = getDecoratedMeasuredWidth(child); int childHeight = getDecoratedMeasuredHeight(child); if (offsetX + childWidth > width - getPaddingRight()) { offsetX = getPaddingLeft(); offsetY += lineMaxHeight; lineMaxHeight = 0; } layoutDecorated(child, offsetX, offsetY, offsetX + childWidth, offsetY + childHeight); offsetX += childWidth; lineMaxHeight = Math.max(lineMaxHeight, childHeight); } mTotalHeight = offsetY + lineMaxHeight + getPaddingBottom(); } @Override public boolean canScrollVertically() { return true; } @Override public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { if (getChildCount() == 0 || dy == 0) { return 0; } int scrolled = 0; if (dy > 0) { View lastChild = getChildAt(getChildCount() - 1); int lastVisiblePos = getPosition(lastChild); if (lastVisiblePos == getItemCount() - 1 && lastChild.getBottom() - dy < getHeight() - getPaddingBottom()) { dy = lastChild.getBottom() - getHeight() + getPaddingBottom(); } } else { View firstChild = getChildAt(0); int firstVisiblePos = getPosition(firstChild); if (firstVisiblePos == 0 && firstChild.getTop() - dy > getPaddingTop()) { dy = firstChild.getTop() - getPaddingTop(); } } offsetChildrenVertical(-dy); scrolled += dy; fill(recycler); return scrolled; } private void fill(RecyclerView.Recycler recycler) { int topOffset = getPaddingTop(); int leftOffset = getPaddingLeft(); int lineMaxHeight = 0; int width = getWidth(); for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); int childWidth = getDecoratedMeasuredWidth(child); int childHeight = getDecoratedMeasuredHeight(child); if (leftOffset + childWidth > width - getPaddingRight()) { leftOffset = getPaddingLeft(); topOffset += lineMaxHeight; lineMaxHeight = 0; } layoutDecorated(child, leftOffset, topOffset, leftOffset + childWidth, topOffset + childHeight); leftOffset += childWidth; lineMaxHeight = Math.max(lineMaxHeight, childHeight); } detachAndScrapAttachedViews(recycler); } @Override public int computeVerticalScrollOffset(RecyclerView.State state) { return computeVerticalScrollExtent(state); } @Override public int computeVerticalScrollExtent(RecyclerView.State state) { return getHeight() - getPaddingTop() - getPaddingBottom(); } @Override public int computeVerticalScrollRange(RecyclerView.State state) { return mTotalHeight; } } ``` 使用时只需要将RecyclerView的LayoutManager设置为自定义的FlowLayoutManager即可实现流式布局
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值