在 RecyclerView 项目中显示动态数量的视图?

2024-03-11

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

我有一个数据列表:

List<Block> blocks;

And the Block.java类有一个方法getNumBlocks()它返回该项目应显示的块数。块的数量可以小到 1 个块,大到 20 个块。

我创建了一个普通的 RecyclerView 适配器,以及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();
    }

}

Here is block_layout.xml(它只是一个空的 LinearLayout,块应该添加到这个 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 layout:

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

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

做这个的最好方式是什么性能方面?


您关心性能是件好事。创造新ImageViews每次想要显示一行都违背了回收视图的想法。基本上,当滚动时,您只会重复使用顶层视图,但仍然创建新的ImageViews任何项目每次出现在屏幕上时。

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

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 does.

每次ViewHolder想要呈现子项目,它将:

  • 从中获取 ImageViewimageViewPool。如果池子里没有备用的,就会充气一个新的。
  • 附上这个ImageView对自己。

后来,当特别ViewHolder重新使用或回收将:

  • 全部分离ImageViews来自自身。
  • 返回那些ImageViews到可重复使用的池中,以便屏幕上出现的下一个项目可以使用这些项目。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 RecyclerView 项目中显示动态数量的视图? 的相关文章

随机推荐

  • jQuery 选择器性能

    我知道我只是对几毫秒的表演时间有强迫症 但我只是想知道为什么以下内容对我来说是正确的 这似乎违背了我的逻辑 我目前有一个 div 它在悬停时淡出内部图像 div someclass hover function this children
  • 如何使用一个文件输入元素上传多个文件

    我正在尝试使用一个文件输入元素使用 html 表单将多个文件上传到云端硬盘 尽管文件选择器允许选择多个文件 但这似乎仅适用于一个文件 回到脚本日志查看器 我只看到我上传的两个文件中捕获的一个文件 这是不受支持的 还是我走错了路 Code g
  • 标记位置更改事件

    我正在使用新的 Android 版 Google 地图 v2 有没有办法为标记位置变化设置监听器 例如 当用户拖动标记时 Quoting 文档 https developers google com maps documentation a
  • R 中 SumIf 函数的等效项是什么

    我是 R 和这个网站的新手 但我搜索后没有找到我正在寻找的答案 如果我有以下数据集 总计 names lt c a b c d a b c d x lt cbind x1 3 x2 c 3 10 total lt data frame na
  • 如何将 JSONP 数据类型与 Ember 数据结合使用?

    如何设置 Ember Data 在进行 ajax 调用时使用 JSONP 数据类型 我将使用 Ember 和 Phonegap 并需要发出跨域请求 覆盖私有的要容易得多ajaxOptions函数而不是使用jQuery 无论如何 Ember
  • 如何在facet_wrap中将label_wrap_gen与as_labeller一起使用

    我有一个方面图 并且想将方面条标题包装在多行上 如果超过一定数量的字符 所以我知道我使用labeller label wrap gen 10 比如包裹超过 10 个字符 当传递给facet wrap不过 我也想传递新的标签 我知道我可以使用
  • 如何仅将图片框显示的内容捕获为位图,而不使用“从屏幕复制”?

    具体来说 我需要将图片框实际显示的特定区域捕获为位图 该区域的坐标由我覆盖在图片框顶部的控件的边界指定 但该控件属于图片框 当我制作该区域的 快照 时 该控件被隐藏 我尝试使用普通的屏幕捕获方法 CopyFromScreen 但您无法真正控
  • Greasemonkey调试,获取真实行号

    我正在尝试让 Greasemonkey 用户脚本正常工作 但它一直抛出异常 缺少 声明之前 在 Javascript 错误控制台中 Greasemonkey 文档说应该忽略行号 但由于脚本相当长 因此了解错误发生的位置将非常有帮助 我怎样才
  • 使用 Javascript 旋转文本

    我想循环浏览一系列单词来创建文本旋转效果 我的大部分工作都按预期进行 有什么方法可以在 p 元素的长度上使用 css 过渡吗 当从 char length gt 10 的对象遍历到 char length HTML p span span
  • 通过经过身份验证的 Web 表单保护 ASP.net 中的 Ajax 请求

    我已经读过通过 GUID 保护 AJAX 请求 https stackoverflow com questions 652851 securing ajax requests via guid and 保护 ajax 请求 https st
  • 安装 XAMPP 时如何使用 UAC

    我正在将 Xampp 安装到我的计算机上 但是当我尝试安装它时 会出现一个对话框 我该如何解决这个问题 非常感谢您的帮助 对话框 重要的 因为您的系统上已激活用户帐户控制 UAC XAMPP 的功能可能受到限制 使用UAC请避免安装XAMP
  • Vertx 线程阻塞警告

    我正在 ubuntu 服务器上运行 vert x 应用程序 它有一个在端口 3000 上运行的 HTTPServer 应用程序工作正常 但有时我会看到以下警告 Dec 08 2017 1 23 43 AM io vertx core imp
  • 将额外数据传递给 finder auth

    我的发现者来自Auth有我需要访问的条件 this gt request但我无权访问UsersTable 应用控制器 初始化 this gt loadComponent Auth authenticate gt Form gt finder
  • 什么是 __CxxFrameHandler4 以及链接器错误“无法解析的外部符号 __CxxFrameHandler4”究竟意味着什么?

    我正在针对我的 Visual C 项目使用通过 vcpkg 构建的多个库 例如 civet web 和 prometheus cpp 当构建 x86 时一切都很完美 在 x64 中我收到一堆链接器错误 错误 LNK2001 无法解析的外部符
  • Java 相当于 PHP 简单 HTML DOM 解析器

    由于我必须使用多线程 而我无法在 PHP 中雄辩地解决这个问题 所以我想用 Java 进行编程 不幸的是 我找不到一个库 它可以让我像在 PHP 中那样强大 快速 轻松地解析 HTML DOM 简单的 HTML DOM 解析器 您知道 Ja
  • db.getCollectionInfos 不是一个函数

    我正在编写一个 MERN 应用程序 并尝试使用以下命令获取 MongoDB 数据库中的所有集合名称db getCollectionInfos method https docs mongodb com manual reference me
  • WPF-如何在 控件中显示 ImageSource 的裁剪区域?

    WPF 如何在控件中显示 ImageSource 的裁剪区域 我有一个可用像素大小的 ImageSource 我有一个计算出的裁剪矩形 指示我们实际要使用多少图像 我不想直接编辑图像数据 但我想要我的
  • 如何阻止 vaadin 窃取所有 url 模式(并与 spring mvc 很好地配合)

    我有一个 vaadin 应用程序 我试图提供一些由 spring MVC 提供的 REST URL 我的 web xml 如下 我只在 info 处收到 404 错误 看起来 Vaadin 窃取了所有 url 模式 如果我删除 Vaadin
  • 无法将 Firebase 函数拆分到多个文件中

    我正在使用 firebase 函数并达到数百个函数 现在很难用单个函数来管理它index js文件如大量示例所示 我尝试将该函数拆分为多个文件 例如 firebase json functions node modules index js
  • 在 RecyclerView 项目中显示动态数量的视图?

    我正在尝试重新创建这个 我有一个数据列表 List