在RecyclerView项目中显示动态视图数? [英] Showing a dynamic number of views in RecyclerView item?

查看:197
本文介绍了在RecyclerView项目中显示动态视图数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试重新创建它:

I am trying to re-create this:

我有一个数据列表:

List<Block> blocks;

Block.java类具有方法getNumBlocks(),该方法返回该项目应显示的块数.块的数量可以从1个块到20个块不等.

And the Block.java class has a method getNumBlocks() which returns the number of blocks that item should show. The number of blocks can range from something as small as 1 block to something as large as 20 blocks.

我创建了一个普通的RecyclerView适配器,以及该块的ImageView布局:

I created a normal RecyclerView adapter, along with the ImageView layout for the block:

public class BlockAdapter extends RecyclerView.Adapter<BlockAdapter.ViewHolder> {

    private Context context;

    private List<Block> blocks;

    public BlockAdapter(Context context, List<Block> blocks) {
        this.context = context;
        this.blocks = blocks;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public ImageView block;

        public ViewHolder(View v) {
            super(v);

            block = (ImageView) v.findViewById(R.id.block);
        }
    }

    @Override
    public BlockAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);

        View view = inflater.inflate(R.layout.block_layout, parent, false);

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        Block block = blocks.get(position);

        // How to use block.getNumBlocks() to show the correct number of blocks?
    }

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

}

这里是block_layout.xml(它只是一个空的LinearLayout,应该在此LinearLayout的内部添加块):

Here is block_layout.xml (it's just an empty LinearLayout, the blocks should be added inside of this LinearLayout):

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/card_bg"
    android:padding="16dp">


</LinearLayout>

这是block.xml布局:

<ImageView
    android:id="@+id/block"
    android:layout_width="18dp"
    android:layout_height="18dp"
    android:layout_marginEnd="8dp"
    android:layout_marginRight="8dp" />

所以我的问题是,我该如何实现它以便为每个RecyclerView项目显示正确的块数?

So my question is, how can I implement this so that it shows the correct number of blocks for each RecyclerView item?

执行此明智的操作的最佳方法是什么?

What is the best way to do this performance wise?

推荐答案

您最好关心性能.每次要显示一行时都创建新的ImageViews与回收视图的想法背道而驰.基本上,在滚动时,您将仅重用顶层视图,但是每次出现在屏幕上时,仍会为任何项目创建新的ImageViews.

It's good that you care about performance. Creating new ImageViews every time you want to display a row is against the idea of recycling views. Basically when scrolling you would re-use only the top level views, but still creating new ImageViews for any item every time it appears on screen.

要解决这个问题,您可以创建自己的视图库,如下所示:

To deal with that you can create your own pool of views like that:

public class BlockAdapter extends RecyclerView.Adapter<BlockAdapter.ViewHolder> {

    private final List<Block> blocks;
    private final List<ImageView> imageViewPool = new LinkedList<>();

    public BlockAdapter(List<Block> blocks) {
        this.blocks = blocks;
    }

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

    @Override
    public BlockAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.block_layout, parent, false));
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        holder.bind(blocks.get(position));
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        private final List<ImageView> imageViews = new ArrayList<>();
        private final ViewGroup container;

        public ViewHolder(View v) {
            super(v);
            container = (ViewGroup) itemView;
        }

        public void bind(Block block) {
            recycleImageViews();
            for (int i = 0; i < block.getNumBlocks(); ++i) {
                final ImageView imageView = getRecycledImageViewOrCreate();
                imageViews.add(imageView);
                container.addView(imageView);
            }
        }

        private ImageView getRecycledImageViewOrCreate() {
            if (imageViewPool.isEmpty()) {
                return (ImageView)LayoutInflater.from(container.getContext()).inflate(R.layout.block, container, false);
            }
            return imageViewPool.remove(0);
        }

        public void recycleImageViews() {
            imageViewPool.addAll(imageViews);
            imageViews.clear();
            container.removeAllViews();
        }
    }

    @Override
    public void onViewRecycled(ViewHolder holder) {
        super.onViewRecycled(holder);
        holder.recycleImageViews();
    }
}

此解决方案的思想与RecyclerView的思想非常相似.

The idea behind this solution is very similar to what RecyclerView does.

每次ViewHolder想要显示子项目时,它都会:

Every time ViewHolder wants to present sub items it will:

  • imageViewPool中获取ImageView.如果池中没有多余的人,则会给新人充气.
  • 将此ImageView附加到自身.
  • Take ImageView from the imageViewPool. If there is no spare one in the pool, a new one will be inflated.
  • Attach this ImageView to itself.

稍后,当特定的ViewHolder被重新使用或回收时,它将:

Later, when particular ViewHolder is re-used or recycled it will:

  • 从自己身上拆下所有ImageViews.
  • 将那些ImageViews返回到可重复使用的池中,以便出现在屏幕上的下一项可以使用它们.
  • Detach all ImageViews from itself.
  • Return those ImageViews to re-usable pool so next item that will appear on the screen can take those.

这篇关于在RecyclerView项目中显示动态视图数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆