0

I have a RecyclerView in a Fragment which is in a ViewPager hosted in an Activity. There's two Activities in this project MainActivity which lists items and DetailActivity which shows details about the item chosen in the first activity.

When I move from DetailsActivity to MainActivity I am always take to ViewPager Fragment position 0 which is the first Fragment. How can I restore the fragment position?

Bundle is always empty when I move from DetailActivity to MainActivity.

Here is the full code of the app.

MainActivity

public class MainActivity extends AppCompatActivity {

    private ViewPager mViewPager;
    private static final String LOG = MainActivity.class.getSimpleName();
    private static final String VIEWPAGER_POSITION = "currentItem";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_titles);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        setupViewPager(mViewPager);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(mViewPager);

        if (savedInstanceState != null) {
            int pos = savedInstanceState.getInt(VIEWPAGER_POSITION, 0);
            Log.d(LOG, "onCreate pos: " + pos);
            mViewPager.setCurrentItem(pos);
        } else {
            Log.d(LOG, "onCreate savedInstanceState is null");
        }
    }

    private void setupViewPager(ViewPager viewPager) {
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(new PopularFragment(), getResources().getString(R.string.popularity));
        adapter.addFragment(new RatingFragment(), getResources().getString(R.string.rating));
        adapter.addFragment(new FavoriteFragment().newInstance(), getResources().getString(R.string.favorite));
        viewPager.setAdapter(adapter);
    }

    public static class ViewPagerAdapter extends FragmentStatePagerAdapter {
        private final List<Fragment> mFragmentList = new ArrayList<>();
        private final List<String> mFragmentTitleList = new ArrayList<>();

        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);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onSaveInstanceState(Bundle bundle) {
        super.onSaveInstanceState(bundle);
        int pos = mViewPager.getCurrentItem();
        Log.d(LOG, "onSaveInstanceState pos: " + pos);
        bundle.putInt(VIEWPAGER_POSITION, mViewPager.getCurrentItem());
    }
}

Thanks.

Sudhir Singh Khanger
  • 1,598
  • 2
  • 17
  • 34

2 Answers2

0

I am shooting, when you go back from DetailActivity, look for Bundle in

this.getIntent().getExtras().getInt(VIEWPAGER_POSITION, 0)

UPDATE:

if you need persist your current position in for example SharedPreferences in onPause and retrieve it in onResume. like:

private static String MY_PAGER_TAG  = "tag_of_shared_vp_position";
    public void onPause(){ 
  super.onPause();
  int pos = getCurrentViewPagerPosition();//custom function, implement it by //yourself
  SharedPreferences sharedPref = this.getPreferences(Context.MODE_PRIVATE);
  SharedPreferences.Editor editor = sharedPref.edit();
  editor.putInt(MY_PAGER_TAG, pos);
  editor.commit();
}

public void onResume(){
  super.onResume();
  SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
  int pos = sharedPref.getInt(MY_PAGER_TAG,0);
  setUpViewPagerOnPosition(pos);
}
wojciech_maciejewski
  • 1,277
  • 1
  • 12
  • 28
0

I noticed that if I pressed the physical back button the ViewPager and RecyclerView were properly restored. So I wanted a way to set up button behavior same as onBackPressed(). Answer to which has already been posted in the question Make the “up” button behave like the “back” button on Android.

I made following changes in DetailActivity and my code started working just fine.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    if (id == android.R.id.home) {
        onBackPressed();
        return true;
    }

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
Sudhir Singh Khanger
  • 1,598
  • 2
  • 17
  • 34