Commit de967f1c by tanghuan

ios手势操作返回

1 parent 6b0f058e
......@@ -17,7 +17,6 @@ import 'package:dio/dio.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fluwx/fluwx.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
......@@ -200,7 +199,6 @@ class WebState extends Equatable {
class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
late final MessageDispatcher _dispatcher;
late final WebViewController _controller;
late final Fluwx _fluwx;
HttpServer? _server;
PlayerService? _playerService;
RecorderService? _recorderService;
......@@ -255,8 +253,7 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
}
} catch (e) {
emit(state.copyWith(isUpgrading: false));
print('升级检测处理失败');
print(e);
debugPrint('升级检测处理失败 $e');
}
// 消息处理器
......@@ -275,13 +272,17 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
_readH5ShowVersion();
// 初始化其它一些属性
_fluwx = getIt.get<Fluwx>();
_playerService = getIt.get<PlayerService>();
_playerService?.sendResponse = _sendResponse;
_recorderService = getIt.get<RecorderService>();
// 登录IM
_loginIM();
// 针对ios系统,处理侧滑返回
if (Platform.isIOS) {
WebCubitHolder.register(this);
}
}
Future<Map<String, String>> _getVersionConfig() async {
......@@ -361,8 +362,8 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
await _recorderService?.close();
},
onPageFinished: (String url) async {
print('onPageFinished--------------------------------->');
print(url);
debugPrint('onPageFinished--------------------------------->');
debugPrint(url);
_controller.runJavaScript(
'document.querySelector("meta[name=viewport]").setAttribute("content", "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no")',
......@@ -466,7 +467,7 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
_sendResponse(response);
}, webCubit: this);
} catch (e) {
print('消息解析错误: $e');
debugPrint('消息解析错误: $e');
}
}
......@@ -1130,7 +1131,7 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
// 安全起见,执行一次关闭旧的server,
_server?.close();
} catch (e) {
print('SocketException: $e');
debugPrint('SocketException: $e');
}
emit(state.copyWith(testMsg: 'A ${DateTime.now()}'));
_server = await localServerService.restartLocalServer();
......@@ -1201,11 +1202,14 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
@override
Future<void> close() async {
_server?.close();
// _fluwx.removeSubscriber(_responseListener);
await _playerService?.close();
await _recorderService?.close();
if (Platform.isIOS) {
WebCubitHolder.unregister();
}
// 移除观察者
WidgetsBinding.instance.removeObserver(this);
......
import 'dart:io';
import 'package:appframe/bloc/web_cubit.dart';
import 'package:appframe/ui/pages/adv_page.dart';
import 'package:appframe/ui/pages/im_page.dart';
import 'package:appframe/ui/pages/link_page.dart';
......@@ -9,11 +12,13 @@ import 'package:appframe/ui/pages/scan_code_page.dart';
import 'package:appframe/ui/pages/setting/account_page.dart';
import 'package:appframe/ui/pages/setting/account_phone_page.dart';
import 'package:appframe/ui/pages/web_page.dart';
import 'package:appframe/ui/widgets/ios_edge_swipe_detector.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
final GoRouter router = GoRouter(
initialLocation: '/web',
observers: Platform.isIOS ? [AppRouteObserver()] : [],
routes: <RouteBase>[
GoRoute(
path: '/web',
......@@ -83,3 +88,72 @@ final GoRouter router = GoRouter(
),
],
);
///
/// 只针对iOS使用
///
class AppRouteObserver extends NavigatorObserver {
@override
void didPush(Route route, Route? previousRoute) {
super.didPush(route, previousRoute);
if (route.settings.name == '/web') {
// push时,当前路由为 /web,代表 /web 路由被push进栈,展示web页面
// 设置手势监听回调
debugPrint("设置监听--------");
IosEdgeSwipeDetector.onEdgeSwipe(
() {
WebCubitHolder.instance?.handleBack();
},
);
} else if (previousRoute?.settings.name == '/web') {
// push时,前一个路由是 /web,代表是从web页进入此页面
// 将手势监听回调取消
debugPrint("取消监听--------");
IosEdgeSwipeDetector.dispose();
}
}
@override
void didPop(Route route, Route? previousRoute) {
super.didPop(route, previousRoute);
if (previousRoute?.settings.name == '/web') {
// Pop时, 前一个路由是/web,代表回到web页面
// 设置手势监听回调
debugPrint("设置监听--------");
IosEdgeSwipeDetector.onEdgeSwipe(
() {
WebCubitHolder.instance?.handleBack();
},
);
}
}
@override
void didRemove(Route route, Route? previousRoute) {
super.didRemove(route, previousRoute);
if (route.settings.name == '/web') {
// remove时, 当前路由为 /web, 代表 /web 路由被删除,展示的不是web页面
// 将手势监听回调取消
debugPrint("取消监听--------");
IosEdgeSwipeDetector.dispose();
}
}
}
///
/// 只针对iOS使用
///
class WebCubitHolder {
static WebCubit? instance;
static void register(WebCubit cubit) {
instance = cubit;
}
static void unregister() {
instance = null;
}
}
import 'dart:convert';
import 'dart:io';
import 'package:appframe/config/constant.dart';
import 'package:appframe/config/env_config.dart';
import 'package:appframe/config/locator.dart';
import 'package:appframe/services/im_service.dart';
import 'package:appframe/ui/widgets/ios_edge_swipe_detector.dart';
import 'package:archive/archive.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
......@@ -17,6 +19,7 @@ void main() async {
await setupLocator();
await _initH5Version();
await _initImSdk();
await _initIOSGesture();
runApp(const App());
}
......@@ -60,3 +63,10 @@ Future<void> _initImSdk() async {
await getIt.get<ImService>().initSdk();
}
}
Future<void> _initIOSGesture() async {
if (Platform.isIOS) {
// ios边缘滑动检测
await IosEdgeSwipeDetector.init();
}
}
import 'dart:io';
import 'package:appframe/bloc/link_cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
......@@ -17,12 +19,7 @@ class LinkPage extends StatelessWidget {
create: (context) => LinkCubit(LinkState(loaded: false, url: url!, title: title ?? '')),
child: BlocConsumer<LinkCubit, LinkState>(
builder: (ctx, state) {
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
ctx.read<LinkCubit>().handleBack(ctx);
},
child: Scaffold(
final scaffold = Scaffold(
appBar: AppBar(
title: Text(state.title, style: TextStyle(color: Colors.white, fontSize: 18)),
centerTitle: true,
......@@ -37,7 +34,21 @@ class LinkPage extends StatelessWidget {
),
)
: const Center(child: CircularProgressIndicator(color: Color(0xFF7691fa))),
),
);
if (Platform.isIOS) {
return scaffold;
}
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
if (didPop) {
return;
}
ctx.read<LinkCubit>().handleBack(ctx);
},
child: scaffold,
);
},
listener: (context, state) {},
......
import 'dart:io';
import 'package:appframe/bloc/web_cubit.dart';
import 'package:appframe/config/constant.dart';
import 'package:appframe/config/env_config.dart';
import 'package:appframe/config/locator.dart';
import 'package:appframe/config/routes.dart';
import 'package:appframe/ui/widgets/tip_overlay_widget.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
......@@ -39,7 +39,8 @@ class WebPage extends StatelessWidget {
}
return BlocProvider(
create: (context) => WebCubit(
create: (context) {
final webCubit = WebCubit(
WebState(
loginOpFlag: loginOpFlag,
sessionCode: sessionCode,
......@@ -48,15 +49,12 @@ class WebPage extends StatelessWidget {
userType: userType,
stuId: stuId,
),
),
);
return webCubit;
},
child: BlocConsumer<WebCubit, WebState>(
builder: (ctx, state) {
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
ctx.read<WebCubit>().handleBack();
},
child: Scaffold(
final scaffold = Scaffold(
appBar: _buildAppBar(ctx, state),
endDrawer: _buildDrawer(ctx, state),
body: Stack(
......@@ -124,7 +122,22 @@ class WebPage extends StatelessWidget {
],
)
: null,
),
);
// ios 不使用 PopScope
if (Platform.isIOS) {
return scaffold;
}
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
if (didPop) {
return;
}
ctx.read<WebCubit>().handleBack();
},
child: scaffold,
);
},
listener: (context, state) {
......
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
class IosEdgeSwipeDetector {
static const MethodChannel _channel = MethodChannel('ios_edge_swipe');
/// 初始化边缘滑动检测器
/// 调用原生iOS代码注册边缘滑动监听
static Future<void> init() async {
try {
await _channel.invokeMethod('initSwipeListener');
} catch (e) {
debugPrint('初始化边缘滑动监听失败: $e');
}
}
/// 注册边缘滑动事件回调
/// [onSwipeDetected] 当检测到边缘滑动时的回调函数
static void onEdgeSwipe(VoidCallback onSwipeDetected) {
_channel.setMethodCallHandler((call) async {
if (call.method == 'onEdgeSwipe') {
onSwipeDetected();
} else {
debugPrint('方法 ${call.method} 未实现');
}
});
}
/// 清理边缘滑动监听器
/// 在组件销毁时调用,防止内存泄漏
static void dispose() {
_channel.setMethodCallHandler(null);
}
}
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!