代码之家  ›  专栏  ›  技术社区  ›  Pierre

为RecyclerView缓存可扩展字符串

  •  3
  • Pierre  · 技术社区  · 6 年前

    我有一个RecyclerView,它包含很多信息,类似于聊天屏幕。

    在每个列表项中,我都有一个 TextView 其中我设置 Spannable 串。字符串包含图像和文本,有时仅包含文本。我必须将字符串中的一些字符替换为 Drawables 当有大量的字符需要替换为图像时,会产生明显的抖动/滞后 onScroll . 我还将成本高昂的方法 AsyncTask 这大大提高了回收视图的速度。

    问题:

    可以缓存一个 可纺的 对象及其所有元数据?如果用户向上滚动一两个屏幕,然后再向下滚动,我希望尝试避免 Spannables 每次在屏幕上呈现行时生成。

    如果缓存是可能的,我甚至会进一步实现一个“预缓存”方法,它在一个单独的线程上构建和缓存可扩展文件,因此如果用户上下滚动,它将只是从缓存加载,而不是构建它,如果它存在,导致“更快”或“更平滑”的用户体验。

    拖鞋

    可拖动文件是从 FilePaths ,插入为 ImageSpan 在可展字符串之后设置为 文本框 在AsyncTask中。

    2 回复  |  直到 6 年前
        1
  •  0
  •   Oknesif    6 年前

    首先,我建议你看看 setItemViewCacheSize(int) 方法 RecyclerView . 下一步,如果你的 Spannable 也许值得检查一下这个抽屉的尺寸,它们可能太大了。另一个想法是在将项目传递给 bindViewHolder .

        2
  •  0
  •   Pierre    6 年前

    我能够实现我想要的。

    - 1。创建一个类 LruSpannableCache 延伸到 LruCache

    并覆盖 sizeOf 方法

    @override
    protected int sizeOf(Object key, Object value)
    {
        //The cache size will be measured in kilobytes rather than number of items.
        return ((CacheSpannable)value).size() / 1024;
    }
    

    - 2。创建了一个对象 CacheSpannable

    public class CacheSpannable
    {
        private int key;
        private ISpannable text;
    
        // Getters and Setters for key and text...
    
        public int size()
        {
            return text.length(); //Can also add the byte length for `key`
        }
    }
    

    - 3。最后用静态方法创建了一个类 add get 缓存的Spannables

    private static LruCache spannableCache;
    private static final int cacheSize = Runtime.getRuntime().maxMemory() / 1024 / 6;
    
    public static void addSpannable(int key, CacheSpannable value)
    {
        if (spannableCache == null) spannableCache = new LruSpannableCache(cacheSize);
    
        if (getSpannable(key) == null)
        {
            spannableCache.put(key, value);
        }
    }
    
    public static CacheSpannable getSpannable(int key)
    {
        if (spannableCache == null) spannableCache = new LruSpannableCache(cacheSize);
    
        return (CacheSpannable)spannableCache.get(key);
    }
    

    然后使用它,我只需检查 Spannable 被缓存(缓存) getSpannable(key) != null )然后将其设置为 TextView 或者,如果没有,构建它,添加到缓存,然后将其设置为 文本框 .

    下一步将是实现磁盘缓存以无限期地持久化可扩展性