Hello there I have a recyclerview
with images loaded from firebase
I want to implement endless scroll but the issue I'm getting is with StaggeredGridLayoutManager
and I have to use it I cant replace it with 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;
}
});
}
Update 1
The main question code is changed with the current answer and Added the adapter class as requested
Problem
After implementing the answer there are no errors but the images are not loading in so I have updated the main code with the added answer
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;
}
}
}
For your first problem you already have a solution.
StaggeredGridLayoutManager staggeredGridLayoutManager = new
StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
postRecyclerView.setLayoutManager(
staggeredGridLayoutManager // I have 3 rows
);
For second problem:
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;
}
});
}
You might have to call the getData()
initially in your onCreate()
so that some data loads up on the screen and you have a scroll behavior.
Update:
The second parameter in a StaggeredGridLayoutManager is orientation so instead of context
you have to pass orientation StaggeredGridLayoutManager.VERTICAL
.