title: Scroll state of recyclerview inside ViewPager Tab Fragment not saved when device orientation is handled manually using onConfigurationChanged()
body: <p>What I want to achieve:</p>
  
  <p><a href="https://i.stack.imgur.com/VzA04.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/VzA04.png" alt="This is what I want to achieve"></a></p>
  
  <p>FragmentOne is under Tab1 and FragmentTwoPortrait is under Tab2. I want to save the state of the recyclerview of FragmentTwoPortrait, then restore the fragment state along with the last scroll position of the recyclerview. Similar operation is intended when I rotate the device from landscape to portrait orientation.</p>
  
  <p>In my posted code here, Fragment transaction through the instance FragmentTwoLandscape is done inside a FrameLayout at the beginning to create the initial state of FragmentTwo for landscape orientation. Later on, the view of last saved state of FragmentTwoPortrait is tried to be inflated. The FrameLayout is hidden in portrait orientation, and will be visible only when the device is in Landscape orientation.</p>
  
  <p>Due to certain reasons, I have to handle the device orientation change manually through overriding onConfigurationChanged() from inside the parent activity. Parent activity's life-cycle states need to be handled accordingly if needed.</p>
  
  <p>I have tried out so many solutions over the last few days. I have applied solutions provided on stackoverflow and also tried some of my own. But nothing seems to work! I think I have made a silly mistake somewhere for the code not to return the desired behavior.</p>
  
  <p><strong>P.S:</strong> Please keep in mind while proposing a solution:
  1. The tab fragments are inside a viewpager
  2. FragmentTwo is not allowed to call onSaveInstanceState() [there are obvious reasons behind that]
  3. I cannot preserve the header value of the StickyHeaderRecyclerView library (<a href="https://github.com/TellH/RecyclerStickyHeaderView" rel="nofollow noreferrer">https://github.com/TellH/RecyclerStickyHeaderView</a>) using basic recycler view methods.</p>
  
  <p>activity_main.xml:</p>
  
  <pre><code>&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/activity_main"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.example.sakib.viewpagerfragmentrestoration.Activity.MainActivity"&gt;
  
  &lt;FrameLayout
      android:background="@android:color/white"
      android:id="@+id/fragment_container"
      android:layout_width="480dp"
      android:layout_height="match_parent"
      android:layout_alignParentRight="true"
      android:layout_alignParentEnd="true"
      android:visibility="gone"/&gt;
  
  &lt;LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_toStartOf="@+id/fragment_container"
      android:layout_toLeftOf="@+id/fragment_container"
      android:orientation="vertical"&gt;
  
      &lt;ImageView
          android:id="@+id/image_view"
          android:layout_width="match_parent"
          android:layout_height="200dp" /&gt;
  
      &lt;LinearLayout
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical"&gt;
  
          &lt;android.support.design.widget.TabLayout
              android:id="@+id/tabs"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:background="?attr/colorPrimary"
              android:minHeight="?attr/actionBarSize"
              app:tabGravity="fill"
              app:tabMode="fixed"
              app:tabSelectedTextColor="@color/colorAccent"
              app:tabTextColor="#FFF" /&gt;
  
  
          &lt;com.example.sakib.viewpagerfragmentrestoration.ViewPager.NoScrollViewPager
              android:id="@+id/pager"
              android:layout_width="match_parent"
              android:layout_height="match_parent" /&gt;
  
      &lt;/LinearLayout&gt;
  
  
  &lt;/LinearLayout&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>MainActivity.java:</p>
  
  <pre><code>public class MainActivity extends AppCompatActivity {
  
  NoScrollViewPager viewPager;
  FragmentOne fragmentOne;
  FragmentTwo fragmentTwoPortrait, fragmentTwoLandscape;
  ViewPagerAdapter adapter;
  TabLayout tabLayout;
  FrameLayout fragmentTwoLandscapeContainer;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
  
      viewPager = (NoScrollViewPager) findViewById(R.id.pager);
      tabLayout = (TabLayout) findViewById(R.id.tabs);
      fragmentTwoLandscapeContainer = (FrameLayout) findViewById(R.id.fragment_container);
  
      setViewPagerAdapter();
      loadFragmentForLandscape();
  }
  
  @Override
  public void onConfigurationChanged(Configuration newConfig) {
      super.onConfigurationChanged(newConfig);
  
      // Checks the orientation of the screen
      if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
          fragmentTwoLandscape.adjustScrollPosition(fragmentTwoPortrait.getRecyclerView());
          Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
      } else {
          Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
          fragmentTwoPortrait.adjustScrollPosition(fragmentTwoLandscape.getRecyclerView());
      }
  
      adapter.notifyDataSetChanged();
      setVisibility(newConfig);
  }
  
  private void setVisibility(Configuration newConfig){
      if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
          fragmentTwoLandscapeContainer.setVisibility(View.VISIBLE);
      } else {
          Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
          fragmentTwoLandscapeContainer.setVisibility(View.GONE);
      }
  }
  
  
  private void setViewPagerAdapter() {
  
      fragmentOne = new FragmentOne();
      fragmentTwoPortrait = new FragmentTwo();
  
      //Add Fragments to adapter one by one
      adapter = new ViewPagerAdapter(getSupportFragmentManager());
      adapter.addFragment(fragmentOne, "FRAG1");
      adapter.addFragment(fragmentTwoPortrait, "FRAG2");
      viewPager.setAdapter(adapter);
      tabLayout.setupWithViewPager(viewPager);
  
      if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
          viewPager.setCurrentItem(1);
      }
  }
  
  
  private void loadFragmentForLandscape() {
      fragmentTwoLandscape = new FragmentTwo();
  
      FragmentManager fm = getSupportFragmentManager();
      FragmentTransaction ft = fm.beginTransaction();
      ft.replace(R.id.fragment_container, fragmentTwoLandscape);
      ft.commit();
  }
  
  
  // Adapter for the viewpager using FragmentPagerAdapter
  class ViewPagerAdapter extends FragmentPagerAdapter {
      private final List&lt;Fragment&gt; mFragmentList = new ArrayList&lt;&gt;();
      private final List&lt;String&gt; mFragmentTitleList = new ArrayList&lt;&gt;();
  
  
      public ViewPagerAdapter(FragmentManager manager) {
          super(manager);
      }
  
      @Override
      public Fragment getItem(int position) {
          return mFragmentList.get(position);
      }
  
      @Override
      public int getCount() {
          return mFragmentList.size();
      }
  
      public void addFragment(Fragment fragment, String title) {
          mFragmentList.add(fragment);
          mFragmentTitleList.add(title);
      }
  
      @Override
      public CharSequence getPageTitle(int position) {
          return mFragmentTitleList.get(position);
      }
    }
  }
  </code></pre>
  
  <p>FragmentTwo.java:</p>
  
  <pre><code>public class FragmentTwo extends Fragment {
  private RecyclerView rv;
  private StickyHeaderViewAdapter adapter;
  private Random random = new Random(System.currentTimeMillis());
  
  public FragmentTwo() {
      // Required empty public constructor
  }
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setHasOptionsMenu(true);
  }
  
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                           Bundle savedInstanceState) {
      // Inflate the layout for this fragment
      return inflater.inflate(R.layout.fragment_two, container, false);
  }
  
  @Override
  public void onViewCreated(View view, Bundle savedInstanceState) {
      super.onViewCreated(view, savedInstanceState);
      // add your code here which executes after the execution of onCreateView() method.
  
      initView(view);
      initData();
  }
  
  private void initView(View view) {
      rv = (RecyclerView) view.findViewById(R.id.recyclerView);
      LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
      rv.setLayoutManager(linearLayoutManager);
  }
  
  
  private void initData() {
      Gson gson = new Gson();
      Result result = gson.fromJson(User.dataSource, Result.class);
      List&lt;User&gt; userList = result.getItems();
      Collections.sort(userList, new Comparator&lt;User&gt;() {
          @Override
          public int compare(User o1, User o2) {
              return o1.getLogin().compareToIgnoreCase(o2.getLogin());
          }
      });
      List&lt;DataBean&gt; userListBak = new ArrayList&lt;&gt;();
      String currentPrefix = userList.get(0).getLogin().substring(0, 1).toUpperCase();
      userListBak.add(new ItemHeader(currentPrefix));
      for (User user : userList) {
          if (currentPrefix.compareToIgnoreCase(user.getLogin().substring(0, 1)) == 0)
              userListBak.add(user);
          else {
              currentPrefix = user.getLogin().substring(0, 1).toUpperCase();
              userListBak.add(new ItemHeader(currentPrefix));
              userListBak.add(user);
          }
      }
      adapter = new StickyHeaderViewAdapter(userListBak)
              .RegisterItemType(new UserItemViewBinder())
              .RegisterItemType(new ItemHeaderViewBinder());
      rv.setAdapter(adapter);
  }
  
  @Override
  public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
      inflater.inflate(R.menu.menu_main, menu);
      super.onCreateOptionsMenu(menu,inflater);
  }
  
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
      switch (item.getItemId()) {
          case R.id.action_add_view:
              User user = new User("Sticky View", 123, "https://avatars.githubusercontent.com/u/15800681?v=3");
              user.setShouldSticky(random.nextBoolean());
              adapter.append(user);
              break;
          case R.id.action_clear_all:
              adapter.clear(rv);
              break;
          default:
              break;
      }
      return super.onOptionsItemSelected(item);
  }
  
  
  public void adjustScrollPosition(RecyclerView recyclerView) {
      if(recyclerView == null) {
          return;
      }
      LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
      int position = layoutManager.findFirstVisibleItemPosition();
      int positionOffset = (recyclerView.getChildAt(0) == null) ? 0 : (recyclerView.getChildAt(0).getTop() - recyclerView.getChildAt(0).getPaddingTop());
  
      LinearLayoutManager targetLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
      targetLayoutManager.scrollToPositionWithOffset(position, positionOffset);
  }
  
  public RecyclerView getRecyclerView() {
      if(rv == null) {
          return null;
      }
      return rv;
  }
  }
  </code></pre>