Request to moderators: This is not a duplicate question, please read the below information.
Before asking this question, i'd tried almost every available solution on SO, but none of them worked for me, some resulted in crash and some didn't work at all (I'm a beginner, it is possible that i've done something wrong in my code, i'm not blaming anyone's answer available on SO for not working in my case). Below are my codes, please have a look:
fragment_tab1.xml (which contains recyclerview):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:background="#333333"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="96dp">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="42dp"
            android:background="@color/colorPrimaryDark"
            android:id="@+id/sort1"
            android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/sort"
            android:layout_marginLeft="10dp"
            android:fontFamily="@font/quicksand"
            android:textStyle="bold"
            android:text="Sort by:"
            android:textColor="#ffffff"/>
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                style="@style/Widget.AppCompat.Button.Colored"
                android:text="Oldest first"/>
            <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
                style="@style/Widget.AppCompat.Button.Colored"
            android:text="Newest first"/>
        </LinearLayout>
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_below="@id/sort1"
        android:clipToPadding="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:padding="5dp" />
    </RelativeLayout>
</LinearLayout>
Fragmenttab1.java
public class tab1  extends Fragment {
    RecyclerView mRecyclerView;
    FirebaseDatabase mFirebaseDatabase;
    DatabaseReference mRef;
    LinearLayoutManager manager;
    private static final String TAG = "tab1";
    ProgressDialog progressDialog;
    View rootView;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //Returning the layout file after inflating
        //Change R.layout.tab1 in you classes
         rootView = inflater.inflate(R.layout.fragment_tab1, container, false);
return rootView;
    }
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
        manager = new LinearLayoutManager(getActivity());
        mRecyclerView.setLayoutManager(manager);
        mRecyclerView.setItemViewCacheSize(20);
        mRecyclerView.setDrawingCacheEnabled(true);
        mFirebaseDatabase = FirebaseDatabase.getInstance();
        mRef = mFirebaseDatabase.getReference("memes");
        mFirebaseDatabase.getInstance().getReference().keepSynced(true);
        progressDialog = new ProgressDialog(getActivity());
        progressDialog.setMessage("Please Wait");
        progressDialog.show();
    }
    public void onStart() {
        super.onStart();
        FirebaseRecyclerAdapter<Model, ViewHolder> firebaseRecyclerAdapter =
                new FirebaseRecyclerAdapter<Model, ViewHolder>(
                        Model.class,
                        R.layout.row2,
                        ViewHolder.class,
                        mRef
                ) {
                    @Override
                    protected void populateViewHolder(ViewHolder viewHolder, Model model, int position) {
                        viewHolder.setDetails(getActivity(), model.getTitle(), model.getDesc(), model.getImage());
                        progressDialog.cancel();
                    }
                    @Override
                    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                        ViewHolder viewHolder = super.onCreateViewHolder(parent, viewType);
                        viewHolder.setOnClickListener(new ViewHolder.ClickListener(){
                            @Override
                            public void onItemClick(View view, int position){
                                //get data from firebase here
                                String mTitle = getItem(position).getTitle();
                                String mDesc= getItem(position).getDesc();
                                String mImage = getItem(position).getImage();
                                //pass this data to new activity
                                Intent intent = new Intent(view.getContext(), ArticleDetail.class);
                                intent.putExtra("title", mTitle);// put title
                                intent.putExtra("desc", mDesc);// put description
                                intent.putExtra("image", mImage); //put image urls
                                startActivity(intent);
                            }
                            @Override
                            public void onItemLongClick(View view, int position){
                                //TODO your own implementation on long item click
                            }
                        });
                        return viewHolder;
                    }
                };
        mRecyclerView.setAdapter(firebaseRecyclerAdapter);
    }
    @Override
    public void  onPause() {
        super.onPause();
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
        View firstChild = mRecyclerView.getChildAt(0);
        int firstVisiblePosition = mRecyclerView.getChildAdapterPosition(firstChild);
        int offset = firstChild.getTop();
        Log.d(TAG, "Postition: " + firstVisiblePosition);
        Log.d(TAG, "Offset: " + offset);
        preferences.edit()
                .putInt("position", firstVisiblePosition)
                .putInt("offset", offset)
                .apply();
    }
    @Override
    public void onResume(){
        super.onResume();
    }
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }
    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
    }
}
If you are trying to clear all items from the RecyclerView, you need to delete all items from its adapter and then notify it via an appropriate method. If you are trying to only remove whatever filter applied on it, in order to show all items, then it will depend on how results are being filtered.
Just set your LayoutManager and adapter for the first time. Make a setDataList method in your adapter class. And set your updated list to adapter list. And then every time of calling API set that list to setDataList and call adapter.
You can use scrollToPosition() with the index of the last position. Based on the doc, " RecyclerView does not implement scrolling logic, rather forwards the call to scrollToPosition(int)". It does not implement the logic, simply call this function will does nothing.
After paying so many days, after trying many many solutions, finally found a working solution for my problem, thanks to https://stackoverflow.com/a/42563804/2128364
I've moved the working solution to another methods to make it work in the fragment.
Maybe this can save someone's day, Here is how it worked:
mBundleRecyclerViewState = new Bundle();    
mListState = mRecyclerView.getLayoutManager().onSaveInstanceState();
mBundleRecyclerViewState.putParcelable(KEY_RECYCLER_STATE, mListState);
if (mBundleRecyclerViewState != null) {
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            mListState = mBundleRecyclerViewState.getParcelable(KEY_RECYCLER_STATE);
            mRecyclerView.getLayoutManager().onRestoreInstanceState(mListState);
        }
    }, 50);
}    
mRecyclerView.setLayoutManager(staggeredGridLayoutManager);
If you don't have already, add the recyclerView dependency in your build.gradle
implementation "androidx.recyclerview:recyclerview:1.2.0"
Than just set the stateRestorationPolicy just after you initialize your list adapter.
 listAdapter = ListAdapter()
 // Set scroll restore policy
 listdapter.stateRestorationPolicy =
      RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY
For more information on stateRestorationPolicy and different types of policies visit this article
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With