Android StaggeredGridLayoutManager布局RecyclerView在滚动状态可见范围刷新数据

简介: Android StaggeredGridLayoutManager布局RecyclerView在滚动状态可见范围刷新数据之所以把StaggeredGridLayoutManager布局的RecyclerView单列出...

Android StaggeredGridLayoutManager布局RecyclerView在滚动状态可见范围刷新数据


之所以把StaggeredGridLayoutManager布局的RecyclerView单列出来处理滚动状态下可见(可视)范围内的数据更新问题,是因为在StaggeredGridLayoutManager布局下的RecyclerView,对于第一个可视item和最后一个可视item,即第一个可视item位置和最后一个可视item位置,不像在LinearLayoutManager布局下直接获取,需要进行一个简单计算。关键的计算过程我写在了getOutRange()方法内。

package zhangphil.recyclerview;

import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Arrays;

public class RecyclerViewActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private RecyclerViewAdapter mAdapter;
    private StaggeredGridLayoutManager layoutManager;
    private ArrayList<String> mItems;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.recycler_view_activity);

        mItems = new ArrayList<>();
        for (int i = 0; i < 110; i++) {
            mItems.add(i + "");
        }

        initRecyclerView();

        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);

                if (recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE) {
                    int[] outRange = getOutRange();
                    int len = outRange[1] - outRange[0] + 1;

                    int num = (int) (Math.random() * 10);
                    for (int i = 0; i < len; i++) {
                        mItems.set(outRange[0] + i, num + "");
                    }

                    mAdapter.notifyDataSetChanged();
                }
            }
        });
    }

    private int[] getOutRange() {
        int[] range = new int[2];

        int[] first = new int[layoutManager.getSpanCount()];
        layoutManager.findFirstVisibleItemPositions(first);

        int[] last = new int[layoutManager.getSpanCount()];
        layoutManager.findLastVisibleItemPositions(last);

        range[0] = first[0];

        Arrays.sort(last);
        range[1] = last[last.length - 1];

        return range;
    }

    private void initRecyclerView() {
        mRecyclerView = findViewById(R.id.recycler_view);
        layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(layoutManager);

        mAdapter = new RecyclerViewAdapter();
        mRecyclerView.setAdapter(mAdapter);
    }

    private class RecyclerViewAdapter extends RecyclerView.Adapter<MyVH> {

        @NonNull
        @Override
        public MyVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(getApplicationContext()).inflate(android.R.layout.simple_list_item_2, parent, false);
            return new MyVH(view);
        }

        @Override
        public void onBindViewHolder(@NonNull MyVH holder, int position) {
            holder.text1.setText("" + position);
            holder.text2.setText(mItems.get(position));
        }

        @Override
        public int getItemCount() {
            return mItems.size();
        }
    }

    private class MyVH extends RecyclerView.ViewHolder {
        public TextView text1;
        public TextView text2;

        public MyVH(View itemView) {
            super(itemView);
            text1 = itemView.findViewById(android.R.id.text1);
            text1.setTextColor(Color.WHITE);
            text1.setBackgroundColor(Color.RED);
            text2 = itemView.findViewById(android.R.id.text2);
            text2.setTextColor(Color.DKGRAY);
        }
    }
}

代码实现一个简单意图,用StaggeredGridLayoutManager控制RecyclerView,当RecyclerView滚动停止后,更新可可范围内的数据到最新。

如图:



相关文章
|
2月前
|
ARouter Android开发
Android不同module布局文件重名被覆盖
Android不同module布局文件重名被覆盖
|
4月前
|
移动开发 监控 前端开发
构建高效Android应用:从优化布局到提升性能
【7月更文挑战第60天】在移动开发领域,一个流畅且响应迅速的应用程序是用户留存的关键。针对Android平台,开发者面临的挑战包括多样化的设备兼容性和性能优化。本文将深入探讨如何通过改进布局设计、内存管理和多线程处理来构建高效的Android应用。我们将剖析布局优化的细节,并讨论最新的Android性能提升策略,以帮助开发者创建更快速、更流畅的用户体验。
67 10
|
3月前
|
Android开发 开发者 索引
Android实战经验之如何使用DiffUtil提升RecyclerView的刷新性能
本文介绍如何使用 `DiffUtil` 实现 `RecyclerView` 数据集的高效更新,避免不必要的全局刷新,尤其适用于处理大量数据场景。通过定义 `DiffUtil.Callback`、计算差异并应用到适配器,可以显著提升性能。同时,文章还列举了常见错误及原因,帮助开发者避免陷阱。
202 9
|
3月前
|
存储 缓存 Android开发
Android RecyclerView 缓存机制深度解析与面试题
本文首发于公众号“AntDream”,详细解析了 `RecyclerView` 的缓存机制,包括多级缓存的原理与流程,并提供了常见面试题及答案。通过本文,你将深入了解 `RecyclerView` 的高性能秘诀,提升列表和网格的开发技能。
73 8
|
2月前
|
存储 大数据 数据库
Android经典面试题之Intent传递数据大小为什么限制是1M?
在 Android 中,使用 Intent 传递数据时存在约 1MB 的大小限制,这是由于 Binder 机制的事务缓冲区限制、Intent 的设计初衷以及内存消耗和性能问题所致。推荐使用文件存储、SharedPreferences、数据库存储或 ContentProvider 等方式传递大数据。
76 0
|
2月前
|
ARouter Android开发
Android不同module布局文件重名被覆盖
Android不同module布局文件重名被覆盖
122 0
|
4月前
|
编解码 Android开发
【Android Studio】使用UI工具绘制,ConstraintLayout 限制性布局,快速上手
本文介绍了Android Studio中使用ConstraintLayout布局的方法,通过创建布局文件、设置控件约束等步骤,快速上手UI设计,并提供了一个TV Launcher界面布局的绘制示例。
59 1
|
4月前
|
存储 缓存 Java
Android项目架构设计问题之优化业务接口数据的加载效率如何解决
Android项目架构设计问题之优化业务接口数据的加载效率如何解决
47 0
|
4月前
|
存储 Android开发 开发者
Android项目架构设计问题之定义RecyclerView的ViewHolder如何解决
Android项目架构设计问题之定义RecyclerView的ViewHolder如何解决
45 0
|
8天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。