转到上一个活动

时间:2017-02-10 20:55:00

标签: android android-fragments android-viewpager onsaveinstancestate

方案: 活动A打开活动B,活动B使用FragmentPagerAdapter在viewpager中有两个片段a和b,片段a和b有一些单选按钮和用户交互的复选框;

即使我将活动B留到A

,我也需要在片段中存储按钮和复选框状态

我的尝试: 1-删除super.onBack()按下以强制系统调用活动中的onSavedInstanceState,但仍然无法将片段保存到它,因为我在适配器中实例化它们并且不知道如何获取创建的相同对象他们参加活动

2-尝试了每个片段中的onSaveInstanceState(),onViewStateRestored(),onSateInstance从未在oncreate()中使用setRetainInstance(true)调用;然后通过调用onPause()

强制调用onSaveInstanceState()

我在堆栈上阅读了大多数可用的解决方案,并且没有工作,我的代码如下;

public class FilterPagerAdapter extends FragmentPagerAdapter {


    public final static int KEYWORDS_TAB = 0;
    public final static int AREAS_TAB = 1;
    private int tabCount;
    private Context context;

public FilterPagerAdapter(FragmentManager fm, int tabCount, Context context) {
    super(fm);
    this.tabCount = tabCount;
    this.context = context;
}


@Override
public Fragment getItem(int position) {
    Fragment fragment;
    switch (position) {
        case KEYWORDS_TAB:
            fragment = KeyWordsFragment.newInstance();
            break;
        case AREAS_TAB:
            fragment = AreasFragment.newInstance();
            break;
        default:
            return null;
    }
    return fragment;
}

@Override
public int getCount() {
    return tabCount;
}

@Override
public CharSequence getPageTitle(int position) {
    String tabTitle = "";
    switch (position) {
        case KEYWORDS_TAB:
            tabTitle = context.getResources().getString(R.string.tab_keywords);
            break;
        case AREAS_TAB:
            tabTitle = context.getResources().getString(R.string.tab_area);
            break;
        default:

    }
    return tabTitle;
}

}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_filters);

    ButterKnife.bind(this);

    mAreas = new Areas();
    mKeywords = new KeyWords();
    viewControllers();
}


private void viewControllers() {

    tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_keywords), CATEGORIES_TAB);
    tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_area), BRANDS_TAB);
    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
    tabLayout.addOnTabSelectedListener(this);

    filterPagerAdapter = new FilterPagerAdapter(getSupportFragmentManager(),
            tabLayout.getTabCount(), this);
    viewPager.setAdapter(filterPagerAdapter);
    tabLayout.setupWithViewPager(viewPager);
}

@Override
public void onBackPressed() {

    startActivity(new Intent(FiltersActivity.this, BranchesActivity.class));
}


@Override
public void onStop() {
    super.onStop();
    tabLayout.removeOnTabSelectedListener(this);
}

}

1 个答案:

答案 0 :(得分:0)

首先,我建议不要强制调用onSavedInstanceState或任何其他生命周期回调。最好是适应生命周期的流程,而不是让生命周期适应你的流程。

其次,很可能没有理由在像这样的Fragments上使用setRetainInstance()。此方法对creating viewless Fragments and store large data-sets很有用。超越该用例往往会带来很多麻烦。

所以,有了这些,应该有几种方法来解决这个问题,它们取决于它所代表的数据类型。

方法1:

与您尝试使用#1类似的一种方法是前进到下一个Activity(在这种情况下为ActivityA),而不是在用户按下时返回。这将暂停并可能停止ActivityB以及使用onSaveInstanceState()方法来存储片段的状态。

FragmentPagerAdapter只会在需要新getItem()时致电Fragment。已创建的所有Fragments都将位于FragmentManager中。每个片段都必须处理自己的状态。活动或适配器无需了解它。每个先前创建的片段都会调用onSavedInstanceState(),从中返回的包将在onCreate(bundle)onCreateView(bundle)中传递。

方法2:

以上适用于数据不是很重要的很多情况。你可以放弃它,并保持状态更方便。如果用户由于某种原因离开ActivityB一段时间,系统可能会从堆栈中转储它。如果发生这种情况,那么它仍然可以被销毁并且状态会恢复。在这种情况下,您必须使用SharedPreferences或其他一些更永久的数据存储来保存和恢复状态。

方法3:

我注意到ActivityB的名称实际上是FiltersActivity。我假设FiltersActivity是一个Activity,其中用户选择要发送回BranchesActivity的过滤器。如果你不想让这些持久化,那么另一种方法就是简单地在两者之间来回传递信息。

  1. BranchesActivity会将当前过滤器传递给FiltersActivity

  2. FiltersActivity然后将其所有设置默认为传入的过滤器。

  3. FiltersActivity允许用户选择新的过滤器集。

  4. 用户在FiltersActivity上按“返回”,返回选定的过滤器。

  5. BranchesActivity现在有了新的过滤器。当用户想要更改过滤器时,BranchesActivity将返回步骤1.