当我们进行一个页面跳转的时候,有哪些方法呢?
大家应该十分清楚,android原生提供了两种方案:隐式跳转和显式跳转。
这两种方案想必大家都非常清楚,这里就不一一举例了。而在组件化开发过程中,我们绝大多数都无法使用显式跳转来跳转页面。原因很简单,因为我们要跳转的页面可能不是在同一个library中,因此无法import对应activity的路径。因此,我们只能使用隐式跳转来完成需求。我们先不考虑使用类似arouter这样的路由框架(底层原理也是使用隐式跳转的)。
倘若,我们不想引入第三方框架,那么该如何实现对应的需求呢?
这里提供了两种方案
我们先看下项目的结构
我们来看下如何在不使用路由框架的情况下从Test1Activity跳转到TestActivity。
package com.brett.test1;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class Test1Activity extends AppCompatActivity {
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test1);
btn = findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
Class clazz = Class.forName("com.brett.test.TestActivity");
Intent intent = new Intent(Test1Activity.this,clazz);
startActivity(intent);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
这种方法比较简单,我们拿到类的路径名,然后使用隐式跳转进行页面跳转即可。缺点是:类路径名不要写错,写错就GG了。
思路大概是这样:我们新建一个RecordPathManager类里面持有一个map来存储需要跳转的页面的类,然后在app模块的application方法把需要跳转的类添加进去,最后当我们要跳转页面时循环遍历该map找到对应的页面。
package com.brett.common.bean;
/**
* Created by Brett.li on 2022/6/22.
*/
public class PathBean {
private String path;
private Class clazz;
public PathBean(){}
public PathBean(String path, Class clazz) {
this.path = path;
this.clazz = clazz;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public Class getClazz() {
return clazz;
}
public void setClazz(Class clazz) {
this.clazz = clazz;
}
}
package com.brett.common;
import com.brett.common.bean.PathBean;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Brett.li on 2022/6/22.
*/
public class RecordPathManager {
private static Map<String, List<PathBean>> maps = new HashMap<>();
public static void addGroupInfo(String groupName,String pathName,Class<?> clazz){
List<PathBean> list = maps.get(groupName);
if(null==list){
list = new ArrayList<>();
list.add(new PathBean(pathName,clazz));
maps.put(groupName,list);
}else{
maps.put(groupName,list);
}
}
public static Class<?> startTargetActivity(String groupName, String pathName){
List<PathBean>list = maps.get(groupName);
if(list == null){
return null;
}
for (PathBean pathBean:list){
if(pathName.equalsIgnoreCase(pathBean.getPath())){
return pathBean.getClazz();
}
}
return null;
}
}
package com.brett.myapplication;
import android.app.Application;
import com.brett.common.RecordPathManager;
import com.brett.test.TestActivity;
import com.brett.test1.Test1Activity;
/**
* Created by Brett.li on 2022/6/22.
*/
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
RecordPathManager.addGroupInfo("test","test_TestActivity", TestActivity.class);
RecordPathManager.addGroupInfo("test1","test1_Test1Activity", Test1Activity.class);
}
}
package com.brett.test1;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.brett.common.RecordPathManager;
public class Test1Activity extends AppCompatActivity {
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test1);
btn = findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Class<?> targetActivity = RecordPathManager.startTargetActivity("test","test_TestActivity");
startActivity(new Intent(Test1Activity.this,targetActivity));
}
});
}
}
这种方法的缺点是必须在application中添加类才行,不然就跳转不了了。
注意:最好新建一个模块单独封装RecordPathManager的逻辑,把该模块当作一个common模块,所有的模块都继承该模块,这样就很通用了。
像笔者这样:所有的模块都依赖common模块。