0

场景:Activity A打开Activity B,Activity B在viewpager中使用FragmentPagerAdapter有两个fragment a和b,fragment a和b有一些单选按钮和复选框供用户交互;

即使我将活动 B 留给 A,我也需要将按钮和复选框状态存储在片段中

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

2-在每个片段中尝试了 onSaveInstanceState()、onViewStateRestored(),并且从未在 oncreate() 中使用 setRetainInstance(true) 调用 onSavedInstance;然后通过调用 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);
}

}

4

1 回答 1

0

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

其次,很可能没有理由setRetainInstance()在这样的片段上使用。这种方法对于创建无视图片段和存储大型数据集很有用。超越该用例往往会带来很多麻烦。

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

方法一:

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

FragmentPagerAdapter只有在getItem()需要新的Fragment. 所有Fragments已经创建的都将在FragmentManager. 每个 Fragment 都必须处理自己的状态。Activity 或 Adapter 不需要知道它。每个先前创建的 Fragment 都会onSavedInstanceState()被调用,并且从中返回的包将被传入onCreate(bundle)and onCreateView(bundle)

方法二:

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

方法三:

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

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

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

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

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

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

于 2017-02-10T21:30:08.840 回答