Активность с сохранением состояния TabLayout после начала новой активности

У меня есть Activity, который содержит TabLayout, связанный с ViewPager. ViewPager содержит три фрагмента, и каждый фрагмент имеет RecyclerView, содержащий список статей. Когда вы нажимаете на элемент списка, он начинает новый Activity с полным текстом статьи. После того, как я запускаю новую Activity, затем нажимаю кнопку «Назад», чтобы вернуться к первой Activity, она начинается с первой выбранной вкладки.

Я хотел бы иметь возможность запускать новый Activity с любой вкладки, а затем при нажатии кнопки «Назад» он возвращается к предыдущему действию с той же выбранной вкладкой. И желательно поддерживать состояние в пределах RecyclerView (т.е. насколько далеко оно прокручивается вниз). Как я могу этого добиться?

Я попытался использовать onSaveInstanceState, чтобы сохранить файл viewPager.getCurrentItem(). Это сработало, когда устройство было повернуто, но сохраненное состояние экземпляра, похоже, не вызывается после запуска нового Activity.


Вкладка 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);
        }
    }
}

И один из фрагментов, содержащихся в 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);
    }
}

Мне было любопытно, поэтому я просто проверил это. Activity на самом деле не уничтожается, когда я запускаю новый Activity. Он уничтожается (а затем воссоздается) только после того, как я нажимаю кнопку «Назад». Я не понимаю, зачем это делать, если Activity не нужно уничтожать при запуске нового, зачем его уничтожать, когда он просто выходит на передний план?

У меня есть другая активность (моя SettingsActivity), у которой нет родителя Activity, и она просто вызывает finish() при нажатии кнопки "Назад". Если я начну этот Activity с моего ArticleActivity, ArticleActivity никогда не будет уничтожен и отлично сохранит свое состояние.


comment
but the saved instance state does not seem to be called after a new Activity is started вместо этого используйте предпочтение сохранения.   -  person Rod_Algonquin    schedule 30.03.2016
comment
@Sourabh Обновлено с кодом.   -  person Bryan    schedule 30.03.2016
comment
@Rod_Algonquin Правда? Я имею в виду, я думаю, что мог бы, но это кажется излишеством... должно быть что-то проще, не так ли?   -  person Bryan    schedule 30.03.2016
comment
@Bryan Нет, это не излишество, и вы начинаете новое действие, поэтому все сохраненные экземпляры будут уничтожены.   -  person Rod_Algonquin    schedule 30.03.2016


Ответы (1)


Я нашел свой ответ здесь: кнопка "вверх" ActionBar уничтожает родительскую активность, "назад" - нет

А здесь: Как правильно вернуться к родительскому действию?

Родительский (ArticleActivity) уничтожался после нажатия кнопки Назад в дочернем Activity, потому что это поведение "стандартного" режима запуска. Я установил android:launchMode="singleTop" вместо ArticleActivity в манифесте, что дает мне желаемое поведение при запуске. Теперь при нажатии Назад в дочернем элементе Activity родитель не создается заново.

person Bryan    schedule 30.03.2016