如何正确返回父活动?

在我的 android 应用程序中有2个活动(A 和 B) ,我使用一个意图从活动 A 到活动 B。启用了 father _ activity 的使用:

 <activity
android:name=".B"
android:label="B" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.app_name.A" />
</activity>

我还使用了一个主题,它提供了一个 UP 按钮。

因此,在我调用活动 B 之后,我可以使用 UP 按钮返回到活动 A。问题是,应用程序似乎再次调用活动 A 的 OnCreate ()函数,这不是我需要的行为。我需要活动 A 看起来和我调用活动 B 之前一样。

有办法做到吗?

剪辑

我没有编写任何从活动 A 启动活动 B 的代码,我认为它是由 Eclipse 自动生成的。

B 类似于:

    @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
getActionBar().setDisplayHomeAsUpEnabled(true);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_b, menu);
return true;
}




@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
168605 次浏览

更新答案: 向上导航设计

您必须声明哪个活动是每个活动的适当父活动。这样做允许系统简化诸如 Up 之类的导航模式,因为系统可以从清单文件确定逻辑父活动。

因此,您必须在带有属性的 Activity 标记中声明您的父 Activity

android:parentActivityName

比如,

<!-- The main/home activity (it has no parent activity) -->
<activity
android:name="com.example.app_name.A" ...>
...
</activity>
<!-- A child of the main activity -->
<activity
android:name=".B"
android:label="B"
android:parentActivityName="com.example.app_name.A" >
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.app_name.A" />
</activity>

使用这种方式声明的父活动,您可以导航到适当的父活动,如下所示,

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}

因此,当您调用 NavUtils.navigateUpFromSameTask(this);这个方法时,它将完成当前活动并启动(或恢复)适当的父活动。如果目标父活动位于任务的后台堆栈中,则按照 FLAG_ACTIVITY_CLEAR_TOP的定义将其提前。

要显示 Up 按钮,必须声明 setDisplayHomeAsUpEnabled():

@Override
public void onCreate(Bundle savedInstanceState) {
...
getActionBar().setDisplayHomeAsUpEnabled(true);
}

旧答案: (没有向上导航,默认返回导航)

只有当你从活动 B 再次启动活动 A 时才会发生这种情况。

使用 startActivity()

代替从活动 A 启动活动 B 使用 startActivityForResult()并在活动 A 中覆盖 onActivtyResult()

现在在活动 B 中只需调用按钮上的 finish()。所以现在您定向到活动 A 的 onActivityResult(),而没有再次创建活动 A。.

我几乎有同样的设置,导致同样不想要的行为。对我来说,这个方法奏效了: 在我的应用程序的 Manifest.xml中为活动 A 添加以下属性:

android:launchMode="singleTask"

有关详细说明,请参阅 这篇文章

你在 Android 清单中声明了标准 launchMode的活动 A。根据 文件,这意味着:

系统总是在目标中创建活动的新实例 任务和路线的意图到它。

因此,即使任务堆栈处理正确,系统也必须重新创建活动 A (即调用 onCreate)。

要解决这个问题,您需要更改清单,将以下属性添加到 A 活动声明:

android:launchMode="singleTop"

注意: 调用 finish()(正如前面建议的解决方案)工作于 只有,当您是 完全确定时,您正在终止的活动 B 实例位于活动 A 的实例之上。在更复杂的工作流中(例如,从通知中启动活动 B) ,情况可能并非如此,您必须从 B 中正确启动活动 A。

实现这一目标的更好方法是使用两种手段: 电话:

NavUtils.navigateUpFromSameTask(this);

现在,为了让它工作,您需要让您的清单文件状态为活动 A 有家长活动 B。家长活动不需要任何东西。在版本4及以上版本中,您将不需要额外的工作就可以得到一个很好的反向箭头(这也可以在较低版本中通过一些代码来实现,我将在下面介绍) 您可以在 GUI 的 Manif- > application 选项卡中设置这些数据(向下滚动到父活动名称,然后手动放置它)

支援节点:

如果希望支持版本4以下的版本,还需要包括元数据。 右键单击活动,add-> meta data,name = android.support. paRENT _ ACTIVITY 和 value = your.full.activity.name

以获得更低版本的漂亮箭头:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

请注意,您将需要支持库版本7,以得到这一切的工作,但它是非常值得的!

试试这个:

Intent intent;
@Override
public void onCreate(Bundle savedInstanceState) {
intent = getIntent();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
getActionBar().setDisplayHomeAsUpEnabled(true);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_b, menu);
return true;
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpTo(this,intent);
return true;
}
return super.onOptionsItemSelected(item);
}

使用属性添加到活动清单信息中

android:launchMode="singleTask"

对我来说效果很好

我在使用 android 5.0时遇到过类似的问题,使用了一个糟糕的父活动名称

<activity
android:name=".DisplayMessageActivity"
android:label="@string/title_activity_display_message"
android:parentActivityName=".MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.MainActivity" />
</activity>

我从父活动名称中删除了 com.example.myfirstapp,它运行正常

我试过 android:launchMode="singleTask"但没用。 我用 android:launchMode="singleInstance"就行了

虽然这是一个老问题,但这里有另一个(我认为是最干净和最好的)解决方案,因为所有以前的答案都不适合我,因为我从 小部件活动 B

public void navigateUp() {
final Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot()) {
Log.v(logTag, "Recreate back stack");
TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities();
} else {
NavUtils.navigateUpTo(this, upIntent);
}
}

[ https://stackoverflow.com/a/31350642/570168]

还可以看到: https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-android

进入我的清单,并添加 android:launchMode="singleTop"的活动为我做了诀窍。

这特别解决了我的问题,因为我不希望 Android 在点击工具栏上的 Up按钮后创建前一个活动的新实例——我想在导航层次结构中使用前一个活动的现有实例。

参考资料: Android: launchMode

给@LorenCK 的回答加上一条: 改变

NavUtils.navigateUpFromSameTask(this);

下面的代码,如果你的活动可以从另一个活动启动,这可以成为任务的一部分,由其他应用程序启动

Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
TaskStackBuilder.create(this)
.addNextIntentWithParentStack(upIntent)
.startActivities();
} else {
NavUtils.navigateUpTo(this, upIntent);
}

这将启动一个新任务并启动您的 Activity 的父 Activity,您可以在 Manifest 中定义它,如 MinSDK version < = 15

<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.app_name.A" />

如果大于15,则使用 parentActivityName

在 Java 类:-

    toolbar = (Toolbar) findViewById(R.id.apptool_bar);
setSupportActionBar(toolbar);


getSupportActionBar().setTitle("Snapdeal");


getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

舱单:-

<activity
android:name=".SubActivity"
android:label="@string/title_activity_sub"
android:theme="@style/AppTheme" >
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity"></meta-data>
</activity>

它会帮助你的

对我起作用的是:

    @Override
public boolean onOptionsItemSelected(MenuItem item) {


switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}


@Override
public void onBackPressed() {
finish();
}

TheRelevantActivity.java,现在它正在按预期工作

还有别忘了加上:

onCreate()方法中的 getSupportActionbar.setDisplayHomeAsUpEnabled(true);

    @Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);

就像背压一样

尝试使用这个解决方案,在子活动中: Https://stackoverflow.com/a/49980835/7308789

在任何上下文中,如果您想要在 onBackPressed上打开父活动

protected fun navigateToParent() {
NavUtils.getParentActivityIntent(this)?.let { upIntent ->
if (NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot) {
Timber.d("navigateToParent: sourceActivity should recreate")
startActivity(upIntent)
} else {
Timber.d("navigateToParent: sourceActivity in stack, just finish")
}
}
super.onBackPressed()
}

在清单中设置 android:parentActivityName

 <activity
android:name=".feature.signup.SignUpActivity"
android:parentActivityName=".feature.welcome.WelcomeActivity"
android:windowSoftInputMode="adjustResize" />