目录
前言
本来ARouter的内容已经分析完了,到第四篇就应该结束了,但是今天上github查看版本发现更新很频繁,对比了下代码,除了细微处的修改,主要还是增加了几个非常有用的功能,所以打算继续深入研究下。
转场动画
在Postcard中增加了两个方法
public Postcard withTransition(int enterAnim, int exitAnim) { this.enterAnim = enterAnim; this.exitAnim = exitAnim; return this; } /** * Set options compat * * @param compat compat * @return this */ @RequiresApi(16) public Postcard withOptionsCompat(ActivityOptionsCompat compat) { if (null != compat) { this.optionsCompat = compat.toBundle(); } return this; }
使用方法和设置参数类似
// 转场动画(常规方式)ARouter.getInstance() .build("/test/activity2") .withTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom) .navigation(this);// 转场动画(API16+)ActivityOptionsCompat compat = ActivityOptionsCompat. makeScaleUpAnimation(v, v.getWidth() / 2, v.getHeight() / 2, 0, 0);// ps. makeSceneTransitionAnimation 使用共享元素的时候,需要在navigation方法中传入当前Activity
使用原理也相对比较简单,
private Object _navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) { final Context currentContext = null == context ? mContext : context; switch (postcard.getType()) { case ACTIVITY:........... // Navigation in main looper. new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { if (requestCode > 0) { // Need start for result ActivityCompat.startActivityForResult((Activity) currentContext, intent, requestCode, postcard.getOptionsBundle()); } else { ActivityCompat.startActivity(currentContext, intent, postcard.getOptionsBundle()); } if ((0 != postcard.getEnterAnim() || 0 != postcard.getExitAnim()) && currentContext instanceof Activity) { // Old version. ((Activity) currentContext).overridePendingTransition(postcard.getEnterAnim(), postcard.getExitAnim()); }......... } });........}
在调用真正跳转的使用,直接传入动画就完成了。
Fragment支持
在之前的版本(前面博文中分析的)中,ARouter是不支持Route Fragment的。如今,在RouteProcessor中添加了对Fragment的支持
if (types.isSubtype(tm, fragmentTm) || types.isSubtype(tm, fragmentTmV4)) { logger.info(">>> Found fragment route: " + tm.toString() + " <<<"); routeMete = new RouteMeta(route, element, RouteType.parse(FRAGMENT), null); }
和IProvider以及Service一样,没有和activity一样的Autowired参数map,这是可以理解的,因为Activity的autowired参数表的作用是列出所有需要被注入参数的类型,在使用uri跳转的时候,根据类型进行参数注入。由于frament是没有uri跳转的,所以同样不需要参数表。
于是当我们给Fragment添加上@Route注解之后,我们可以在Group文件中出现如下代码:
atlas.put("/test/fragment", RouteMeta.build(RouteType.FRAGMENT, BlankFragment.class, "/test/fragment", "test", null, -1, -2147483648));
然后在和activity类似,调用navigation,不过不同的是,activity会直接启动,而fragment会返回一个实例,如下:
case FRAGMENT: Class fragmentMeta = postcard.getDestination(); try { Object instance = fragmentMeta.getConstructor().newInstance(); if (instance instanceof Fragment) { ((Fragment) instance).setArguments(postcard.getExtras()); } else if (instance instanceof android.support.v4.app.Fragment) { ((android.support.v4.app.Fragment) instance).setArguments(postcard.getExtras()); } return instance; } catch (Exception ex) { logger.error(Consts.TAG, "Fetch fragment instance error, " + TextUtils.formatStackTrace(ex.getStackTrace())); }
调用默认构造函数创建实例,然后放入arguments。
Autowired类型扩展
增加了Autowired中 Parcelable对象和 普通对象支持。分别通过getParcelableExtra的方式注入和通过json2Object的方式注入。