go() 有如上几个重载方法,如果是在Fragment中发起startActivityForResult 路由操作,切记传当前fragment实例哦!不然在fragment中是接受不到回调的。
- 添加跳转动画
// 1. 基础动画
Router.build(uri).anim(enter, exit).go(this);
// 2. 转场动画ActivityOptions
Router.build(uri).activityOptions(options).go(this);
- 获取目标页面
// 1. 获取intent,然后可以操作intent
Intent intent = Router.build(uri).getIntent(context);
// 2. 获取fragment,然后可以将该fragment添加到Activity中
Fragment fragment = (Fragment) Router.build(uri).getFragment(context);
- 全局拦截器
// 1. 添加全局拦截器
Router.addGlobalInterceptor(routeInterceptor);
// 2. 跳过全局拦截器
Router.build(uri).skipInterceptors().go(this);
- 添加拦截器
拦截器是Router 的功能之一,作用就是在执行路由之前判断是否需要拦截该次路由请求。比如可以在拦截器中做登录状态判断。
// 定义拦截器(通过注解)
@Interceptor("SampleInterceptor")
public class SampleInterceptor implements RouteInterceptor {
@Override
public boolean intercept(Context context, @NonNull Uri uri, @Nullable Bundle extras) {
// 返回true表示拦截当前路由
return true;
}
}
// 定义拦截器(通过代码)
Router.handleInterceptorTable(new InterceptorTable() {
@Override
public void handle(Map<String, Class<? extends RouteInterceptor>> map) {
map.put("SampleInterceptor", SampleInterceptor.class);
}
});
// 应用拦截器(通过注解)
@Route(value = "test", interceptors = "SampleInterceptor")
public class TestActivity extends AppCompatActivity {
...
}
// 应用拦截器(通过代码)
Router.handleTargetInterceptors(new TargetInterceptors() {
@Override
public void handle(Map<Class<?>, String[]> map) {
map.put(TestActivity.class, new String[]{"SampleInterceptor"});
}
});
- 自定义路由
除了可以使用注解来添加路由外(上面步骤2介绍的方式),还可以通过代码手动控制路由表。
// 动态添加路由表
Router.handleRouteTable(new RouteTable() {
@Override
public void handle(Map<String, Class<?>> map) {
map.put("dynamic1", TestActivity.class);
map.put("dynamic2", TestFragment.class);
...
}
});
该方式与注解没有冲突,可以同时使用。
- 路由匹配规则
该功能是Router 最大的特色功能,不同于其他框架,Router 并没有规定路由的写法规则,而是抽象出Matcher 的概念,交给用户去控制。但是Router 仍然内置了4个常用的Matcher 。
MatcherRegistry
匹配优先级从高到低依次是DirectMatcher 、SchemeMatcher 、ImplicitMatcher 和BrowserMatcher ,关于原理将在后序的原理篇中进行讲解。
假设有如下路由页面:
@Route({"user", "http://example.com/user"})
public class UserActivity extends Activity {
...
}
除了可以通过Router.build("test").go(this) 和Router.build("http://example.com/user").go(this) 打开UserActivity之外(DirectMatcher 命中),还可以通过Router.build("http://example.com/user?id=9527&status=0").go(this) 打开(通过SchemeMatcher 命中),并且自动帮你配置了Bundle参数,即:
@Route({"user", "http://example.com/user"})
public class UserActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
Bundle bundle = getIntent().getExtras();
String id = bundle.getString("id");
String status = bundle.getString("status");
}
}
Matcher 支持配置多个,会根据优先级依次进行匹配。
- 参数注入
上面讲了可以通过路由传递参数,然后在目标页面通过Bundle获取,其实这个过程也被Router 简化了。通过@InjectParam 注解可以为Activity或者Fragment的成员变量添加参数注入
@Route({"test", "http://example.com/test", "router://test"})
public class TestActivity extends AppCompatActivity {
@InjectParam
int id = 123;
@InjectParam(key = "status")
private String sts = "default"; // 不建议使用private修饰符
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
Router.injectParams(this); // 实现参数注入
}
}
-
@InjectParam 会在Bundle中取出对应key的值传给成员变量,默认key为变量名,也可以通过key=""属性指定
- 参数注入支持变量的默认值,目前支持默认值的变量类型有基本数据类型,String,CharSequence,其他类型的默认值都是null
- 变量不建议使用
private 修饰符,因为私有的变量会采用反射的方式注入参数
- 需要使用
Router.injectParams(this) 来实现最终的参数注入
Router 还有其他一些人性化的小功能,在这里就不一一介绍了,有问题可以在项目主页提issue。后续会给大家讲解一下背后的实现原理。
总结
Router 是一个十分小巧灵活的路由框架,代码设计也很优雅简洁,且完美支持组件化开发,目前仍在不断地迭代中,源码地址为https://github.com/chenenyu/Router,欢迎各位试用点评。
上一篇
下一篇
|