Flutter的副屏显示
最近一直在做Flutter项目,用来开发具有两块屏幕的收银机应用。在找遍了全网Flutter资料后发现,Flutter居然没有提供这样子的API,看来只能自己手工实现了。
POS收银机外型
由于副屏无需触屏幕交互,所以我打算利用 Android Presentation API 在副屏幕上显示个WebView,通过Flutter -> Native接口 -> 切换Web的Hash
来发送副屏切换命令。
Android端代码
副屏代码
/**
* 副屏
*/
public class AdPresentation extends Presentation {
Activity context;
XWebView mainWebView;
/**
* 全局变量
*/
public static AdPresentation globalInstance;
public AdPresentation(Context outerContext, Display display) {
super(outerContext, display);
if(outerContext instanceof Activity){
context = (Activity) outerContext;
}
globalInstance = this;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ad);
mainWebView = findViewById(R.id.MainWebView);
}
private void loadUrl(String hash){
context.runOnUiThread(()->{
String originUserAgent = mainWebView.getSettings().getUserAgentString();
mainWebView.getSettings().setUserAgentString(originUserAgent);
mainWebView.loadUrl(BuildConfig.PRESENTATION_URL+"#"+hash);
});
}
/**
* 切换页面
*/
public void switchHash(String hash){
loadUrl(hash);
}
}
Flutter控制副屏的插件代码
/**
* 副屏插件
*/
public class PresentationPlugin implements MethodChannel.MethodCallHandler {
private Context mContext;
//副屏幕
DisplayManager mDisplayManager;//屏幕管理类
Display mDisplay[];//屏幕数组
Presentation lastDisplayPresentation;//用于记录上次展示的副屏的界面
AdPresentation mPresentation;
private PresentationPlugin(Context context) {
mContext = context;
showPresentation();
}
public void showPresentation() {
mDisplayManager = (DisplayManager) MainActivity.globalInstance .getSystemService(Context.DISPLAY_SERVICE);
mDisplay = mDisplayManager.getDisplays();
if (mDisplay.length < 2) {
return;
}
new Handler().postDelayed(() -> {
mPresentation = new AdPresentation(MainActivity.globalInstance, mDisplay[1]);
mPresentation.show();
//延时取消,否则会闪动
new Handler().postDelayed(() -> {
if (lastDisplayPresentation != null) {
lastDisplayPresentation.dismiss();
lastDisplayPresentation = null;
}
lastDisplayPresentation = mPresentation;
}, 100);
}, 100);
}
public static void registerWith(PluginRegistry.Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "app/presentation");
channel.setMethodCallHandler(new PresentationPlugin(registrar.context()));
}
@Override
public void onMethodCall(MethodCall call, final MethodChannel.Result result) {
switch (call.method) {
case "switchHash":
String hash = call.argument("hash").toString();
if(mDisplay.length >= 2){
AdPresentation.globalInstance.switchHash(hash);
result.success("OK");
}else{
result.error("FAIL", "NO_PRESENTATION", null);
}
break;
default:
result.notImplemented();
break;
}
}
}
Flutter端
import 'dart:async';
import 'package:flutter/services.dart';
class PresentationPlugin {
static const MethodChannel _channel = const MethodChannel('app/presentation');
static Future<Null> switchHash({
String hash,
Function(String) callback,
}) async {
print('PresentationPlugin.swichHash:'+hash);
try {
final String resp = await _channel.invokeMethod('switchHash', {'hash': hash}); //切换副屏幕
if (callback != null) {
callback(resp);
}
} catch (e) {
print(e);
}
}
}
//调用切换
PresentationPlugin.switchHash(
hash:"/pages/Payment?payway=wx",
);
总结
如果不需要交互,WebView真的是非常不错的渲染载体。