在 FragmentStatePagerAdapter 中导航时清除片段
Fragment is cleared when navigated in FragmentStatePagerAdapter
我有一个 activity,其中包含一个 FragmentStatePagerAdapter,在此 FragmentStatePagerAdapter 中有三个片段。或者,它们在调用适当的 getItem() 时启动。
activity 执行数据密集型任务,并在完成后发送广播。我已经在 FragmentStatePagerAdapter 中的每个片段中注册了一个广播接收器。
现在一切正常,除了一件事:
- 当我们滚动到位置 2 的片段时(位置 1 和 2
正常工作)位置0的片段被清除并且没有
return.
以下是我的一些代码示例:
FragmentStatePagerAdapter
public class MessagePagerAdapter 扩展了 FragmentStatePagerAdapter {
public MessagePagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int arg0) {
if(arg0 == 0) {
Fragment fragment = new RecentConversationFragment();
return fragment;
} else if(arg0 == 1) {
Fragment fragment = new PrivateConversationFragment();
return fragment;
} else {
Fragment fragment = new ClanConversationFragment();
return fragment;
}
}
@Override
public int getCount() {
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
if(position == 0) {
return "Recent";
} else if(position == 1) {
return "Private";
} else {
return "Clan";
}
}
相关部分activity
收到数据后,我广播了一个意图
Intent recentIntent = new Intent("MESSAGE_LOADER_RECENT");
MessageActivity.this.sendBroadcast(recentIntent);
这个广播在我的片段中是这样接收的:
private void createReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("MESSAGE_LOADER_RECENT");
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
fetchMessages();
}
};
getActivity().getApplicationContext().registerReceiver(receiver,
intentFilter);
}
private void fetchMessages() {
this.conversations = mActivity.getRecentPrivateConversations();
messageListView.setAdapter(new ConversationListAdapter(mActivity,
R.layout.conversation_row, conversations));
messageListView.setDivider(null);
messageListView.setDividerHeight(0);
mActivity.recentConversationBroadcastReceived = true;
messageListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
mActivity.navigateToConversation(conversations.get(position));
}
});
}
注意我设置了mActivity.recentConversationBroadcastReceived = true
,我这样做是因为我一直这样发送广播:
在viewPager.setOnPageChangeListener、
@Override
public void onPageSelected(int arg0) {
//here we check whether a broadcast is already sent to the
//specific fragment, if not we need to send one
if (arg0 == 0 || arg0 == 1) {
// recent or private
if (MessageActivity.this.loadedConversations != null) {
// check if the fragment already received a broadcast
if (arg0 == 0 && !recentConversationBroadcastReceived) {
Intent intent = new Intent("MESSAGE_LOADER_RECENT");
MessageActivity.this.sendBroadcast(intent);
} else if (arg0 == 1
&& !privateConversationBroadcastReceived) {
Intent intent = new Intent("MESSAGE_LOADER_PRIVATE");
MessageActivity.this.sendBroadcast(intent);
}
}
} else {
// clan
if (!clanConversationBroadcastReceived
&& MessageActivity.this.loadedClanConversations != null) {
Intent intent = new Intent("MESSAGE_LOADER_CLAN");
MessageActivity.this.sendBroadcast(intent);
}
}
}
我这样做是因为当我发送广播时,不能保证当前活动片段是实际使用数据的片段,并且该片段可能不会被启动。所以我在每次页面更改时发送一个广播,直到收到为止。
希望有人能帮我解决这个问题。
呃。我讨厌回答自己的问题。
这个问题可以通过设置ViewPager的offScreenPageLimit来避免。默认限制是 2,但我有 3 个片段,所以这就是为什么每次都重新创建位置 0 的片段。所以解决方案是:
viewpager.setOffscreenPageLimit(2);
来源:Android : FragmentPagerAdapter don't saved the state of Fragment?
当然要感谢帮助过我的人
我有一个 activity,其中包含一个 FragmentStatePagerAdapter,在此 FragmentStatePagerAdapter 中有三个片段。或者,它们在调用适当的 getItem() 时启动。
activity 执行数据密集型任务,并在完成后发送广播。我已经在 FragmentStatePagerAdapter 中的每个片段中注册了一个广播接收器。
现在一切正常,除了一件事:
- 当我们滚动到位置 2 的片段时(位置 1 和 2 正常工作)位置0的片段被清除并且没有 return.
以下是我的一些代码示例:
FragmentStatePagerAdapter
public class MessagePagerAdapter 扩展了 FragmentStatePagerAdapter {
public MessagePagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int arg0) {
if(arg0 == 0) {
Fragment fragment = new RecentConversationFragment();
return fragment;
} else if(arg0 == 1) {
Fragment fragment = new PrivateConversationFragment();
return fragment;
} else {
Fragment fragment = new ClanConversationFragment();
return fragment;
}
}
@Override
public int getCount() {
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
if(position == 0) {
return "Recent";
} else if(position == 1) {
return "Private";
} else {
return "Clan";
}
}
相关部分activity
收到数据后,我广播了一个意图
Intent recentIntent = new Intent("MESSAGE_LOADER_RECENT");
MessageActivity.this.sendBroadcast(recentIntent);
这个广播在我的片段中是这样接收的:
private void createReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("MESSAGE_LOADER_RECENT");
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
fetchMessages();
}
};
getActivity().getApplicationContext().registerReceiver(receiver,
intentFilter);
}
private void fetchMessages() {
this.conversations = mActivity.getRecentPrivateConversations();
messageListView.setAdapter(new ConversationListAdapter(mActivity,
R.layout.conversation_row, conversations));
messageListView.setDivider(null);
messageListView.setDividerHeight(0);
mActivity.recentConversationBroadcastReceived = true;
messageListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
mActivity.navigateToConversation(conversations.get(position));
}
});
}
注意我设置了mActivity.recentConversationBroadcastReceived = true
,我这样做是因为我一直这样发送广播:
在viewPager.setOnPageChangeListener、
@Override
public void onPageSelected(int arg0) {
//here we check whether a broadcast is already sent to the
//specific fragment, if not we need to send one
if (arg0 == 0 || arg0 == 1) {
// recent or private
if (MessageActivity.this.loadedConversations != null) {
// check if the fragment already received a broadcast
if (arg0 == 0 && !recentConversationBroadcastReceived) {
Intent intent = new Intent("MESSAGE_LOADER_RECENT");
MessageActivity.this.sendBroadcast(intent);
} else if (arg0 == 1
&& !privateConversationBroadcastReceived) {
Intent intent = new Intent("MESSAGE_LOADER_PRIVATE");
MessageActivity.this.sendBroadcast(intent);
}
}
} else {
// clan
if (!clanConversationBroadcastReceived
&& MessageActivity.this.loadedClanConversations != null) {
Intent intent = new Intent("MESSAGE_LOADER_CLAN");
MessageActivity.this.sendBroadcast(intent);
}
}
}
我这样做是因为当我发送广播时,不能保证当前活动片段是实际使用数据的片段,并且该片段可能不会被启动。所以我在每次页面更改时发送一个广播,直到收到为止。
希望有人能帮我解决这个问题。
呃。我讨厌回答自己的问题。
这个问题可以通过设置ViewPager的offScreenPageLimit来避免。默认限制是 2,但我有 3 个片段,所以这就是为什么每次都重新创建位置 0 的片段。所以解决方案是:
viewpager.setOffscreenPageLimit(2);
来源:Android : FragmentPagerAdapter don't saved the state of Fragment?
当然要感谢帮助过我的人