android - 使用 StaggeredGridLayoutManager 预加载 Android Recyclerview 项目

标签 android performance android-recyclerview

问题:如何预加载 recyclerview 项目以便为用户提供最佳用户体验。

找到这个 blog做同样的事情,但它使用 LinearLayoutManager 而不是 StaggeredGridLayoutManager

方法 setExtraLayoutSpacesetInitialPrefetchItemCount(int)StaggeredGridLayoutManager API 中不可用。

我如何在用户滚动之前加载一些 items(images) 以提供更好的用户体验。

最佳答案

Its not the perfect way but still it works.

Create intent service for loading/cache images in background when user scroll to load new post it will fetch it from cache instead of going to server.

ImageCahce.java

public class ImageCache extends IntentService {

    Context mContext;

    public ImageCache() {
        super("ImageCache");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;
        Log.d("ImageCache", "Service Started");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null)
            if (intent.getStringExtra(Constants.IncomingClass) != null)
                if (intent.getStringExtra(Constants.IncomingClass).equalsIgnoreCase("Trending")) {
                    ArrayList<Trending> items = intent.getExtras().getParcelableArrayList(Constants.CacheKey);
                    StartCachingImages(items);
                }
        return START_NOT_STICKY;
    }

    //Trending logic
    private void StartCachingImages(final ArrayList<Trending> items) {

        if (items != null) {
            if (!items.isEmpty()) {
                for (int i = 0; i < items.size(); i++) {

                    Post pogo = items.get(i).postObj;
                    String imagePath = "";
                    if (pogo.type.equalsIgnoreCase("Picture")) {
                        imagePath = pogo.picture;
                    } else if (pogo.type.equalsIgnoreCase("Video")) {
                        imagePath = pogo.thumbnail;
                    } else if (pogo.type.equalsIgnoreCase("Multimedia")) {
                        //  imagePath = pogo.thumbnail;
                        if (pogo.picture.length() > 0) imagePath = pogo.picture;
                        else imagePath = pogo.thumbnail;
                    }

                    //Log.d("ImageCache", "index " + i + " started");
                    BackgroundCaching backgroundCaching = new BackgroundCaching(i, imagePath, items.get(i).userObj.picture);
                    backgroundCaching.execute();
                }
                //Log.d("ImageCache", "Self stopping");
                ImageCache.this.stopSelf();
            }
        }
    }

    class BackgroundCaching extends AsyncTask<String, Void, String> {

        String path, thumbnail;
        int id;

        public BackgroundCaching(int id, String path, String thumbnail) {
            this.id = id;
            this.path = path;
            this.thumbnail = thumbnail;
        }

        @Override
        protected String doInBackground(String... params) {
            try {
                FutureTarget<File> future = Glide.with(mContext).load(path)
                        .downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
                future.get();
                //Log.d("ImageCache", "Loaded actual " + id);
            } catch (Exception e) {
                //Log.d("ImageCache", "Failed to load ->" + path);
            }
            try {
                FutureTarget<File> future = Glide.with(mContext).load(thumbnail)
                        .downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
                future.get();

                //Log.d("ImageCache", "Loaded thumbnail " + id);
            } catch (Exception e) {
                //Log.d("ImageCache", "Failed to load ->" + thumbnail);
            }
            return "Executed";
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("ImageCache", "Service Stopped");
    }
}

使用StartImageCacheService()启动服务。

 void StartImageCacheService(Context context, LinkedList<com.fayvo.Model.Trending> trendingHash) {
        if (context != null && trendingHash.size() > 0) {
            Intent i = new Intent(context, ImageCache.class);
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            i.putParcelableArrayListExtra(Constants.CacheKey, new ArrayList<com.fayvo.Model.Trending>(trendingHash));
            i.putExtra(Constants.IncomingClass, "Trending");
            context.startService(i);
        }
    }

为了给用户更好的体验

关于android - 使用 StaggeredGridLayoutManager 预加载 Android Recyclerview 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45437197/

相关文章:

android - react native android : app state when on another activity

javascript - 什么是更好的性能明智,1 个巨大的 js 和 css 文件或多个文件

android - 使用android数据绑定(bind)将数据从Recycler View onClick传递到Detail Activity

java - 如何在 Android 中创建 Google 注销类文件

java - 通过 AdapterPosition 获取 RecyclerView 的 View

c# - 使用 MonoGame 和双指手势实现缩放

android - 从测试内部下载的相同应用程序版本与从内部应用程序共享下载的相同应用程序版本之间的应用程序大小差异

performance - 微软 Access 2010 : query slows down dramatically when using parameters

android - 检查服务是否正在从广播接收器运行

C++ 初始值设定项列表 std::array 最佳性能