如何使用StaggeredGridLayoutManager在recyclerview中实现无限滚动(分页)

2024-01-12

你好,我有一个recyclerview图像加载自firebase我想实现无限滚动,但我遇到的问题是StaggeredGridLayoutManager我必须使用它,但我无法替换它grid-layout

注意:-我看过关于这个主题的其他答案,但大多数 答案是为了LinearLayoutManager还有一些是为了GridLayout但那里 我找到的只有一个答案StaggeredGridLayoutManager我不知道 知道为什么它对我不起作用

如果您想要更多代码参考,请告诉我,我会更新 问题

Profile_Fragment.java

 public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_profile, container, false);
    requireActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    ImageView accountSettings = view.findViewById(R.id.account_Settings);
    RelativeLayout relativeLayout = view.findViewById(R.id.snipet_profile);
    profilePhoto = relativeLayout.findViewById(R.id.circleImageView);
    editProfileButton = relativeLayout.findViewById(R.id.edit_profile_button);
    uploadImageButton = view.findViewById(R.id.upload_image_profile);
    progressBar = view.findViewById(R.id.progressBar_Profile);
    editProfileButton.setOnClickListener(v -> {
        Fragment edit_profile = new Edit_Profile();
        assert getFragmentManager() != null;
        FragmentTransaction transaction = getFragmentManager().beginTransaction();
        transaction.add(R.id.fragment_container, edit_profile);
        transaction.addToBackStack(String.valueOf(edit_profile));
        transaction.commit();
    });
    uploadImageButton.setOnClickListener(v -> {
        BottomSheet_Upload bottomSheetSettings = new BottomSheet_Upload();
        bottomSheetSettings.show(requireActivity().getSupportFragmentManager(), bottomSheetSettings.getTag());
    });
    accountSettings.setOnClickListener(
            v -> {
                BottomSheet_Settings bottomSheetSettings = new BottomSheet_Settings();
                bottomSheetSettings.show(requireActivity().getSupportFragmentManager(), bottomSheetSettings.getTag());
            }
    );
    postRecyclerView = view.findViewById(R.id.postRecyclerViewProfile);
    StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
    postRecyclerView.setLayoutManager(
            staggeredGridLayoutManager // I have 3 rows
    );


    postRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {

            visibleItemCount = staggeredGridLayoutManager.getChildCount();
            totalItemCount = staggeredGridLayoutManager.getItemCount();
            int[] firstVisibleItems = null;
            firstVisibleItems = staggeredGridLayoutManager.findFirstVisibleItemPositions(firstVisibleItems);
            if (firstVisibleItems != null && firstVisibleItems.length > 0) {
                pastVisibleItems = firstVisibleItems[0];
            }

            if (loading) {
                if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
                    loading = false;
                    getData();
                    Log.d("tag", "LOAD NEXT ITEM");
                }
            }
        }
    });
    postRecyclerView.setVisibility(View.INVISIBLE);
    progressBar.setVisibility(View.VISIBLE);
    initImageLoader();
    setProfileImage();
    mUploads = new ArrayList<>();
    postsAdapter = new PostAdapter(getContext(), mUploads);
    postRecyclerView.setAdapter(postsAdapter);
    postsAdapter.setOnItemClickListener(Profile_Fragment.this);
    return view;
}

private void initImageLoader() {
    UniversalImageLoader universalImageLoader = new UniversalImageLoader(getContext());
    ImageLoader.getInstance().init(universalImageLoader.getConfig());
}

private void setProfileImage() {
    String imgUrl = "www.64.media.tumblr.com/1276b4edef49034af70bda14325385e3/d8872c747cafa206-96/s500x750/aa915fc49a84b5295f0cd44145d655b66eb906a6.jpg";
    UniversalImageLoader.setImage(imgUrl, profilePhoto, null, "https://");
}

private void getData() {
    mStorage = FirebaseStorage.getInstance();
    databaseEventListener = databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if (snapshot.exists()) {
                progressBar.setVisibility(View.GONE);
                postRecyclerView.setVisibility(View.VISIBLE);
                mUploads.clear();
                for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                    Upload upload = dataSnapshot.getValue(Upload.class);
                    Objects.requireNonNull(upload).setmKey(dataSnapshot.getKey());
                    mUploads.add(upload);


                }

            }

            //notify the adapter
            postsAdapter.notifyDataSetChanged();
            loading = true;
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            loading = true;
        }
    });
}

Update 1

主要问题代码已更改为当前答案,并按要求添加了适配器类

Problem

实现答案后,没有错误,但图像未加载,因此我已使用添加的答案更新了主代码

PostAdapter.java

public class PostAdapter extends RecyclerView.Adapter<PostAdapter.PostViewHolder> {
    public static List<Upload> mUploads;
    public Context mcontext;
    private OnItemClickListener mListener;
    /* ShimmerFrameLayout shimmerFrameLayout; */


    public PostAdapter(Context context, List<Upload> uploads) {
        mUploads = uploads;
        mcontext = context;
    }

    @NonNull
    @Override
    public PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        LayoutInflater.from(mcontext).inflate(R.layout.post_item_container_profile, parent, false);
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.post_item_container_profile, parent, false);
        return new PostViewHolder(view);

    }

    @Override
    public void onBindViewHolder(@NonNull PostViewHolder holder, int position) {
        Upload uploadCurrent = mUploads.get(position);
        Shimmer shimmer = new Shimmer.ColorHighlightBuilder()
                .setBaseColor(Color.parseColor("#F3F3F3"))
                .setBaseAlpha(1)
                .setHighlightColor(Color.parseColor("#E7E7E7"))
                .setHighlightAlpha(1)
                .setDropoff(50)
                .build();
        ShimmerDrawable shimmerDrawable = new ShimmerDrawable();
        shimmerDrawable.setShimmer(shimmer);
        Glide.with(mcontext)
                .load(uploadCurrent.getmImageUrl())
                .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
                .placeholder(shimmerDrawable)
                .centerCrop()
                .fitCenter()
                .into(holder.imageView);

    }

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

    public void setOnItemClickListener(OnItemClickListener listener) {
        mListener = listener;

    }

    public interface OnItemClickListener {
        void onClick(View view);

        void onItemClick(int position);

        void onDeleteClick(int position);
    }

    public class PostViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
            View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener {
        ShapeableImageView imageView;

        PostViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.imagePost);

            itemView.setOnClickListener(this);
            itemView.setOnCreateContextMenuListener(this);
        }

        @Override
        public void onClick(View v) {
            if (mListener != null) {
                int position = getAdapterPosition();
                if (position != RecyclerView.NO_POSITION) {
                    mListener.onItemClick(position);
                }
            }
        }

        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
            MenuItem delete = menu.add(Menu.NONE, 2, 2, "Delete");
            delete.setOnMenuItemClickListener(this);
        }

        @Override
        public boolean onMenuItemClick(MenuItem item) {
            if (mListener != null) {
                int position = getAdapterPosition();
                if (position != RecyclerView.NO_POSITION) {
                    if (item.getItemId() == 2) {
                        mListener.onDeleteClick(position);
                        return true;
                    }
                }
            }
            return false;
        }
    }
}

对于您的第一个问题,您已经有了解决方案。

StaggeredGridLayoutManager staggeredGridLayoutManager = new 
   StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
    postRecyclerView.setLayoutManager(
            staggeredGridLayoutManager // I have 3 rows
    );
    

对于第二个问题:

postRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener({
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

        visibleItemCount = staggeredGridLayoutManager .getChildCount();
        totalItemCount = staggeredGridLayoutManager .getItemCount();
        int[] firstVisibleItems = null;
        firstVisibleItems = mLayoutManager.findFirstVisibleItemPositions(firstVisibleItems);
        if(firstVisibleItems != null && firstVisibleItems.length > 0) {
            pastVisibleItems = firstVisibleItems[0];
        }

        if (loading) {
            if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
                loading = false;
                getData()
            }
        }
    }
 });
 ..........
 ..........
  private void getData() {
    mStorage = FirebaseStorage.getInstance();
    databaseEventListener = databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if (snapshot.exists()) {
                progressBar.setVisibility(View.GONE);
                postRecyclerView.setVisibility(View.VISIBLE);
                mUploads.clear();
                for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                    Upload upload = dataSnapshot.getValue(Upload.class);
                    Objects.requireNonNull(upload).setmKey(dataSnapshot.getKey());
                    mUploads.add(upload);
                }
            }
            //notify the adapter
            postsAdapter.notifyDataSetChanged();
            loading = true;
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
           loading = true;
        }
    });
}

您可能需要致电getData()最初在你的onCreate()以便一些数据加载到屏幕上并且您有滚动行为。

更新: StaggeredGridLayoutManager 中的第二个参数是方向,因此而不是context你必须通过定向StaggeredGridLayoutManager.VERTICAL.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用StaggeredGridLayoutManager在recyclerview中实现无限滚动(分页) 的相关文章

  • 如何像 youtube 一样在纸板中观看普通视频

    我有一个可以正常播放的应用程序VR视频 我的应用程序有两个玩家可以玩这两种类型 在我的VrVideoView有一个按钮可以让视频播放立体声模式 我的问题是 我怎样才能观看正常的视频Cardboard就像YouTube app None
  • 如何使用 bash 脚本通过 tar 备份文件系统?

    我想备份我的 ubuntu 文件系统 我写了这个小脚本 这是非常基本的 但这是我第一次尝试 我害怕犯错误 由于需要几个小时才能完成才能看到结果 因此我认为最好向经验丰富的程序员询问我是否做错了什么 我特别感兴趣 gt 会记录输出mv或者它也
  • Java 中的下载管理器 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要通过 FTP HTTP 从 Java 获取几个大文件 几个演出 有现成的库 java 命令行工具
  • 从其对象获取结构体字段的名称和类型

    例如 我有一个类似这样的结构 struct Test int i float f char ch 10 我有一个该结构的对象 例如 Test obj 现在 我想以编程方式获取字段名称和类型obj 是否可以 顺便说一句 这是 C 你正在要求C
  • Hibernate Envers:如何捕获谁删除了审计表中的实体

    我在用hibernate envers with spring 一切工作正常 除了当我删除一个实体时 它不会改变的值updated by and updated date在审计表内 它会在之后保存一个与之前完全相同的实体 仅复制 sprin
  • 如何打印Oracle中过程的定义?

    oracle中有没有办法查看过程的结构是什么 我正在尝试记录并运行程序 并希望将实际的程序结构存储在我的日志中 您可以查询ALL SOURCE table SELECT text FROM all source WHERE owner lt
  • 真实值与预测值的降维可视化

    我有一个数据框 如下所示 label predicted F1 F2 F3 F40 major minor 2 1 4 major major 1 0 10 minor patch 4 3 23 major patch 2 1 11 min
  • html5 canvas 使用图像作为蒙版

    是否可以使用具有形状的图像作为整个画布或画布内图像的蒙版 我想将图像放置在画布中 并在图像上添加蒙版 然后将其另存为新图像 您可以使用 source in globalCompositeOperation 将黑白图像用作蒙版 首先 将蒙版图
  • 解析用户周围的位置

    您好 我开发了一个应用程序 我想问一个问题 在我的数据云解析中 我有 餐馆 类 我有三列 名称 类型字符串 imageFile 类型文件 description 类型数组和 Location 类型GeoPoint 我想知道使用哪种方法来获取
  • Eclipse:如何增加查找/替换历史记录?

    查找 替换对话框显示最后 8 个条目 该对话框通过 Ctrl F 显示 我想增加 查找 和 替换为 输入字段的历史记录中显示的条目数 我必须搜索并替换几个字符串和正则表达式 因此我一次又一次地输入字符串和正则表达式 我并不是指文件内容更改的
  • 重定向到其他控制器中的操作

    我想从一个控制器中的操作重定向到第二个控制器中的操作 通常我会使用 RedirectToAction actionName controllerName objects 我想要重定向到的方法有两个重载 一个用于 HttpVerbs Get
  • 在 Oracle 中使用触发器记录对表的更改

    我的一门课有一个项目 当我们的两个表发生更改时 我们需要创建一个日志 插入 更新 删除 我们需要使用Oracle触发器和PL SQL 在日志文件中 我们需要记录用户ID 日期时间 IP地址和事件 插入 更新 删除 我知道如何设置触发器 但我
  • 如何将 Hibernate 5 安装到 Apache Karaf v4 中

    我已经安装了 Apache Karaf v4 03 并查询了 Hibernate 的可用功能列表 如下所示 不幸的是 我使用的是 Hibernate v5 hibernate 3 3 2 GA Uninstalled enterprise
  • 是否有与 pdl2(或 Devel::REPL)中的 perl 调试器“x”等效的东西?

    我在用pdl2 the PDL http p3rl org PDLshell 也作为我的默认 Perl 交互式 shell 它加载所有不错的插件Devel REPL http search cpan org perldoc Devel 3a
  • 如何在 Swift 中使用 substringToIndex? [复制]

    这个问题在这里已经有答案了 我在这一行收到编译器错误 UIDevice currentDevice identifierForVendor UUIDString substringToIndex 8 类型 String Index 不符合协
  • 在 MVC4 中使函数异步时 HttpContext.Current null

    我目前正在 VS2010 SP1 中开发 MVC4 我做了其中一个功能 控制器类异步 作为其中的一部分 我制作了控制器类 派生自 AsyncController 并添加了以下两个方法 参见代码部分 1 和 2 下 一种以 Async 结尾的
  • jsf文件下载不起作用

    当我点击h commandButton它执行myBean dowanlod 方法 但它不下载任何文件 这是我在支持 bean 中的方法 没有例外 光标变得忙碌 似乎在等待响应 对于这种操作是否有任何额外的配置或者这段代码有什么问题吗
  • 将文件传递给活动作业/后台作业

    我通过标准文件输入接收请求参数中的文件 def create file params file upload Upload create file file filename img png end 但是 对于大型上传 我想在后台作业中执行
  • SQL 大表中的随机行(使用 where 子句)

    我有一个网站 人们可以在其中对汽车进行投票 向用户展示 4 辆汽车 他 她可以投票选出他们最喜欢的汽车 桌子cars有重要的列 car id int 10 not auto increment so has gaps views int 7
  • IOError:在 Linux 上的 ReportLab 中使用 matplotlib PNG 时“解码器 zip 不可用”,适用于 Windows

    我正在使用 ReportLab 打印 matplotlib 生成的图表 我可以在我的 Windows 开发机器上毫无问题地执行此操作 然而 当我部署到 Ubuntu 服务器时 渲染失败并出现所述错误 我假设我缺少一个 Python 模块 但

随机推荐