本篇為繼上片監聽返回鍵基礎下優化:
以下做返回鍵監聽兩種情況:
import 'package:fluttertoast/fluttertoast.dart'; //提示第三方插件
1. 單擊提示雙擊退出,雙擊時退出App
DateTime _lastPressedAt; //上次點擊時間
main.dart-MyApp中:
home: WillPopScope( // 監聽返回鍵Widget
onWillPop: () async { // 點擊返回鍵即觸發該事件
if (_lastPressedAt == null) { //首次點擊提示...信息
Fluttertoast.showToast(
msg: "雙擊退出程序...",
gravity: ToastGravity.BOTTOM,
timeInSecForIos: 1,
backgroundColor: Colors.grey[400],
textColor: Colors.white,
fontSize: ScreenUtil().setWidth(12),
);
}
if (_lastPressedAt == null || DateTime.now().difference(_lastPressedAt) > Duration(seconds: 1)) {
//兩次點擊間隔超過1秒則重新計時
_lastPressedAt = DateTime.now();
return false; // 不退出
}
return true; //退出
},
child: Pages(),
),
2. 單擊返回手機桌面,不退出App
main.dart文件
import 'package:flutter_smart_park/untils/android_back_desktop.dart';
home: WillPopScope(
onWillPop: () async {
AndroidBackTop.backDeskTop();
return false;
},
child: configProvide.token == '0' ? UserLogIn() : Pages(),
),
android_back_desktop.dart
import 'package:flutter/services.dart'; import 'package:flutter/material.dart';
class AndroidBackTop {
//初始化通信管道-設置退出到手機桌面
static const String CHANNEL = "android/back/desktop";
//設置回退到手機桌面
static Future<bool> backDeskTop() async {
final platform = MethodChannel(CHANNEL);
//通知安卓返回,到手機桌面
try {
final bool out = await platform.invokeMethod('backDesktop');
if (out) debugPrint('返回到桌面');
} on PlatformException catch (e) {
debugPrint("通信失敗(設置回退到安卓手機桌面:設置失敗)");
print(e.toString());
}
return Future.value(false);
}
}
需在MainActivity.java文件中添加配置:
import android.os.Bundle; import android.view.KeyEvent;import io.flutter.app.FlutterActivity; import io.flutter.plugins.GeneratedPluginRegistrant; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel;
public class MainActivity extends FlutterActivity {
//通訊名稱,回到手機桌面
private final String CHANNEL = "android/back/desktop";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if (methodCall.method.equals("backDesktop")) {
result.success(true);
moveTaskToBack(false); //是否關閉
}
}
}
);
}
}
附加: MethodChannel 本地訪問
在客戶端,MethodChannel(API)允許發送與方法調用相對應的消息。 在平台方 面,Android(API)上的MethodChannel和 iOS(API)上的 FlutterMethodChannel啟用接收方法調用並發回結果。
import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result;
申明變量CHANNEL,值與定義觸發事件包名相同,以上android_back_desktop為例:
private final String CHANNEL = "android/back/desktop";
在MethodChannel的中調用.setMethodCallHandler() 方法,需要一個MethodCallHandler 對象,是一個匿名內部類,有一個方法onMethodCall,在Flutter發送請求事,onMethodCall方法會執行。
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "android_back_desktop";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, Result result) {
}
}
);
}
}
onMethodCall方法中有兩個參數 MethodCall 和 result,MethodCall 中有關當前請求的信息,例如調用方法的名字changeLife;Result用於發送信息給Flutter。
在onMethodCall中判斷當前請求是否為changeLife,如果是通過result 的 success 返回信息:Life Changed .
public void onMethodCall(MethodCall methodCall, Result result) {
if (methodCall.method.equals("backDesktop")){
String message ="Life Changed";
result.success(message);
}
...
