Activity 使用 TabLayout 在新 Activity 开始后保存状态

Activity With TabLayout Save State After New Activity Start

我有一个 Activity,其中包含一个 TabLayout 链接到一个 ViewPagerViewPager 包含三个片段,每个片段都有一个包含文章列表的 RecyclerView。当您单击列表项时,它会启动一个包含完整文章文本的新 Activity。在我启动新的 Activity 后,然后按后退按钮 return 到第一个 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 在新的启动时不需要被销毁,为什么它只是在前台时需要被销毁?

我有另一个 activity(我的 SettingsActivity),它没有父 Activity,并且在按下后退按钮时调用 finish()。如果我从我的 ArticleActivity 开始这个 ActivityArticleActivity 永远不会被破坏,并完美地保存它的状态。

我在这里找到了答案:ActionBar 'up' button destroys parent activity, 'back' does not

这里:How can I return to a parent activity correctly?

父项 (ArticleActivity) 在子项 Activity 中按下 后退 按钮后被销毁,因为这是 "standard" 启动模式。我在清单中为 ArticleActivity 设置了 android:launchMode="singleTop",这为我提供了所需的启动行为。现在,当 Back 在子 Activity 中按下时,不会重新创建父项。