# Flutter 常见问题
# 1. 小程序右上角的更多按钮里的菜单支持自定义吗?如果支持,要怎么实现?
答:支持。 不过,iOS和android里的实现不太一样,需要分别处理。
iOS
首先,创建一个flutter向原生工程通信的channel。
const toAppMessageChannel = MethodChannel("com.message.flutter_to_app");
然后,创建一个继承自AppletHandler的实现类。
class MyAppletHandler extends AppletHandler {
...
bool customCapsuleMoreButtonClick(String appId) {
// 返回true,代表要自定义更多视图;返回false,代表使用默认的更多视图
// 注意该代理方法仅针对iOS端生效,安卓端见常见问题列表。
// 这里通过channel发送事件给iOS工程的原生代码。
toAppMessageChannel.invokeMethod("showCustomMoreView", {"appId": appId});
return true;
}
...
}
然后,注册代理实现对象。
Mop.instance.registerAppletHandler(MyAppletHandler());
最后,在iOS原生工程里监听channel里的事件,处理弹出自定义更多视图的逻辑。
_channel = [FlutterMethodChannel methodChannelWithName:@"com.message.flutter_to_app" binaryMessenger:messenger];
[_channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
NSLog(@"收到Flutter消息:%@", call.method);
if ([call.method isEqualToString:@"showCustomMoreView"]) {
NSString *appId = call.arguments[@"appId"];
// 弹出自定义的更多视图
UIViewController *viewController = [[UIApplication sharedApplication] fat_topViewController];
UIAlertController *alertViewController = [UIAlertController alertControllerWithTitle:@"更多视图" message:appId preferredStyle:UIAlertControllerStyleActionSheet];
[alertViewController addAction:[UIAlertAction actionWithTitle:@"转发" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}]];
[alertViewController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}]];
[viewController presentViewController:alertViewController animated:YES completion:nil];
}
}];
android
- 首先,在安卓工程里新建一个application。
- 然后,AndroidManifest.xml里配置application的name。
- 再然后,在application的
onCreate
方法里注册实现代理的对象。 - 最后,重写更多按钮点击事件的方法即可。
public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
initProcessHandler();
}
private void initProcessHandler() {
if (!FinAppClient.INSTANCE.isFinAppProcess(this)) {
return;
}
FinAppProcessClient.INSTANCE.getAppletProcessApiManager().setAppletProcessHandler(new IAppletProcessHandler(){
@Override
public boolean onNavigationBarMoreButtonClicked(@NonNull Context context, @NonNull String appId) {
// 在这里弹出自定义的更多视图
new AlertDialog.Builder(context)
.setTitle("更多视图")
.setMessage(appId)
.setPositiveButton("菜单", null)
.setNegativeButton("取消", null)
.show();
// 返回true表示要自行处理更多视图;返回false表示使用默认的更多视图
return true;
}
});
}
}
# 2.公共UI如何支持国际化?
1、如果只是中英文切换,SDK默认支持只要修改如下配置(iOS、Android 均有效)。
需要在初始化SDK时,配置Config对象里的language
参数为LanguageType.English
或者LanguageType.Chinese
(简体中文)。
//多服务器配置
FinStoreConfig storeConfigA = FinStoreConfig(
"SDK key",
"SDK secret",
"服务器地址",
cryptType: "SM",
);
List<FinStoreConfig> storeConfigs = [storeConfigA];
Config config = Config(storeConfigs);
config.language = LanguageType.English;
2、如果需要设置其他语言的话Android 和 iOS的设置会不一样,另外还得自备国际化文本资源。
Android 如下:
FinStoreConfig storeConfigA = FinStoreConfig(
"SDK key",
"SDK secret",
"服务器地址",
cryptType: "SM",
);
List<FinStoreConfig> storeConfigs = [storeConfigA];
Config config = Config(storeConfigs);
/// 语言列表字符串可以参考:https://uutool.cn/info-i18n/ 或者Java类 【java.util.Locale】有说明
config.localeLanguage = "zh_TW"; //繁体中文
备注:
- 此配置的优先级会高于上面的配置【config.language】 仅仅Android 平台有效。
- 另外SDK内部只内置了简体中文和英文的国际化资源文本,其他语言的得自行添加。参考文档:Android SDK做国际化 (opens new window)
- 工程内都有对应的Android工程项目,参考Android SDK的国际化配置即可;新增的语言配置也是放在对应的Android工程的相关目录下。
iOS如下:
自定义国际化语言使用的 key 需要从 FinApplet.framework
中拿到,路径为: FinApplet.framework/FinApplet.bundle/zh-Hans.lproj/Localizable.strings
以日语为例,在 iOS 开发工程创建国际化文件目录 jp.lproj
,并在目录下创建 Localizable.strings
文件,将我们FinApplet.framework
内部的 key 粘贴到这个文件下并进行翻译。
配置代码如下:
FinStoreConfig storeConfigA = FinStoreConfig(
"SDK key",
"SDK secret",
"服务器地址",
cryptType: "SM",
);
List<FinStoreConfig> storeConfigs = [storeConfigA];
Config config = Config(storeConfigs);
if (Platform.isIOS) {
// 直接将 jp.lproj 放在工程目录下(也就是 mainBundle 下),初始化方式如下
config.customLanguagePath = "jp.lproj";
// 或者,如果将 jp.lproj 文件存放在某个自定义 bundle 下,则需要带上相对路径
// config.customLanguagePath = "XXX.bundle/jp.lproj";
}
# 3.如果自定义小程序的loading页面?
首先,需要分别在iOS和安卓工程创建一个自定义的的loading视图,分别需要继承或实现自FATBaseLoadingView
和 IFinAppletLoadingPage
。
这里可以参考设置加载页UI
然后,在flutter-sdk初始化时配置各自的自定义loading视图的class。
:
注意
两端设置自定义的loading视图的配置项不一样!!
// iOS
...
Config config = Config(storeConfigs);
config.baseLoadingViewClass = "LoadingView";
...
// android
...
UIConfig uiconfig = UIConfig();
uiconfig.loadingLayoutCls = "com.finogeeks.mop_example.CustomLoadingPage";
# 4.Flutter 工程中如何集成扩展SDK?
FinClip 的Flutter-sdk 是 mop,mop-sdk 默认是依赖了安卓和iOS SDK 的核心SDK和基础库扩展SDK。
// mop依赖的iOS SDK:
FinApplet
FinAppletExt
// mop依赖的安卓SDK:
finapplet
plugins
当我们flutter 工程里的小程序还需要其他扩展SDK中的api或者组件时,我们可以在安卓和iOS 工程中添加其他扩展SDK的依赖即可。 iOS 在根目录下的ios文件夹下的podfile中添加需要的扩展SDK,示例:
// 高德地图实现的map组件和定位api
pod 'FinAppletGDMap', '2.42.8-alpha20231127v04'
// 蓝牙相关的api
pod 'FinAppletBLE', '2.42.8-alpha20231127v04'
// 联系人api
pod 'FinAppletContact', '2.42.8-alpha20231127v04'
// 粘贴板 api
pod 'FinAppletClipBoard', '2.42.8-alpha20231127v04'
// live组件
pod 'FinAppletLive', '2.42.8-alpha20231127v04'
// 分享扩展SDK
pod 'FinAppletShare', '2.42.8-alpha20231127v04'
// 微信扩展SDK
pod 'FinAppletWXExt', '2.42.8-alpha20231127v04'
// 日历 api
pod 'FinAppletCalendar', '2.42.8-alpha20231127v04'
关于iOS 各个扩展SDK中的包含小程序api以及扩展SDK更详细的描述,见 iOS 扩展SDK
Android 在根目录下的android/app文件夹下的build.gradle中添加扩展SDK,示例:
implementation "com.finogeeks.mop:live:${sdk_version}"
// 地图组件和定位api
implementation "com.finogeeks.mop:map:${sdk_version}"
// 蓝牙api
implementation "com.finogeeks.mop:bluetooth:${sdk_version}"
// 通讯录api
implementation "com.finogeeks.mop:contact:${sdk_version}"
// 粘贴板api
implementation "com.finogeeks.mop:clipboard:${sdk_version}"
// video 的投屏扩展SDK
implementation "com.finogeeks.mop:cast:${sdk_version}"
// 分享扩展SDK
implementation "com.finogeeks.mop:share:${sdk_version}"
// xlog日志扩展SDK
implementation "com.finogeeks.mop:xlog:${sdk_version}"
// 日历api
implementation "com.finogeeks.mop:calendar:${sdk_version}"
关于Android 各个扩展SDK中的包含小程序api以及扩展SDK更详细的描述,见 Android 扩展SDK