Android活动导航保存状态
Posted
技术标签:
【中文标题】Android活动导航保存状态【英文标题】:Android activity navigation save state 【发布时间】:2014-02-24 01:37:34 【问题描述】:在主要活动ActivityA
中,我将FragmentA
替换为片段FragmentB
。从FragmentB
,用户可以开始一个新的活动ActivityB
。通过点击ActivityB
中的返回按钮,ActivityA
将显示为FragmentA
。我期待看到FragmentB
的最后状态。我是否必须单独保存以前活动的状态才能提供此行为?
ActivityA(FragmentA) -> ActivityA(FragmentB) -> ActivityB
BACK
ActivityA(FragmentB)
在主要活动中,我使用以下方式设置当前片段:
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.a_main_frame_content, new FragmentB())
.addToBackStack(null)
.commit();
从片段中我开始一个新的活动:
Intent intent = new Intent(getActivity(), ActivityB.class);
getActivity().startActivity(intent);
ActivityA
被设置为ActivityB
的父活动以提供正确的导航。
[UPDTATE] 问题似乎在于向后导航和向上导航的不同行为。如果我向后导航,则活动将显示为其最后状态,而向上导航会强制重新创建活动。
【问题讨论】:
你能发布活动完整代码吗? 我的解决方案对你有用吗? 【参考方案1】:让我们试试这个:
在parentActivity的intent中(如果你可以在创建parentActivity之前设置它最好,否则你可能不得不使用setIntent):
currentActivityIntent.putExtra("random-unique-key-for-each-activity",
random-unique-key-for-each-activity);
在您创建子活动之前,您将以下内容放入地图中:
myKeyIntentMap.put(random-unique-key-for-each-activity, currentActivityIntent);
在“Up”事件触发的方法中:
String parentKey = currentActivity.parentActivity.getIntent.getStringExtra("random-unique-key-for-each-activity");
Intent intentToLaunch = (Intent)myKeyIntentMap.get(parentKey);
intentToLaunch.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP );
startActivity(intentToLaunch);
这样,使用意图,即使您的历史堆栈是 A-someAct1-someAct2-B,并且您启动解析到 A 的意图,它也会被“带到前面”杀死一些行为。
附:我没有做任何空检查,也没有记住确切的方法名称,只是给了你一个方法。
【讨论】:
这实际上可以工作。但我想我误解了设计指南。通过执行这样的操作,UP
按钮的行为将无法达到预期。
IMO 你要求一些不可接受的东西,上一个屏幕并不意味着它必须重新加载屏幕。意图标志用于将现有行为置于前面或启动新行为等,因此这完全取决于它如何适合您的应用程序。如果 UP 需要保留父活动的先前状态,则可以使用我的解决方案,否则请使用他们提供的解决方案。但理想情况下,我喜欢一个选项来指定,如果我想去以前的状态或新的状态。【参考方案2】:
“向上”的行为有时确实具有误导性。当我遇到类似的问题时,我更愿意节省时间而不是处理保存状态。
您可以通过在Activity
中捕获导航“向上”事件来快速解决它:
@Override
public boolean onOptionsItemSelected(MenuItem item)
if (item.getItemId() == android.R.id.home)
onBackPressed();
return true;
【讨论】:
有没有办法判断backstack中是否有activity?如果我的应用程序直接在这个 Activity 中启动,我该怎么办? 好吧,我认为你不必这样做。使用此代码,一切都将按预期工作:当您按下返回或向上处于最后一个返回堆栈状态(活动或片段)时,您将离开 app.框架将为您完成所有工作。试试看。 有没有办法说:If up-activity == back-activty then onBackPressed()
?
你为什么需要它?据我所知 up-activity 总是等于 back-activty。
不,这不是真的。 Up 始终指向活动的逻辑父级,而 back 指向查看的最后一个活动。向上与向后:developer.android.com/design/patterns/navigation.html【参考方案3】:
发生这种情况是因为当您移动到 ActivityB
时,activityA 将分别关闭和销毁状态,因此当您返回到活动 ActivityA
时,ActivityA 再次开始,因此您将 fragmentA 作为视图。您需要使用 sharedPfer 保存状态。使用一些标志将状态保存在onCreateView()
检查状态并为视图设置正确的片段。希望你明白我的意思。
public static final String PREFS_NAME = "mypref";
boolean isVisited;
//check sharedpref
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
isVisited= settings.getBoolean("isVisited", false);
if(!isVisited)
// set fragmentA
else
// set fragmentB
// inside fragment transaction block
Editor edit = settings.editor();
isVisited.setBoolean(true);
edit.commit();
【讨论】:
感谢提示,知道了。但这是否也意味着我也必须保存片段视图的状态?喜欢 ListView 的数据和滚动位置? 如果你想显示特定的,那么你也可以保存这些状态。 @Yup 当我们将活动 A 移动到 B 时,它调用活动 A 的 OnPause 和 OnStop 而不是 OnDestroy。以上是关于Android活动导航保存状态的主要内容,如果未能解决你的问题,请参考以下文章