首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ViewPager和片段 - 存储片段状态的正确方法是什么?

ViewPager和片段 - 存储片段状态的正确方法是什么?

提问于 2017-12-19 14:45:41
回答 2关注 0查看 414

片段似乎是非常好的UI界面逻辑分成一些模块。但是随着ViewPager它的生命周期对我来说还是朦胧的。所以大师的想法是非常需要的!

编辑

看到下面的愚蠢的解决方案;-)

范围

主要活动有一个ViewPager片段。这些片段可以为其他(子域)活动实现一些不同的逻辑,所以片段的数据通过活动内的回调接口填充。而一切正常的第一次发射,但!!

问题

当活动被重新创建(例如在方向改变时),所以做ViewPager的碎片。代码(你会发现下面)说,每当创建活动,我尝试创建一个新的ViewPager片段适配器相同的片段(也许这是问题),但FragmentManager已经有所有这些片段存储的地方(?)和启动这些娱乐机制。因此,娱乐机制调用onAttach,onCreateView等“旧”片段与我的回调接口调用启动数据通过活动的实施方法。但是这个方法指向通过Activity的onCreate方法创建的新创建的片段。

问题

也许我正在使用错误的模式,但即使Android 3 Pro书也没有太多的关于它。所以,请给我一个两拳,指出如何正确的做法。非常感谢!

主要活动

代码语言:txt
复制
代码语言:txt
复制
public class DashboardActivity extends BasePagerActivity implements OnMessageListActionListener {
代码语言:txt
复制
代码语言:txt
复制
private MessagesFragment mMessagesFragment;
代码语言:txt
复制
代码语言:txt
复制
@Override
代码语言:txt
复制
protected void onCreate(Bundle savedInstanceState) {
代码语言:txt
复制
    Logger.d("Dash onCreate");
代码语言:txt
复制
    super.onCreate(savedInstanceState);
代码语言:txt
复制
代码语言:txt
复制
    setContentView(R.layout.viewpager_container);
代码语言:txt
复制
    new DefaultToolbar(this);
代码语言:txt
复制
代码语言:txt
复制
    // create fragments to use
代码语言:txt
复制
    mMessagesFragment = new MessagesFragment();
代码语言:txt
复制
    mStreamsFragment = new StreamsFragment();
代码语言:txt
复制
代码语言:txt
复制
    // set titles and fragments for view page
代码语言:txt
复制
    Map<String, Fragment> screens = new LinkedHashMap<String, Fragment>();
代码语言:txt
复制
    screens.put(getApplicationContext().getString(R.string.dashboard_title_dumb), new DumbFragment());
代码语言:txt
复制
    screens.put(getApplicationContext().getString(R.string.dashboard_title_messages), mMessagesFragment);
代码语言:txt
复制
代码语言:txt
复制
    // instantiate view pager via adapte
代码语言:txt
复制
    mPager = (ViewPager) findViewById(R.id.viewpager_pager);
代码语言:txt
复制
    mPagerAdapter = new BasePagerAdapter(screens, getSupportFragmentManager());
代码语言:txt
复制
    mPager.setAdapter(mPagerAdapter);
代码语言:txt
复制
代码语言:txt
复制
    // set title indicato
代码语言:txt
复制
    TitlePageIndicator indicator = (TitlePageIndicator) findViewById(R.id.viewpager_titles);
代码语言:txt
复制
    indicator.setViewPager(mPager, 1);
代码语言:txt
复制
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
/* set of fragments callback interface implementations */
代码语言:txt
复制
代码语言:txt
复制
@Override
代码语言:txt
复制
public void onMessageInitialisation() {
代码语言:txt
复制
代码语言:txt
复制
    Logger.d("Dash onMessageInitialisation");
代码语言:txt
复制
    if (mMessagesFragment != null)
代码语言:txt
复制
        mMessagesFragment.loadLastMessages();
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
@Override
代码语言:txt
复制
public void onMessageSelected(Message selectedMessage) {
代码语言:txt
复制
代码语言:txt
复制
    Intent intent = new Intent(this, StreamActivity.class);
代码语言:txt
复制
    intent.putExtra(Message.class.getName(), selectedMessage);
代码语言:txt
复制
    startActivity(intent);
代码语言:txt
复制
}

BasePagerActivity又名助手

代码语言:txt
复制
代码语言:txt
复制
public class BasePagerActivity extends FragmentActivity {
代码语言:txt
复制
代码语言:txt
复制
BasePagerAdapter mPagerAdapter;
代码语言:txt
复制
ViewPager mPager;
代码语言:txt
复制
}

适配器

代码语言:txt
复制
public class BasePagerAdapter extends FragmentPagerAdapter implements TitleProvider {
代码语言:txt
复制
代码语言:txt
复制
private Map<String, Fragment> mScreens;
代码语言:txt
复制
代码语言:txt
复制
public BasePagerAdapter(Map<String, Fragment> screenMap, FragmentManager fm) {
代码语言:txt
复制
代码语言:txt
复制
    super(fm);
代码语言:txt
复制
    this.mScreens = screenMap;
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
@Override
代码语言:txt
复制
public Fragment getItem(int position) {
代码语言:txt
复制
代码语言:txt
复制
    return mScreens.values().toArray(new Fragment[mScreens.size()])[position];
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
@Override
代码语言:txt
复制
public int getCount() {
代码语言:txt
复制
代码语言:txt
复制
    return mScreens.size();
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
@Override
代码语言:txt
复制
public String getTitle(int position) {
代码语言:txt
复制
代码语言:txt
复制
    return mScreens.keySet().toArray(new String[mScreens.size()])[position];
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
// hack. we don't want to destroy our fragments and re-initiate them afte
代码语言:txt
复制
@Override
代码语言:txt
复制
public void destroyItem(View container, int position, Object object) {
代码语言:txt
复制
代码语言:txt
复制
    // TODO Auto-generated method stub
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
}

分段

代码语言:txt
复制
public class MessagesFragment extends ListFragment {
代码语言:txt
复制
代码语言:txt
复制
private boolean mIsLastMessages;
代码语言:txt
复制
代码语言:txt
复制
private List<Message> mMessagesList;
代码语言:txt
复制
private MessageArrayAdapter mAdapter;
代码语言:txt
复制
代码语言:txt
复制
private LoadMessagesTask mLoadMessagesTask;
代码语言:txt
复制
private OnMessageListActionListener mListener;
代码语言:txt
复制
代码语言:txt
复制
// define callback interface
代码语言:txt
复制
public interface OnMessageListActionListener {
代码语言:txt
复制
    public void onMessageInitialisation();
代码语言:txt
复制
    public void onMessageSelected(Message selectedMessage);
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
@Override
代码语言:txt
复制
public void onAttach(Activity activity) {
代码语言:txt
复制
    super.onAttach(activity);
代码语言:txt
复制
    // setting callback
代码语言:txt
复制
    mListener = (OnMessageListActionListener) activity;
代码语言:txt
复制
    mIsLastMessages = activity instanceof DashboardActivity;
代码语言:txt
复制
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
@Override
代码语言:txt
复制
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
代码语言:txt
复制
    inflater.inflate(R.layout.fragment_listview, container);
代码语言:txt
复制
    mProgressView = inflater.inflate(R.layout.listrow_progress, null);
代码语言:txt
复制
    mEmptyView = inflater.inflate(R.layout.fragment_nodata, null);
代码语言:txt
复制
    return super.onCreateView(inflater, container, savedInstanceState);
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
@Override
代码语言:txt
复制
public void onActivityCreated(Bundle savedInstanceState) {
代码语言:txt
复制
    super.onActivityCreated(savedInstanceState);
代码语言:txt
复制
代码语言:txt
复制
    // instantiate loading task
代码语言:txt
复制
    mLoadMessagesTask = new LoadMessagesTask();
代码语言:txt
复制
代码语言:txt
复制
    // instantiate list of messages
代码语言:txt
复制
    mMessagesList = new ArrayList<Message>();
代码语言:txt
复制
    mAdapter = new MessageArrayAdapter(getActivity(), mMessagesList);
代码语言:txt
复制
    setListAdapter(mAdapter);
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
@Override
代码语言:txt
复制
public void onResume() {
代码语言:txt
复制
    mListener.onMessageInitialisation();
代码语言:txt
复制
    super.onResume();
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
public void onListItemClick(ListView l, View v, int position, long id) {
代码语言:txt
复制
    Message selectedMessage = (Message) getListAdapter().getItem(position);
代码语言:txt
复制
    mListener.onMessageSelected(selectedMessage);
代码语言:txt
复制
    super.onListItemClick(l, v, position, id);
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
/* public methods to load messages from host acitivity, etc... */
代码语言:txt
复制
}

方案

愚蠢的解决方案是用putFragment将片段保存在onSaveInstanceState(主机Activity)中,并通过getFragment将它们放入onCreate中。但我仍然有一种奇怪的感觉,事情不应该这样...请参阅下面的代码:

代码语言:txt
复制
    @Override
代码语言:txt
复制
protected void onSaveInstanceState(Bundle outState) {
代码语言:txt
复制
代码语言:txt
复制
    super.onSaveInstanceState(outState);
代码语言:txt
复制
    getSupportFragmentManager()
代码语言:txt
复制
            .putFragment(outState, MessagesFragment.class.getName(), mMessagesFragment);
代码语言:txt
复制
}
代码语言:txt
复制
代码语言:txt
复制
protected void onCreate(Bundle savedInstanceState) {
代码语言:txt
复制
    Logger.d("Dash onCreate");
代码语言:txt
复制
    super.onCreate(savedInstanceState);
代码语言:txt
复制
代码语言:txt
复制
    ...
代码语言:txt
复制
    // create fragments to use
代码语言:txt
复制
    if (savedInstanceState != null) {
代码语言:txt
复制
        mMessagesFragment = (MessagesFragment) getSupportFragmentManager().getFragment(
代码语言:txt
复制
                savedInstanceState, MessagesFragment.class.getName());
代码语言:txt
复制
                StreamsFragment.class.getName());
代码语言:txt
复制
    }
代码语言:txt
复制
    if (mMessagesFragment == null)
代码语言:txt
复制
        mMessagesFragment = new MessagesFragment();
代码语言:txt
复制
    ...
代码语言:txt
复制
}

回答

和开发者交流更多问题细节吧,去 写回答
相关文章

相似问题

相关问答用户
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档