Dav*_*row 69 android android-activity android-actionbar up-button
我有两个活动,A和B.当活性A被第一次启动,它访问Intent传递给它(因为Bundle是null,因为它应该通过在第一时间),并相应地显示信息:
CustInfo m_custInfo;
...
protected void onCreate(Bundle savedInstanceState)
{
...
Bundle bundle = (savedInstanceState == null) ? getIntent().getExtras() : savedInstanceState;
m_custInfo = (CustInfo) m_bundle.getSerializable("CustInfo");
if (m_custInfo != null
...
}
Run Code Online (Sandbox Code Playgroud)
这在第一次通过时工作正常.该EditText控制和ListView正确地填写.
现在,当单击列表中的项目时,将启动活动B以显示详细信息:
m_custInfo = m_arrCustomers.get(pos);
Intent intent = new Intent(A.this, B.class);
intent.putExtra("CustInfo", m_custInfo); // CustInfo is serializable
// printing this intent, it shows to have extras and no flags
startActivityForResult(intent, 1);
Run Code Online (Sandbox Code Playgroud)
在acivity B启动之前,框架调用A被覆盖onSaveInstanceState():
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putSerializable("CustInfo", m_custInfo);
}
Run Code Online (Sandbox Code Playgroud)
在活动B中,当在操作栏中按下向上按钮时,我想返回活动A并使其处于以前的状态:
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == android.R.id.home)
{
Intent intent = NavUtils.getParentActivityIntent(this);
// printing this intent, it shows to have flags but no extras
NavUtils.navigateUpFromSameTask(this); // tried finish() here but that created an even bigger mess
return true;
}
...
}
Run Code Online (Sandbox Code Playgroud)
这就是问题,当onCreate()第二次进入活动A时,Bundle参数是null 并 getExtras()返回null.自从onSaveInstanceState()被调用以来,我原本期望Bundle参数是非的null.
我在其他网站上看过这个问题,尝试过这些建议,但没有任何效果.
yon*_*joy 132
如果您希望应用程序以这种方式做出反应,您应该将活动A的启动模式声明为:
android:launchMode="singleTop"
Run Code Online (Sandbox Code Playgroud)
在AndroidManifest.xml中.
否则android使用标准启动模式,这意味着
"系统始终在目标任务中创建活动的新实例"
并重新创建您的活动(请参阅Android文档).
使用singleTop,系统将返回到您现有的活动(使用原始附加功能),如果它位于任务后堆栈的顶部.在这种情况下,无需实现onSaveInstanceState.
savedInstanceState在您的情况下为null,因为您的活动以前没有被操作系统关闭.
注意(谢谢,Android开发人员指向这个):
虽然这是问题的解决方案,但如果返回的活动不在后端堆栈的顶部,它将无法工作.考虑活动A的起始B的情况,它开始是C,并且C的父活动被配置为A.如果NavigateUpFromSameTask()从C 调用,则将重新创建活动,因为A不在堆栈顶部.
在这种情况下,可以使用这段代码:
Intent intent = NavUtils.getParentActivityIntent(this);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
NavUtils.navigateUpTo(this, intent);
Run Code Online (Sandbox Code Playgroud)
Mar*_*ner 19
这是因为NavUtils.navigateUpFromSameTask()基本上只是打电话startActivity(intentForActivityA).如果活动A使用默认值android:launchMode="standard",则会创建活动的新实例,并且不使用保存的状态.有三种方法可以解决这个问题,各种优点和缺点.
覆盖活动B中的getParentActivityIntent()并指定活动A所需的适当额外内容:
@Override
public Intent getParentActivityIntent() {
Intent intent = super.getParentActivityIntent();
intent.putSerializable("CustInfo", m_custInfo);
return intent;
}
Run Code Online (Sandbox Code Playgroud)
注意:如果您正在使用ActionBarActivity和支持库中的工具栏,那么您将需要覆盖getSupportParentActivityIntent().
我认为这是最优雅的解决方案,因为无论用户如何导航到活动B,它都能正常工作.如果用户直接导航到活动B而不通过活动A,则下面列出的两个选项无法正常工作,例如,如果活动B从通知或URL处理程序启动.我认为这种情况是"向上"导航API复杂的原因,并不仅仅是一个愚蠢的后退按钮.
该解决方案的一个缺点是使用标准的开始 - 新活动过渡动画而不是返回到先前活动的动画.
拦截了按钮,并把它作为通过重写一个愚蠢的后退按钮onNavigateUp() :
@Override
public boolean onNavigateUp() {
onBackPressed();
return true;
}
Run Code Online (Sandbox Code Playgroud)
注意:如果您正在使用ActionBarActivity和支持库中的工具栏,那么您将需要覆盖onSupportNavigateUp().
这个解决方案有点hacky,只适用于"up"和"back"应该表现相同的应用程序.这可能是罕见的,因为如果"向上"和"向后"应该表现相同,那么为什么还要打扰按钮呢?该解决方案的一个优点是使用标准的返回先前活动动画.
正如yonojoy所建议的,android:launchMode="singleTop"请参加活动A.详情请见他的回答.请注意,这singleTop不适用于所有应用程序.你必须尝试和/或花一些时间阅读文档来自己决定.
| 归档时间: |
|
| 查看次数: |
24598 次 |
| 最近记录: |