动态设置父活动

Dar*_*iss 58 android

所以目前我有一个可以从两个不同活动中获得的活动,问题是我只能将一个活动设置为清单XML文件中的父活动.显然这是糟糕的UX/UI设计,因为活动可能会将用户发回到之前的错误活动,所以我试图动态设置哪个活动是父活动.

问题是我不太确定如何处理这个问题,无论是代码还是XML,所以任何指针都会受到赞赏.:)

Ton*_*han 56

对于未来的读者这里是如何真正实现官方/妥善解决按了一个例子开发者指南(滚动开头段落"这是在适当的时候父活动可能会有所不同...... ").

请注意,此解决方案假设您正在使用支持库来实现您的工作ActionBar,并且您至少可以在清单XML文件中设置"默认"父活动,以便在您要退出的活动处于"任务"中时回退不属于您的应用程序(请阅读链接的文档以进行说明).

// Override BOTH getSupportParentActivityIntent() AND getParentActivityIntent() because
// if your device is running on API 11+ it will call the native
// getParentActivityIntent() method instead of the support version.
// The docs do **NOT** make this part clear and it is important!

@Override
public Intent getSupportParentActivityIntent() {
    return getParentActivityIntentImpl();
}

@Override
public Intent getParentActivityIntent() {
    return getParentActivityIntentImpl();
}

private Intent getParentActivityIntentImpl() {
    Intent i = null;

    // Here you need to do some logic to determine from which Activity you came.
    // example: you could pass a variable through your Intent extras and check that.
    if (parentIsActivityA) {
        i = new Intent(this, ActivityA.class);
        // set any flags or extras that you need.
        // If you are reusing the previous Activity (i.e. bringing it to the top
        // without re-creating a new instance) set these flags:
        i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        // if you are re-using the parent Activity you may not need to set any extras
        i.putExtra("someExtra", "whateverYouNeed");
    } else {
        i = new Intent(this, ActivityB.class);
        // same comments as above
        i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        i.putExtra("someExtra", "whateverYouNeed");
    }

    return i;
}
Run Code Online (Sandbox Code Playgroud)

注意:如果您没有在清单XML文件中设置默认的父Activity,那么您还需要实现onCreateSupportNavigateUpTaskStack(),因为系统将不知道如何为您的任务生成Backstack.我没有提供这个部分的任何例子.

我对finish()类型解决方案的看法

在我寻找这个问题的解决方案时,我遇到了一些答案,提出了覆盖onOptionsItemSelected()和拦截android.R.id.home按钮的策略,这样他们就可以简单地finish()将电流Activity返回到前一个屏幕.

在许多情况下,这将实现所需的行为,但我只想指出这绝对不是一个正确的UP导航.如果您通过其中一个父活动导航到子Activity,那么yes finish()将返回到正确的上一个屏幕,但如果您通过通知输入子Activity,该怎么办?在这种情况下finish(),按下UP按钮会使您回到主屏幕或您在查看通知之前查看的任何应用程序,而是应该将您发送到应用程序中的正确父活动.


Saj*_*Saj 29

像这样,您可以动态导航到父活动:

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

注意:它会将您重定向到您来自的活动或片段,无论它是否是父母.单击操作栏上/主页按钮将完成当前活动.

  • 对于那些阅读,虽然`finish()`确实在许多情况下实现了所需的行为,但在某些情况下它并不总是会导致正确的UP导航.请参阅我的回答和想法[解释此](http://stackoverflow.com/a/28334824/708906). (4认同)

Tas*_*kos 8

"Up"和"Back"在这里有两个概念."回来"是显而易见的:在我来到这里之前带我去我所在的地方.通常你不需要关心'后退',因为系统会处理它很好."向上"并不是那么明显 - 它类似于缩小 - 从元素到集合,从细节到更宽广的画面.

哪些适合您的使用案例?


根据下面的评论:向上按钮从Android清单中提取目的地,但它可以通过编程方式进行自定义.

  • 是的,向上按钮从Android清单中拉出目的地,但它可以[以编程方式自定义](http://developer.android.com/guide/topics/ui/actionbar.html#Home). (6认同)
  • 这个答案应该包含一个很好的例子,而不仅仅是将来可能会死的链接.但是我给它一个+1来使得分数在它所属的地方恢复正面,因为它确实引导我找到一个真正正确的解决方案,而不像其他一些答案. (5认同)
  • 如果你认真对待你的应用程序,也请阅读[导航设计指南](http://developer.android.com/design/patterns/navigation.html) - 保持流程真的有助于应用感觉自然.不要喂你需要全心全意地知道,只要知道有一种事情已经完成. (4认同)

小智 5

要覆盖的方法是 getParentActivityIntent。

这是我的代码并且工作得很好。

@Override
public Intent getParentActivityIntent() {
    Intent parentIntent= getIntent();
    String className = parentIntent.getStringExtra("ParentClassSource"); 

    Intent newIntent=null;
    try {
        //you need to define the class with package name
        newIntent = new Intent(OnMap.this, Class.forName(className));

    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return newIntent;
}
Run Code Online (Sandbox Code Playgroud)

来自家长活动;

Intent i = new Intent(DataDetailsItem.this, OnMap.class);
i.putExtra("ParentClassSource", "com.package.example.YourParentActivity");
startActivity(i);
Run Code Online (Sandbox Code Playgroud)