1

I am new to Android and, as a first step, am building an app, for running in a handset, with an activity in which I put two fragments. The first fragment has a recycler view of items that are supposed to represent article titles. When I click on one, the second fragment opens and shows the title (in a text view) and the content (in another text view) of the article (for the moment, for simplicity, I put the article title as fake titles and I have a setting for which the content is not shown but it is shown the title in the content text view too).

I want to save the scroll position of the recycler view.

When I scroll down, having on top of the screen an article title different from the first, I choose an article and my second fragment opens with the expected contents, and that's ok. When I rotate to landscape, the same fragment contains the same content, ok. So:

1) when I press the back button from the landscape, returning to the first fragment, I get the same setting for the recycler view, ok;

2) when I rotate again to portrait, remaining on the second fragment, it is ok too. Now, if I press the back button to return to the first fragment, to the list of articles, the recycler view is NOT set to start with the item I initially scrolled to. What can I do?

I have this code in the first fragment, the one containing the recycler view:

@Override
public void onSaveInstanceState(Bundle state) {
    int lastFirstVisiblePosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
    state.putInt(Articles.RECYCLER_POSITION_KEY, lastFirstVisiblePosition);

    super.onSaveInstanceState(state);
}

@Override
public void onActivityCreated(Bundle state) {
    super.onActivityCreated(state);

    if (state != null) {
        int lastFirstVisiblePosition = state.getInt(Articles.RECYCLER_POSITION_KEY);
        ((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPosition(lastFirstVisiblePosition);
    }
}

What am I missing? Thanks.

[EDIT] In my listener is this, for invoking the second fragment:

ArticleReaderFrag newFragment = new ArticleReaderFrag();
Bundle args = new Bundle();
args.putString(NEW_FRAG_TITLE_KEY, item);
args.putString(NEW_FRAG_BODY_KEY, itemb);
newFragment.setArguments(args);

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

transaction.replace(R.id.main_activity, newFragment);
transaction.addToBackStack(null);

transaction.commit();
tom
  • 159
  • 2
  • 10

1 Answers1

0

Reuse Fragment

When the Activity launches for the first time create a new instance of Fragment and use a TAG to save it with FragmentManager. When the activity gets recreated after orientation change. Retreive the old instance using the Tag.

Here is a sample code which you should have in your activity.

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.first_activity);
    fragmentManager = getSupportFragmentManager();

    if(savedInstanceState==null) {

        userFragment = UserNameFragment.newInstance();
        fragmentManager.beginTransaction().add(R.id.profile, userFragment, "TAG").commit();
    }
    else {
        userFragment = fragmentManager.findFragmentByTag("TAG");
    }

}

How to save scroll position?

That happens by default. Read this answer for more detail.

EDIT

I believe this is your method

public createSecondFragment(int position){

     ArticleReaderFrag newFragment = new ArticleReaderFrag();
     Bundle args = new Bundle();
     args.putString(NEW_FRAG_TITLE_KEY, item);
     args.putString(NEW_FRAG_BODY_KEY, itemb);
     newFragment.setArguments(args);

     FragmentTransaction transaction = 
     getSupportFragmentManager().beginTransaction();

     transaction.replace(R.id.main_activity, newFragment);
     transaction.addToBackStack(null);

     transaction.commit();

}

Save the position of on rotation and use that position to load the specific fragment.
Call the method when the activity is recreated after orientation change

@Override
protected void onCreate(Bundle savedInstanceState)
{
   super.onCreate(savedInstanceState);
   setContentView(R.layout.first_activity);

   if(savedInstanceState!=null) {

      int lastSavedPosition = // Your logic 
      createSecondFragment(lastSavedPosition )

   }


}
Rohit Singh
  • 16,950
  • 7
  • 90
  • 88
  • Since I need a listener to choose the items, I put inside the method of the listener all the required for opening the new fragment (in paricular, the transaction). So, before trying your solution in my code I ask you, is it possible that this my code conflicts with yours, about the part of the transaction? – tom Apr 04 '19 at 10:52
  • Are you using userFragment = fragmentManager.findFragmentByTag("TAG"); anywhere? This is how you get old instance of a fragment. For better understanding you can post your listener code as well – Rohit Singh Apr 04 '19 at 11:05