如何正确返回父活动?

ash*_*aka 172 android parent android-intent android-activity

我在Android应用程序中有2个活动(A和B),我使用意图从活动A到活动B.使用parent_activity:

 <activity
        android:name=".B"
        android:label="B" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.app_name.A" />
  </activity>
Run Code Online (Sandbox Code Playgroud)

我还使用了一个提供UP按钮的主题.

因此,在我调用活动之后,BI可以使用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);
}
Run Code Online (Sandbox Code Playgroud)

Lor*_*zCK 326

launchMode在Android清单中使用标准声明了活动A. 根据文档,这意味着以下内容:

系统始终在目标任务中创建活动的新实例,并将意图路由到该任务.

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

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

android:launchMode="singleTop"
Run Code Online (Sandbox Code Playgroud)

注意:调用finish()(之前建议为解决方案)在您完全确定要终止的活动B实例位于活动A实例之上时才有效.在更复杂的工作流程中(例如,从通知启动活动B)可能不是这种情况,您必须从B正确启动活动A.

  • **以下是来自Android文档的解释,**"标准"和"单一顶部"模式仅在一个方面彼此不同:每次有"标准"活动的新意图时,该类的新实例是创建以响应该意图.每个实例处理一个intent.类似地,也可以创建"singleTop"活动的新实例来处理新意图.但是,如果目标任务已经在其堆栈顶部具有活动的现有实例,则该实例将接收新意图(在onNewIntent()调用中); 未创建新实例. (10认同)

use*_*305 81

更新的答案:向上导航设计

您必须声明哪个活动是每个活动的适当父级.这样做允许系统便于导航模式,例如Up,因为系统可以从清单文件中确定逻辑父活动.

因此,您必须在标记Activity with attribute中声明您的父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>
Run Code Online (Sandbox Code Playgroud)

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

@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);
}
Run Code Online (Sandbox Code Playgroud)

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

要显示向上按钮,您必须声明 setDisplayHomeAsUpEnabled():

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    getActionBar().setDisplayHomeAsUpEnabled(true);
}
Run Code Online (Sandbox Code Playgroud)

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

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

startActivity().

而不是活动A中的这个,而是在活动A中使用startActivityForResult()和覆盖onActivtyResult()活动B.

现在在活动B中只需finish()按下按钮Up.所以现在你转向活动A onActivityResult()而不再创建活动A.

  • 而不是代码行`NavUtils.navigateUpFromSameTask(this);`write`finished()`. (17认同)
  • 这就引出了一个问题,为什么Google在他们的Navigation(http://developer.android.com/design/patterns/navigation.html)文档中没有提到关于`finish()`或`startActivityForResult()`的任何内容? (4认同)

小智 22

我有几乎相同的设置导致相同的不需要的行为.对我来说这很有效:将以下属性添加到Manifest.xml我的应用程序中的活动A :

android:launchMode="singleTask"
Run Code Online (Sandbox Code Playgroud)

有关更多说明,请参阅此文章.

  • 这不是正确的方法,因为它每次都会不必要地创建一个新任务,你应该使用launchMode ="singleTop". (5认同)

Tob*_*ias 19

虽然这是一个古老的问题,但这是另一个(imho是最干净,最好的)解决方案,因为我将活动BWidget进行了深度链接,所有以前的回答都不适用于我.

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

[ /sf/answers/2194544971/ ]

但也请看:https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-android


don*_*ald 7

实现这一目标的更好方法是使用两件事:call:

NavUtils.navigateUpFromSameTask(this);
Run Code Online (Sandbox Code Playgroud)

现在,为了使其工作,您需要让您的清单文件声明活动A具有父活动B.父活动不需要任何东西.在版本4及更高版本中,您将获得一个不错的后退箭头,无需额外工作(这可以在较低版本上完成,也可以使用一些代码完成,我将它放在下面)您可以在清单 - >应用程序选项卡中设置此数据在GUI中(向下滚动到父活动名称,并手动放置)

支持节点:

如果您希望支持版本低于4的版本,则还需要包含元数据.右键单击活动,添加 - >元数据,name = android.support.PARENT_ACTIVITY和value = your.full.activity.name

在较低版本中获得漂亮的箭头:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Run Code Online (Sandbox Code Playgroud)

请注意,您需要支持库版本7才能使这一切正常运行,但这非常值得!


Sou*_*abh 5

添加@LorenCK的答案,更改

NavUtils.navigateUpFromSameTask(this);
Run Code Online (Sandbox Code Playgroud)

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

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

这将启动一个新任务并启动您的 Activity 的父 Activity,您可以在清单中定义该 Activity,如下所示,最小 SDK 版本 <= 15

<meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.example.app_name.A" />
Run Code Online (Sandbox Code Playgroud)

parentActivityName或者如果它 > 15 则使用


Ham*_*sir 5

对我有用的是添加:

    @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();
    }
Run Code Online (Sandbox Code Playgroud)

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

是的,别忘了添加:

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