页面跳转相关

页面跳转相关(路由)

一、随时获取上一个页面的路径

背景:埋点为避免去从所有埋点里查找进入此页面前的上一个进入页面,希望直接知道此页面的上页面路径。

路由规范

字段 描述 示例
1 sourceFrom 从哪个环境过来
(如h5跳转到app)
appType/h5Type
2

1、无整屏显示的弹窗,即从任何弹窗进入记为从页面进入

二、优雅的自定义返回

背景:从页面进入弹窗(全局WebView)。弹窗和页面不在同一路由栈上,从而使得当页面返回的时候,需要自己判断返回到哪。

详见:优雅的自定义返回

三、一个不用重加载的WebView

背景:一个基于WebView的Cocos2d游戏,因为启动加载引擎会有3-5秒的加载时长。为了更好的游戏体验,希望启动后重新进入不用重新加载。

详见:一个不用重加载的WebView

四、游戏与app跳转交互优化调研

常见:web游戏,极小,游戏页独立存在

特殊:web游戏可以调到app页时候

关键策略:

1、调研游戏内容多网页共享方案
2、建立游戏测试页,提供后续方案验证基础
3、开发方案demo,进行游戏内容多网页实验
4、如果方案有效,后续进行含业务的完整方案梳理;则如果无效则进行其他方案调研

参考文档:《全局WebView》中的【多页面网页内容共享】

调研过程:

1、完成Flutter游戏测试页的建立,并通过尝试共享网页视图或控制器两种方式,进行游戏内容在多页面的共享测试。得出共享时候视图树会重绘,即网页会重新加载,从而无法达到整个跳转过程在同一路由栈下的正常跳转交互。

2、完成实现原生游戏测试页,并在原生上通过共享单例视图方式,进行游戏内容在多页面的共享测试。仍会出现在共享时候视图重绘操作。

3、后续预想方案

方案①游戏页面与其他网页一样常规的正常重新开辟。

优点:能使得整个跳转过程在同一路由栈下的正常跳转交互,享有系统的各种进出交互。

优化点:页面开辟时候,游戏加载慢。

方案②游戏使用唯一独立窗口,形如支付宝蚂蚁森林。需要从游戏内去app的其他页面时候,使用先缩小游戏窗口,到一个悬浮按钮,再弹出目标页面。

存在现象:从目标页再进游戏的时候需要从悬浮按钮进入。

路由解析详见 路由规范(含点击属性规范))

使用WebUrl解析的方法

1
2
3
4
5
6
7
8
// 解析方法如下:
/// 获取指定web地址的所有参数
static Map<String, dynamic>? getAllParamsFromWebUrl(String webUrl, {bool paramToObjectIfOK = false});

/// 将字符串value按需求转成 string 或者 object(如果可以转的情况下)
static dynamic getValueFromWebParamValueString(String value, {bool paramToObjectIfOK = false});

// 构造方法如下:

解析方法详细内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import 'dart:convert';

import 'package:flutter/foundation.dart';

class WebUrlUtil {
/// 获取指定web地址的所有参数
///
/// [webUrl]:要获取参数的地址。
///
/// [paramToObjectIfOK]:一个布尔值,指示是否将参数值转换为对象(如果可能)。默认为false。
///
/// 返回包含地址参数的Map对象,其中参数名作为键,参数值作为值。
///
/// 例如:https://www.baidu.com/?a=1&b=2
/// 返回:{a: 1, b: 2}
static Map<String, dynamic>? getAllParamsFromWebUrl(
String webUrl, {
bool paramToObjectIfOK = false,
}) {
var paramStartIndex = webUrl.indexOf('?');
if (paramStartIndex == -1) {
return null;
}

Map<String, dynamic> paramMap = {};
var str = webUrl.substring(paramStartIndex + 1);
var strs = str.split('&');

for (var i = 0; i < strs.length; i++) {
var keyValueComponent = strs[i].split('=');
var key = keyValueComponent[0];
String value = keyValueComponent[1];
dynamic element = getValueFromWebParamValueString(
value,
paramToObjectIfOK: paramToObjectIfOK,
);

paramMap[key] = element;
}

return paramMap;
}

/// 将字符串value按需求转成 string 或者 object(如果可以转的情况下)
///
/// [value]:要处理的参数的值。
///
/// [paramToObjectIfOK]:一个布尔值,指示是否将参数值转换为对象(如果可能)。默认为false。
///
/// 返回参数值的处理结果。
static dynamic getValueFromWebParamValueString(
String value, {
required bool paramToObjectIfOK,
}) {
try {
value = Uri.decodeComponent(value);
} catch (error) {
// value = value;
debugPrint("不用解码");
}

if (paramToObjectIfOK != true) {
return value;
}

dynamic element; // 如果 json.decode 成功,返回类型会变化,所以需另声明变量
try {
element = json.decode(value);
} catch (error) {
element = value;
}
return element;
}
}

构造方法详细内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import 'dart:convert';

import 'package:flutter/foundation.dart';

class WebUrlUtil {
static String addH5CustomParams(
String newString,
Map<String, dynamic> h5Params,
) {
for (String h5ParamKey in h5Params.keys) {
var h5ParamValue = h5Params[h5ParamKey]; // 类型不一定是String
if (h5ParamValue == null) {
continue;
}
late String h5ParamEncodeValue;
if (h5ParamValue is String) {
// h5ParamEncodeValue = h5ParamValue;
h5ParamEncodeValue =
Uri.encodeComponent(h5ParamValue); // 要编码,否则即使是字符串,但是含中文时候,也会出错
} else {
// String h5ParamParamString = h5ParamValue.toString();
// String h5ParamParamString =
// FormatterUtil.convert(h5ParamValue, 0); // 使用此行来修复json字符串没有引号的问题
String h5ParamParamString = jsonEncode(
h5ParamValue); // 使用此行来修复json字符串没有引号的问题,且避免使用FormatterUtil.convert时候的换行问题
h5ParamEncodeValue = Uri.encodeComponent(
h5ParamParamString); // 要编码,否则url,在app中的webView无法识别(虽然在goole chrome或safari上可以识别)
}

String extraString = "$h5ParamKey=$h5ParamEncodeValue";
if (newString.contains('?')) {
newString += "&$extraString";
} else {
newString += "?$extraString";
}
}
return newString;
}
}

End