Активность с помощью 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 никогда не уничтожается и прекрасно сохраняет свое состояние.

1 ответ

Решение

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

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

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

Другие вопросы по тегам