在RecyclerView项目中显示动态视图数? [英] Showing a dynamic number of views in RecyclerView item?
问题描述
我正在尝试重新创建它:
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屋!