如何使用StaggeredGridLayoutManager在recyclerview中实现无限滚动(分页)
How to implement endless scroll (pagination) in recyclerview with StaggeredGridLayoutManager
你好,我有一个 recyclerview
,图像是从 firebase
加载的我想实现无限滚动,但我遇到的问题是 StaggeredGridLayoutManager
,我必须使用它我无法将其替换为 grid-layout
Note:- I have seen other answers on this topic but the majority of
answers are for LinearLayoutManager
and some for GridLayout
but there
is only one answer I found for StaggeredGridLayoutManager
which I don't
know why it's not working for me
If you want more references of the code please tell me I will update
the question
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;
}
});
}
更新 1
主要问题代码已更改为当前答案并根据要求添加了适配器class
问题
实施答案后没有错误,但图像没有加载,所以我用添加的答案更新了主要代码
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;
}
});
}
您可能必须首先在 onCreate()
中调用 getData()
,以便某些数据加载到屏幕上并且您有滚动行为。
更新:
StaggeredGridLayoutManager 中的第二个参数是方向,因此您必须传递方向 StaggeredGridLayoutManager.VERTICAL
.
而不是 context
你好,我有一个 recyclerview
,图像是从 firebase
加载的我想实现无限滚动,但我遇到的问题是 StaggeredGridLayoutManager
,我必须使用它我无法将其替换为 grid-layout
Note:- I have seen other answers on this topic but the majority of answers are for
LinearLayoutManager
and some forGridLayout
but there is only one answer I found forStaggeredGridLayoutManager
which I don't know why it's not working for me
If you want more references of the code please tell me I will update the question
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;
}
});
}
更新 1
主要问题代码已更改为当前答案并根据要求添加了适配器class
问题
实施答案后没有错误,但图像没有加载,所以我用添加的答案更新了主要代码
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;
}
});
}
您可能必须首先在 onCreate()
中调用 getData()
,以便某些数据加载到屏幕上并且您有滚动行为。
更新:
StaggeredGridLayoutManager 中的第二个参数是方向,因此您必须传递方向 StaggeredGridLayoutManager.VERTICAL
.
context