glide recyclerview集成的进展如何?

时间:2017-12-05 22:51:54

标签: android android-recyclerview kotlin android-glide recyclerview-layout

我只是尝试使用glide recyclerview集成并阅读有关它的文档,它说:“ RecyclerView集成库使您的应用程序中可以使用RecyclerViewPreloader .RecyclerViewPreloader可以在用户滚动的位置之前自动加载图像在RecyclerView “中,但我没有意识到滑翔回收视图集成和滑行之间的任何区别,请解释滑翔回收视图集成的进展是什么?我怎么能看出差异呢?

这是我的代码:

GlideModule.kt

@GlideModule
class GlideModule : AppGlideModule() {
    override fun applyOptions(context: Context?, builder: GlideBuilder?) {
        val requestOp = RequestOptions.noAnimation()
                .priority(Priority.LOW)
        builder?.setDefaultRequestOptions(requestOp)
                ?.setLogLevel(Log.VERBOSE)
        super.applyOptions(context, builder)
    }

    // Disable manifest parsing to avoid adding similar modules twice.
    override fun isManifestParsingEnabled(): Boolean {
        return false
    }
}

MyPreloadModelProvide.kt

class MyPreloadModelProvide(val listUrls: List<String>, val context: Context) : PreloadModelProvider<Any> {
    override fun getPreloadItems(position: Int): MutableList<Any> {
        val url = listUrls.get(position)
        if (TextUtils.isEmpty(url)) {
            return Collections.emptyList();
        }
        return Collections.singletonList(url);
    }

    override fun getPreloadRequestBuilder(url: Any?): RequestBuilder<*>? {
        return GlideApp.with(context)
                .load(url)
    }

}

MyAdapter.kt

class MyAdapter(val listUrl: List<String>, val context: Context) : RecyclerView.Adapter<MyViewHolder>() {
    override fun getItemCount(): Int = listUrl.size

    @SuppressLint("CheckResult")
    override fun onBindViewHolder(holder: MyViewHolder?, position: Int) {

        GlideApp.with(context)
                .load(listUrl[position])
                .into(holder?.imageView)

        holder?.imageView?.setOnClickListener { Toast.makeText(context, listUrl[position], Toast.LENGTH_LONG).show() }
    }

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): MyViewHolder = MyViewHolder(LayoutInflater.from(parent?.context).inflate(R.layout.item, parent, false))
}

class MyViewHolder(view: View?) : RecyclerView.ViewHolder(view) {
    var imageView: ImageView

    init {
        imageView = view!!.findViewById(R.id.img)
    }
}

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private lateinit var preloadSizeProvider: ViewPreloadSizeProvider<Any>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // glide
        var listUrls = listOf(
                "https://img.pokemondb.net/artwork/bulbasaur.jpg",
                "https://img.pokemondb.net/artwork/ivysaur.jpg",
                "https://img.pokemondb.net/artwork/komala.jpg",
                "https://img.pokemondb.net/artwork/turtonator.jpg",
                "https://img.pokemondb.net/artwork/togedemaru.jpg",
                "https://img.pokemondb.net/artwork/mimikyu.jpg",
                "https://img.pokemondb.net/artwork/nihilego.jpg",
                "https://img.pokemondb.net/artwork/buzzwole.jpg",
                "https://img.pokemondb.net/artwork/pheromosa.jpg",
                "https://img.pokemondb.net/artwork/xurkitree.jpg",
                "https://img.pokemondb.net/artwork/celesteela.jpg",
                "https://img.pokemondb.net/artwork/kartana.jpg",
                "https://img.pokemondb.net/artwork/guzzlord.jpg",
                "https://img.pokemondb.net/artwork/necrozma.jpg",
                "https://img.pokemondb.net/artwork/magearna.jpg",
                "https://img.pokemondb.net/artwork/marshadow.jpg"
        )

        preloadSizeProvider = ViewPreloadSizeProvider<Any>()
        val modelProvider = MyPreloadModelProvide(listUrls, this)
        val preloader = RecyclerViewPreloader(GlideApp.with(this), modelProvider, preloadSizeProvider, 2 /*maxPreload*/)

        // recycler view
        recycler_view.layoutManager = LinearLayoutManager(this)
        recycler_view.setHasFixedSize(true)
        recycler_view.adapter = MyAdapter(listUrls, this)

        // THERE ARE NO DIFFERENCES IF I COMMENT THIS LINE
        recycler_view.addOnScrollListener(preloader)
    }
}

如果我评论这一行,那就没有区别了 recycler_view.addOnScrollListener(preloader)

3 个答案:

答案 0 :(得分:2)

RecyclerView集成库使您的应用程序中的RecyclerViewPreloader可用 RecyclerViewPreloader可以在用户滚动RecyclerView之前自动加载图片。

通过确保用户即将到达的图像已经在存储器中。

要使用RecyclerView集成库,请在build.gradle文件中添加依赖项:

compile ("com.github.bumptech.glide:recyclerview-integration:4.4.0") {
  /*Excludes the support library 
    because it's already included by Glide.*/
  transitive = false
}

答案 1 :(得分:0)

假设用户正在滚动加载大图像的RecyclerView,因此,用户应该等待加载图像的延迟,然后才能在相应的列表项中看到它。 RecyclerViewPreloader提前加载图像,因此当用户滚动时,已经加载并立即显示。

在您的代码中,您使用的是一个小列表和一个小的maxPreload值,因此您不会注意到使用RecyclerViewPreloader的区别。要查看它的实际效果,您应该使用包含许多不同图像的长列表,并使用和不使用预加载器快速滚动。如果没有预加载器,您将看到空图像,直到加载为止,图像应该快速平滑地显示。

答案 2 :(得分:0)

您的代码中的问题是您创建了 preloadSizeProvider 类型的 ViewPreloadSizeProvider,但您从未对其调用 preloadSizeProvider.setView(...)。所以它不知道你的目标视图的大小,所以它不能以正确的大小预加载图像,所以你看不到任何改进。

我建议首先尝试使其以固定大小工作。因此,不要使用 ViewPreloadSizeProvider 创建 FixedPreloadSizeProvider(WIDTH, HEIGHT) 并确保在通过 Glide 加载图像时使用相同的大小 Glide.with(this).load(imageUri).override(WIDTH, HEIGHT).into(imageView);

如果您想检查它是否有效,请为这两个 Glide 请求启用日志记录(为了简单起见,我在那里使用了 Java 代码):

MyPreloadModelProvide.kt

class MyPreloadModelProvide(val listUrls: List<String>, val context: Context) : PreloadModelProvider<Any> {

    override fun getPreloadRequestBuilder(url: Any?): RequestBuilder<*>? {
        return GlideApp.with(context)
                .override(250, 250)
                .dontTransform()
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        Log.d("IMAGE PRELOAD", "onResourceReady() called with: model = [" + model + "], target = [" + target + "], dataSource = [" + dataSource + "]");
                        return false;
                    }
                })
                .load(url)
    }

}

MyAdapter.kt

class MyAdapter(val listUrl: List<String>, val context: Context) : RecyclerView.Adapter<MyViewHolder>() {
    override fun getItemCount(): Int = listUrl.size

    @SuppressLint("CheckResult")
    override fun onBindViewHolder(holder: MyViewHolder?, position: Int) {

        GlideApp.with(context)
                .load(listUrl[position])
                .override(250, 250)
                .dontTransform()
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        Log.d("IMAGE LOAD", "onResourceReady() called with: model = [" + model + "], target = [" + target + "], dataSource = [" + dataSource + "]");
                        return false;
                    }
                })
                .into(holder?.imageView)

        holder?.imageView?.setOnClickListener { Toast.makeText(context, listUrl[position], Toast.LENGTH_LONG).show() }
    }
}

在 logcat 中,您应该看到 PRELOAD 请求的 dataSource = [LOCAL] 或 [RESOURCE_DISK_CACHE] 并且 LOAD 请求的 dataSource = [MEMORY_CACHE]。

如果有效,那就太好了。然后您可以重写它以使用 ViewPreloadSizeProvider。在这种情况下,您从 Glide 请求中删除固定图像大小 (.override(250,250)),然后不要忘记在 preloadSizeProvider.setView(holder.imageView) 方法中调用 onCreateViewHolder