gpt4 book ai didi

android - 在 RecyclerView 项目中显示动态数量的 View ?

转载 作者:搜寻专家 更新时间:2023-11-01 08:27:50 24 4
gpt4 key购买 nike

我正在尝试重新创建这个:

enter image description here

我有一个数据列表:

List<Block> blocks;

并且 Block.java 类有一个方法 getNumBlocks() 返回该项目应该显示的 block 数。 block 的数量可以从小到 1 个 block 到大到 20 个 block 不等。

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

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, block 应该添加到这个 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 项目显示正确的 block 数?

实现此性能明智的最佳方法是什么?

最佳答案

您关心性能是件好事。每次要显示一行时都创建新的 ImageViews 与回收 View 的想法背道而驰。基本上,当滚动时,您只会重用顶级 View ,但每次出现在屏幕上时,仍会为任何项目创建新的 ImageViews

要解决这个问题,您可以像这样创建自己的 View 池:

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 所做的非常相似。

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

  • imageViewPool 中获取 ImageView。如果池中没有备用的,则会充气一个新的。
  • 将此 ImageView 附加到自身。

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

  • 从自身分离所有 ImageViews
  • 将那些 ImageViews 返回到可重复使用的池中,以便屏幕上出现的下一个项目可以使用它们。

关于android - 在 RecyclerView 项目中显示动态数量的 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43101231/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com