Android路由机制下Tab页跳转解决方案

        使用过路由框架的人应该知道,使用url的形式进行页面跳转是一种很不错的方式。在不需要import对应页面引用的情况下,通过url可以打开页面,并且可以进行传递参数,设置flag等等操作。但是当一个页面中有viewpager+fragment或者fragmelayout+Fragments的情况下,我们如何通过url进行精准的Tab页跳转呢?

1.涉及框架

        路由框架(ARouter)。我现在的项目使用了阿里的Arouter,其他的路由框架也是可以的,跳转Tab页也只是一个思路而已。

2.路由降级策略

        在基于路由框架的项目中,一般情况下,当遇到有Tab页的页面,若要指定跳转对应的Tab页的话,我们可能需要给页面传递一个参数,来告诉页面我们要跳转的具体页面。在页面中,会根据传递过来的参数,如int类型参数,把参数作为碎片集合的角标去把对应tab页展示出来。这样一来的话,就无法仅通过一个单一的url来进行精准的跳转,还需要伴随一个参数才可以。

        我的思路呢,是仅仅只通过url就可以精确定位要跳转的Tab页,那么这里就必须要路由框架的降级策略来处理。何为降级策略?

        使用系统自带的StartActivity()启动后就无法插手其中任何环节了,只能交给系统管理,这就导致了在跳转失败的情况下无法降级,而是会直接抛出运营级的异常,甚至导致崩溃,这个给用户的感觉就不是很好。ARouter的降级策略就允许我们在自定义降级服务,在跳转失败的时候可以自行处理,比如可以加载H5页面来处理这种错误情况。(此段为转载内容,详细可以通过链接来查看。链接:https://www.jianshu.com/p/008bd4fa9dc0

        也就是通过url并未找到对应逻辑的情况下会走路由的降级处理,这也是思路的关键。我们先看一下不通过降级策略进行Tab页展示的调用方式和弊端。

ARouter.getInstance().build("/testModule/dataBaseActivity").withInt("tab_index",2).navigation();

        通过常规方式进行Tab页跳转,需要url和tab_index两个参数才可以进行跳转。这样多了一步withInt的数据传递,这个倒是不痛不痒,关键点是这样不太适合项目的灵活配置。我的项目呢,因为有多种角色,每种角色在页面上会有不同的权限,所以呢,我们的页面跳转url都是由后台传递给前端的,前端会在数据库存储和刷新不同权限的不同跳转规则。又因为有的页面就是一个普通的单页面,但是有的页面是有Tab的页面,为了在权限数据里能统一,就只以url作为唯一的跳转信息。这样一来,整个移动端的权限就可以通过后台进行管理,很灵活和方便。

        算是吐槽了一下常规方式,赞了一下我的方式吧,惭愧惭愧。也有可能我还没有深挖到路由框架的可以实现Tab跳转机制,如有了解的朋友,可以告诉我哈。

        好,下面我就通过代码的方式来讲解一下如何通过路由降级策略来进行Tab页的跳转。

        首先我们需要创建降级策略类,实现DegradeService接口。DegradeService是ARouter的一个接口,继承于IProvider。

看注释Provide degrade service for router,you can do something when route has lost.也就是当路由失败的时候会走这里的逻辑。

/**
 * Provide degrade service for router, you can do something when route has lost.
 *
 * @author Alex <a href="mailto:[email protected]">Contact me.</a>
 * @version 1.0
 * @since 2016/9/22 14:51
 */
public interface DegradeService extends IProvider {

    /**
     * Router has lost.
     *
     * @param postcard meta
     */
    void onLost(Context context, Postcard postcard);
}

        创建DegradeServiceImpl类并实现DegradeService。

@Route(path = "/service/DegradeServiceImpl")
public class DegradeServiceImpl implements DegradeService {
    @Override
    public void onLost(Context context, Postcard postcard) {
        
    }

    @Override
    public void init(Context context) {

    }
}

        创建完毕之后,我来讲一下,如何只通过url来确定要跳转的页面。一般情况下,页面的url一般都为“/app/TestPage”,那么在url中加一点东西。比如有个带TAb页的页面,共有三个Tab,那么可以定义出三个url来,“/app/TestPage#0”,"/app/TestPage#1","/app/TestPage#2"。当然,带有Tab页的页面的url还是“/app/TestPage”。还是上一部分代码吧。

带有Tab页的activity的url为“/app/TestPage”。index为接收角标的成员变量,changePage用于根据角标进行Tab页展示。

@Route(path = "/app/TestPage")
public class TestActivity extends BaseActivity {
        @AutoWired(name = "index")
        public int index;

        //输入角标index,跳转到对应Page
        public void changePage(int index){
               ......
        }

    准备好了之后,我们就需要做一下降级策略类中的逻辑,在onLost方法中。当使用Arouter对“/app/TestPage#0”,"/app/TestPage#1","/app/TestPage#2"等url进行navigation时,框架会发现并没有这几个url的定义,所以必然会执行路由降级策略,因为路由未找到,所以会执行onLost方法,那么只需要在onLost中对url做一个拆分,用常规逻辑跳过去,就可以实现仅有url的情况下也可以跳转到对应页面的对应Tab页。

        首先获取到执行的url,然后判断url中是否有“#”,如果有,说明此url就是要跳转Tab页的,把url以“#”拆分开来,前一部分就是对应页面的url,后一部分作为一个角标参数来进行一个传参,然后重新执行这个新路由,便实现了url跳转Tab页。

    @Override
    public void onLost(Context context, Postcard postcard) {
        String path = postcard.getPath();
        // path 为空或不包含#号,不做处理
        if (TextUtils.isEmpty(path)){
            return;
        }
        if (!path.contains("#")){
            return;
        }
        // 包含 #,如 /manage/event/eventmanage#tobehandle
        // 需要把 # 号后的部分当作参数传递
        String[] str = path.split("#");
        Postcard myPostcard = ARouter.getInstance().build(str[0]);
        for (int i = 1; i < str.length; i++) {
            if (!TextUtils.isEmpty(str[i])) {
                myPostcard.withString("index", str[i]);
            }
        }
        myPostcard.navigation();
    }
        开发者在使用的时候,就不需要再传参了,只需要使用url就可以了。这样一来,后台服务器也可以根据url来管理移动端所有页面的跳转了,很方便。希望能够帮助到你。

猜你喜欢

转载自blog.csdn.net/lianwa88/article/details/79994013