如何在带有活动的子流中提供后退导航

How to provide back navigation in a sub-flow with activities

我有活动 A、B、C,用户可以在它们之间导航。

Activity B也提供了类似(B1,B2,B3)的子流程。当用户完成子流程时,他会连同一些数据被发送回 B。

我应该使用什么意图标志或启动模式来提供 A - B - C 和 B1 - B2 - B3 之间的反向导航。而且 clear/finish 当返回 B 并在意图中传递一些数据时,这个子流?

我已经尝试将 FLAG_ACTIVITY_CLEAR_TOPFLAG_ACTIVITY_SINGLE_TOP 添加到子活动(B1、B2、B3),但没有成功。

在你的 activity B2:

  public void finish(){
        Bundle bundle = new Bundle();
        bundle.putString("KEY_NAVIGATION", "B");
        Intent intent = new Intent(B2.this, A.class);
        intent.putExtra("EXTRA", bundle);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }

在你的Activity答:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        component.inject(this);
        super.onCreate(savedInstanceState);
        if (getIntent().hasExtra("EXTRA")) {
            Intent intent = new Intent(A.this, B.class);
            startActivity(intent);
        }

        // do your logic
    }

通过这种方式,您可以从B2导航到A

希望对您有所帮助

您可以使用链式 onActivityResult 调用,而不是从 B2 绕到 B,您可以通过相同的链 (B2->B1->B) 自动向后调用 finish()你去从后面的堆栈中删除链条。这样,您仍然可以在 B1 或 B2 时按预期使用后退按钮,但是一旦您转到 A->B->B1->B2->B 后按“后退”按钮,您将回到 A,而不是 B2。

无论您在 B 之前访问了多少活动(例如,如果您从 Aa->Ab->Ac->B 然后通过 B->B1->B2->B 循环),这都将起作用,您仍然可以通过 B->Ac->Ab->Aa 返回。

public class ActivityB extends AppCompatActivity {

  private static final int LAUNCH_B1 = 11;

  void launch_subloop() {
    Intent intent = new Intent(ActivityB.this, ActivityB1.class);
    startActivityForResult(intent, LAUNCH_B1);
  }

  @Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if( resultCode == Activity.RESULT_OK && requestCode == LAUNCH_B1) {
      // do stuff upon loop completion
    }
  }
}

public class ActivityB1 extends AppCompatActivity {
  private static final int LAUNCH_B2 = 12;

  void go_to_next_step() {
    Intent intent = new Intent(this, ActivityB2.class);
    startActivityForResult(intent, LAUNCH_B2);
  }

  @Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if( resultCode == Activity.RESULT_OK && requestCode == LAUNCH_B2) {
      // This will finish B1 and bring us back to B, with B1 and B2 now 
      // removed from the back stack
      setResult(Activity.RESULT_OK);
      finish();
    }
  }
}

public class ActivityB2 extends AppCompatActivity {

  void finish_subloop() {
    // when you finish, this should go back through the 
    // activities and finish B1 and B2, so if you go on from B to C, you can
    // still go back from C -> B -> A
    // This will bring us back to B1 and finish B2 (remove from back stack)
    setResult(Activity.RESULT_OK);
    finish();
  }
}

尝试在 Activity B 的清单中制作:

launchMode = “singleTask”

所以在 Activity B2 之后你可以 开始Activity("intent for activity b2 with putting some data in this intent") 并在 onNewIntent( ) 在 Activity B

如果Actvities B、B1、B2是同一个活动,为什么不直接用片段来制作呢?

你也可以通过标志在没有 lunchMode 的情况下做同样的事情:

来自 Activity A

startActivity("intent for activity b with putting some data in this intent", Intent.FLAG_ACTIVITY_NEW_TASK)

在Activity乙

startActivity("intent for activity B with data (if needs)", Intent.FLAG_ACTIVITY_NO_HISTORY)

在Activity B1

startActivity("intent for activity B with data (if needs)", Intent.FLAG_ACTIVITY_NO_HISTORY)

在Activity B2

startActivity("intent for activity B with data (if needs)", Intent.FLAG_ACTIVITY_NEW_TASK)

最后,我通过执行以下操作获得了预期的结果。在 Activity B 中,我创建了 2 个方法来启动 activity

class ActivityB : AppCompatActivity() {

    fun startFromActivityA(context: Context) {
        val intent = Intent(context, ActivityB::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        context.startActivity(intent)
    }

    fun startFromActivityB2(context: Context, intentData: IntentData) {
        val intent = Intent(context, ActivityB::class.java)
        intent.putExtra(INTENT_DATA, intentData)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        context.startActivity(intent)
    }
}

所以当我进入子流程并且我想完成子流程时,我会调用startFromActivityB2。它会清除整个子流并仍然提供返回导航到 Activity A