How to save and restore recyclerview position in fragment

Viewed 682

Hello I want to save the position of the recycler view when navigating from one fragment to another and then restore the scroll position when returning to the fragment

Note

I didn't try any method till now because I don't know where exactly I have to implement it in my Home_Fragmen.java or in PostAdapter_Home.java

now, how do I implement this in my code?

Home_Fragment.java

 public class Home_Fragment extends Fragment {
    private final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("uploads");
    public List<Upload> mUploads;
    PostAdapter_Home postsAdapter;
    RecyclerView postRecyclerView;
    ShimmerFrameLayout shimmerFrameLayout;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container, false);
        requireActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        postRecyclerView = view.findViewById(R.id.recyclerViewHome);
        shimmerFrameLayout = view.findViewById(R.id.shimmerEffect);
        SnapHelper snapHelper = new PagerSnapHelper();
        snapHelper.attachToRecyclerView(postRecyclerView);
        postRecyclerView.setLayoutManager(
                new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL)
        );

        getData();
        shimmerFrameLayout.startShimmer();
        mUploads = new ArrayList<>();
        postsAdapter = new PostAdapter_Home(getContext(), mUploads);
        postRecyclerView.setAdapter(postsAdapter);
        return view;
    }

    private void getData() {
        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                if (snapshot.exists()) {

                    postRecyclerView.setVisibility(View.VISIBLE);
                    shimmerFrameLayout.stopShimmer();
                    shimmerFrameLayout.setVisibility(View.GONE);
                    mUploads.clear();
                    for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                        Upload upload = dataSnapshot.getValue(Upload.class);
                        assert upload != null;
                        upload.setmKey(dataSnapshot.getKey());
                        mUploads.add(upload);


                    }

                }

                //notify the adapter
                postsAdapter.notifyDataSetChanged();
            }

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

PostAdapter_Home.java

public class PostAdapter_Home extends RecyclerView.Adapter<PostAdapter_Home.PostViewHolder> {
    public static List<Upload> mUploads;
    public Context mcontext;
    //    ShimmerFrameLayout shimmerFrameLayout;


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


    @NonNull
    @Override
    public PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        view = LayoutInflater.from(mcontext).inflate(R.layout.post_item_container_home, 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.DATA)
                .placeholder(shimmerDrawable)
                .into(holder.imageView);


    }

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

    public static class PostViewHolder extends RecyclerView.ViewHolder {
        ShapeableImageView imageView;

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


        public void setOnItemClickListener(PostAdapter.OnItemClickListener listener) {

        }
    }
}
1 Answers

One easy solution is using a static variable.

  1. Add the following as an attribute to your class: public static int saved_position = 0 (the 0 value must be the default value for your recyclerView position).
  2. Whenever the recyclerView value changes, add Home_Fragment.saved_position = ..., in order to save the actual position in the variable. This line of code can be run on any file without problem because the static variable is public.
  3. When you create the fragment, set the recyclerView position to the position saved in Home_Fragment.saved_position, that's why you have to set the default value as it's initial value.
  4. If for some reason the amount of elements in the recyclerView changes, remember to change the value of Home_Fragment.saved_position to the default value.
Related