Skip to content

路由跳转

xiaojinzi123 edited this page Jun 2, 2023 · 3 revisions

路由跳转可分为 普通方式 和 声明式的方式

声明式方式的类似于 Retrofit 的使用形式. 它相比较于普通方式有以下优点:

  1. 可以统一对某个界面的跳转, 由于声明了跳转方式, 在使用的时候不容易出错
  2. 有助于参数的维护

这里预定义几个常量, 表示不同的地址:

登录界面:const val route_login = "user/login"

进入条件:无

参数:无

返回结果:resultCode = Activity.RESULT_OK intent: null

订单详情:const val route_order_detail = "order/detail"

进入条件:需要登录

参数:orderId

返回结果:null

普通跳转 -- 跳转去登录

普通方式

Router.with(context = context)
  .hostAndPath(hostAndPath = route_login)
  .forword()

声明式方式

@RouterApiAnno
interface RouterApi {

  @HostAndPathAnno( route_login )
  fun toLoginView(
    @UiContext context: Context,
  )

}

// 发起跳转
Router.withApi(apiClass = RouterApi::class).toLoginView(context = context)
// 或者这样
RouterApi::class.routeApi().toLoginView(context = context)

普通跳转 -- 跳转去登录 -- 监听跳转成功

普通方式

Router.with(context = context)
  .hostAndPath(hostAndPath = route_login)
  .forword {
    // 成功的回调
  }

// 协程中使用
scope.launch {
  Router.with(context = context)
    .hostAndPath(hostAndPath = route_login)
    .await()
}

声明式方式

@RouterApiAnno
interface RouterApi {

  @HostAndPathAnno( route_login )
  fun toLoginView(
    @UiContext context: Context,
    callback: () -> Unit,
  )

  @HostAndPathAnno( route_login )
  suspend fun toLoginView(
    @UiContext context: Context,
  )

}

// 发起跳转
Router.withApi(apiClass = RouterApi::class)
  .requestPermission(context = context) {
    // 成功的回调
  }


// 协程中使用
scope.launch {
  Router.withApi(apiClass = RouterApi::class).requestPermission(context = context)
}

普通跳转 -- 跳转去登录 -- 监听跳转成功、失败和取消

普通方式

Router.with(context = context)
  .hostAndPath(hostAndPath = route_login)
  .forward(object : Callback {

    override fun onSuccess(result: RouterResult) {
    }

    override fun onError(errorResult: RouterErrorResult) {
    }

    override fun onEvent(successResult: RouterResult?, errorResult: RouterErrorResult?) {
    }

    override fun onCancel(originalRequest: RouterRequest?) {
    }

  })

声明式方式

@RouterApiAnno
interface RouterApi {

  @HostAndPathAnno( route_login )
  fun toLoginView(
    @UiContext context: Context,
    callback: () -> Unit,
  )

}

// 发起跳转
Router.withApi(apiClass = RouterApi::class)
  .requestPermission(context = context, object : Callback {

    override fun onSuccess(result: RouterResult) {
    }

    override fun onError(errorResult: RouterErrorResult) {
    }

    override fun onEvent(successResult: RouterResult?, errorResult: RouterErrorResult?) {
    }

    override fun onCancel(originalRequest: RouterRequest?) {
    }

  })

普通跳转 -- 跳转去登录 -- 手动取消

val disposable: NavigationDisposable = Router.with(context = context)
  .hostAndPath(hostAndPath = route_login)
  .navigate()
  // 后续是可以取消跳转的
  disposable.cancel()

普通跳转 -- 跳转去登录 -- 跳转获取 ActivityResult

普通方式

Router.with(context = context)
  .hostAndPath(hostAndPath = route_login)
  .requestCodeRandom()
  .forwardForResult {
    // 这里拿到了返回的 ActivityResult
  }

// 协程中使用
scope.launch {
  Router.with(context = context)
    .hostAndPath(hostAndPath = route_login)
    .requestCodeRandom()
    .activityResultAwait()
}

声明式方式

@RouterApiAnno
interface RouterApi {

  @RequestCodeAnno // 不填写表示框架自动生成一个
  @NavigateAnno(forResult = true)
  @HostAndPathAnno( route_login )
  fun toLoginView(
    @UiContext context: Context,
    callback: (ActivityResult) -> Unit,
  )

  // suspend 方法
  @RequestCodeAnno // 不填写表示框架自动生成一个
  @NavigateAnno(forResult = true)
  @HostAndPathAnno( route_login )
  suspend fun toLoginView(
    @UiContext context: Context,
  ): ActivityResult

}

普通跳转 -- 跳转去登录 -- 跳转获取 Intent

普通方式

Router.with(context = context)
  .hostAndPath(hostAndPath = route_login)
  .requestCodeRandom()
  .forwardForIntent {
    // 这里拿到了返回的 Intent
  }

// 协程中使用
scope.launch {
  Router.with(context = context)
    .hostAndPath(hostAndPath = route_login)
    .requestCodeRandom()
    .intentAwait()
}

声明式方式

@RouterApiAnno
interface RouterApi {

  @RequestCodeAnno // 不填写表示框架自动生成一个
  @NavigateAnno(forIntent = true)
  @HostAndPathAnno( route_login )
  fun toLoginView(
    @UiContext context: Context,
    callback: (Intent) -> Unit,
  )

  // suspend 方法
  @RequestCodeAnno // 不填写表示框架自动生成一个
  @NavigateAnno(forIntent = true)
  @HostAndPathAnno( route_login )
  suspend fun toLoginView(
    @UiContext context: Context,
  ): Intent

}

普通跳转 -- 跳转去登录 -- 跳转获取 Intent 并且匹配 resutCode

普通方式

Router.with(context = context)
  .hostAndPath(hostAndPath = route_login)
  .requestCodeRandom()
  // 默认匹配 Activity.RESULT_OK
  .forwardForIntentAndResultCodeMatch {
    // 这里拿到了返回的 Intent
  }

Router.with(context = context)
  .hostAndPath(hostAndPath = route_login)
  .requestCodeRandom()
  // 自定义匹配的 resultCode
  .forwardForIntentAndResultCodeMatch(expectedResultCode = xxx) {
    // 这里拿到了返回的 Intent
  }

// 协程中使用
scope.launch {
  Router.with(context = context)
    .hostAndPath(hostAndPath = route_login)
    .requestCodeRandom()
    // 自定义匹配的 resultCode
    .resultCodeMatchAndIntentAwait(expectedResultCode = xxx)
}

声明式方式

@RouterApiAnno
interface RouterApi {

  @RequestCodeAnno // 不填写表示框架自动生成一个
  // 表示想要 Intent, 并且匹配 resultCode
  @NavigateAnno(forIntent = true, resultCodeMatch = Activity.RESULT_OK)
  @HostAndPathAnno( route_login )
  fun toLoginView(
    @UiContext context: Context,
    callback: (Intent) -> Unit,
  )

  // suspend 方法

  // 不填写表示框架自动生成一个
  @RequestCodeAnno
  // 表示想要 Intent, 并且匹配 resultCode
  @NavigateAnno(forIntent = true, resultCodeMatch = Activity.RESULT_OK)
  @HostAndPathAnno( route_login )
  suspend fun toLoginView(
    @UiContext context: Context,
  ): Intent

}

普通跳转 -- 跳转去登录 -- 跳转只要匹配 resultCode

普通方式

Router.with(context = context)
  .hostAndPath(hostAndPath = route_login)
  .requestCodeRandom()
  // 默认匹配 Activity.RESULT_OK
  .forwardForResultCodeMatch {
    // 这里就是匹配成功的回调
  }

Router.with(context = context)
  .hostAndPath(hostAndPath = route_login)
  .requestCodeRandom()
  // 默认匹配 Activity.RESULT_OK
  .resultCodeMatchAwait()

声明式方式

@RouterApiAnno
interface RouterApi {

  @RequestCodeAnno // 不填写表示框架自动生成一个
  // 表示想要匹配 resultCode
  @NavigateAnno(resultCodeMatch = Activity.RESULT_OK)
  @HostAndPathAnno( route_login )
  fun toLoginView(
    @UiContext context: Context,
    callback: () -> Unit,
  )

  // suspend 方法

  // 不填写表示框架自动生成一个
  @RequestCodeAnno
  // 表示想要匹配 resultCode
  @NavigateAnno(resultCodeMatch = Activity.RESULT_OK)
  @HostAndPathAnno( route_login )
  suspend fun toLoginView(
    @UiContext context: Context,
  )

}

普通跳转 -- 跳转去订单详情 -- 进入前完成登录并且传递参数

这里创建一个拦截器, 用于完成登录的拦截

@InterceptorAnno(value = "loginInterceptor")
class LoginInterceptor : RouterInterceptor {

  override suspend fun intercept(chain: RouterInterceptor.Chain): RouterResult {
    if(没登录) {
      val context = chain.request().rawAliveContext!!
      Router.with(context = context)
        .hostAndPath(hostAndPath = route_login)
        .requestCodeRandom()
        // 默认匹配 Activity.RESULT_OK
        .resultCodeMatchAwait()
    }
    return chain.proceed(request = chain.request())
  }

}

普通方式

Router.with(context = context)
  .hostAndPath(hostAndPath = route_order_detail)
  .putString(key = "orderId", value = "xxxxxxx")
  // 使用登录拦截器完成登录
  .interceptors(LoginInterceptor::class)
  .forword()

Router.with(context = context)
  .hostAndPath(hostAndPath = route_order_detail)
  .putString(key = "orderId", value = "xxxxxxx")
  // 使用登录拦截器完成登录
  .interceptorNames("loginInterceptor")
  .forword()

声明式方式

@RouterApiAnno
interface RouterApi {

  @UseInterceptorAnno(classes = [LoginInterceptor::class])
  @HostAndPathAnno( route_order_detail )
  fun toOrderDetail(
    @UiContext context: Context,
    @ParameterAnno orderId: String,
  )

  @UseInterceptorAnno(names = ["loginInterceptor"])
  @HostAndPathAnno( route_order_detail )
  fun toOrderDetail(
    @UiContext context: Context,
    @ParameterAnno("orderId") orderId_xxxxxx: String,
  )

}

更多的用法. 多看看 Demo 中的 SampleApi 文件.