I have an Activity
that contains a TabLayout
linked to a ViewPager
. The ViewPager
contains three fragments, and each fragment has a RecyclerView
containing a list of articles. When you click on an a list item, it starts a new Activity
with the full article text. After I start the new Activity
, then press the back button to return to the first Activity
, it starts with the first tab selected.
I would like to be able to start a new Activity
from any tab, then when the back button is pressed, it goes back to the previous activity with the same tab selected. And preferably, maintain the state within the RecyclerView
(i.e. how far it is scrolled down). How can I achieve this?
I have tried using onSaveInstanceState
to save the viewPager.getCurrentItem()
. It worked for when the device was rotated, but the saved instance state does not seem to be called after a new Activity
is started.
The tabbed Activity
:
public class ArticleActivity extends BaseActivity {
@Bind(R.id.toolbar) Toolbar mToolbar;
@Bind(R.id.content) ViewPager mViewPager;
@Bind(R.id.tabs) TabLayout mTabLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_article);
ButterKnife.bind(this);
setupActionBar();
FragmentPagerAdapter adapter = new BaseFragmentPagerAdapter(this, getSupportFragmentManager(),
NewsFragment.newInstance();
EventsFragment.newInstance();
BulletinFragment.newInstance();
);
mViewPager.setAdapter(adapter);
mTabLayout.setupWithViewPager(mViewPager);
}
private void setupActionBar() {
setSupportActionBar(mToolbar);
ActionBar actionBar = getSupportActionBar();
if(actionBar != null) {
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
}
And one of the fragments contained in the ViewPager
:
public class NewsFragment extends BaseFragment implements
Observer<DataResponse<NewsArticle>> {
@BindDimen(R.dimen.divider_padding_start) float mDividerPadding;
@Bind(R.id.recycler) RecyclerView mRecyclerView;
@Bind(R.id.progress) RecyclerView mProgressBar;
@Bind(R.id.refresh_layout) SwipeRefreshLayout mRefreshLayout;
@Inject RestService mRestService;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_recycler_refresh, container, false);
ButterKnife.bind(this, view);
mRefreshLayout.setColorSchemeColors(
ThemeUtil.getColorAttribute(getContext(), R.attr.colorAccent));
mRefreshLayout.setProgressBackgroundColorSchemeColor(
ThemeUtil.getColorAttribute(getContext(), R.attr.colorPrimary));
mRefreshLayout.setOnRefreshListener(this::getArticles);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.addItemDecoration(new DividerDecoration(getContext(), mDividerPadding));
getArticles();
return view;
}
@Override
public CharSequence getTitle(Context context) {
return context.getString(R.string.title_fragment_news);
}
@Override
publiv void onCompleted() {
mRefreshLayout.setRefreshing(false);
}
@Override
public void onError(Throwable exception) {
Timber.d(exception, "Failed to retrieve articles");
}
@Override
public void onNext(DataResponse<NewsArticle> response) {
mProgressBar.setVisibility(View.GONE);
ArticleAdapter adapter = new ArticleAdapter(getContext(), response.data());
adapter.setOnItemClickListener(this::onItemClick);
mRecyclerView.swapAdapter(adapter, false);
}
private void getArticles() {
mRestService.getNews().subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()).subscribe(this);
}
public void onItemClick(Article article) {
Intent intent = new Intent(getActivity(), ArticleDetailActivity.class);
intent.putExtra("article", article);
startActivity(intent);
}
}
I was curious, so I just tested it. The Activity
doesn't actually get destroyed when I start the new Activity
. It only gets destroyed (then recreated) after I press the back button. I don't understand why it would do that, if the Activity
does not need to be destroyed when a new one starts, why would it need to be destroyed when it simply comes to the foreground?
I have another activity (my SettingsActivity
) that does not have a parent Activity
, and just calls finish()
when the back button is pressed. If I start this Activity
from my ArticleActivity
, the ArticleActivity
never gets destroyed, and saves its state perfectly.