Commit de967f1c by tanghuan

ios手势操作返回

1 parent 6b0f058e
...@@ -17,7 +17,6 @@ import 'package:dio/dio.dart'; ...@@ -17,7 +17,6 @@ import 'package:dio/dio.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fluwx/fluwx.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
...@@ -200,7 +199,6 @@ class WebState extends Equatable { ...@@ -200,7 +199,6 @@ class WebState extends Equatable {
class WebCubit extends Cubit<WebState> with WidgetsBindingObserver { class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
late final MessageDispatcher _dispatcher; late final MessageDispatcher _dispatcher;
late final WebViewController _controller; late final WebViewController _controller;
late final Fluwx _fluwx;
HttpServer? _server; HttpServer? _server;
PlayerService? _playerService; PlayerService? _playerService;
RecorderService? _recorderService; RecorderService? _recorderService;
...@@ -255,8 +253,7 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver { ...@@ -255,8 +253,7 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
} }
} catch (e) { } catch (e) {
emit(state.copyWith(isUpgrading: false)); emit(state.copyWith(isUpgrading: false));
print('升级检测处理失败'); debugPrint('升级检测处理失败 $e');
print(e);
} }
// 消息处理器 // 消息处理器
...@@ -275,13 +272,17 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver { ...@@ -275,13 +272,17 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
_readH5ShowVersion(); _readH5ShowVersion();
// 初始化其它一些属性 // 初始化其它一些属性
_fluwx = getIt.get<Fluwx>();
_playerService = getIt.get<PlayerService>(); _playerService = getIt.get<PlayerService>();
_playerService?.sendResponse = _sendResponse; _playerService?.sendResponse = _sendResponse;
_recorderService = getIt.get<RecorderService>(); _recorderService = getIt.get<RecorderService>();
// 登录IM // 登录IM
_loginIM(); _loginIM();
// 针对ios系统,处理侧滑返回
if (Platform.isIOS) {
WebCubitHolder.register(this);
}
} }
Future<Map<String, String>> _getVersionConfig() async { Future<Map<String, String>> _getVersionConfig() async {
...@@ -361,8 +362,8 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver { ...@@ -361,8 +362,8 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
await _recorderService?.close(); await _recorderService?.close();
}, },
onPageFinished: (String url) async { onPageFinished: (String url) async {
print('onPageFinished--------------------------------->'); debugPrint('onPageFinished--------------------------------->');
print(url); debugPrint(url);
_controller.runJavaScript( _controller.runJavaScript(
'document.querySelector("meta[name=viewport]").setAttribute("content", "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no")', '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 { ...@@ -466,7 +467,7 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
_sendResponse(response); _sendResponse(response);
}, webCubit: this); }, webCubit: this);
} catch (e) { } catch (e) {
print('消息解析错误: $e'); debugPrint('消息解析错误: $e');
} }
} }
...@@ -1130,7 +1131,7 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver { ...@@ -1130,7 +1131,7 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
// 安全起见,执行一次关闭旧的server, // 安全起见,执行一次关闭旧的server,
_server?.close(); _server?.close();
} catch (e) { } catch (e) {
print('SocketException: $e'); debugPrint('SocketException: $e');
} }
emit(state.copyWith(testMsg: 'A ${DateTime.now()}')); emit(state.copyWith(testMsg: 'A ${DateTime.now()}'));
_server = await localServerService.restartLocalServer(); _server = await localServerService.restartLocalServer();
...@@ -1201,11 +1202,14 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver { ...@@ -1201,11 +1202,14 @@ class WebCubit extends Cubit<WebState> with WidgetsBindingObserver {
@override @override
Future<void> close() async { Future<void> close() async {
_server?.close(); _server?.close();
// _fluwx.removeSubscriber(_responseListener);
await _playerService?.close(); await _playerService?.close();
await _recorderService?.close(); await _recorderService?.close();
if (Platform.isIOS) {
WebCubitHolder.unregister();
}
// 移除观察者 // 移除观察者
WidgetsBinding.instance.removeObserver(this); 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/adv_page.dart';
import 'package:appframe/ui/pages/im_page.dart'; import 'package:appframe/ui/pages/im_page.dart';
import 'package:appframe/ui/pages/link_page.dart'; import 'package:appframe/ui/pages/link_page.dart';
...@@ -9,11 +12,13 @@ import 'package:appframe/ui/pages/scan_code_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_page.dart';
import 'package:appframe/ui/pages/setting/account_phone_page.dart'; import 'package:appframe/ui/pages/setting/account_phone_page.dart';
import 'package:appframe/ui/pages/web_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:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
final GoRouter router = GoRouter( final GoRouter router = GoRouter(
initialLocation: '/web', initialLocation: '/web',
observers: Platform.isIOS ? [AppRouteObserver()] : [],
routes: <RouteBase>[ routes: <RouteBase>[
GoRoute( GoRoute(
path: '/web', path: '/web',
...@@ -83,3 +88,72 @@ final GoRouter router = GoRouter( ...@@ -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:convert';
import 'dart:io';
import 'package:appframe/config/constant.dart'; import 'package:appframe/config/constant.dart';
import 'package:appframe/config/env_config.dart'; import 'package:appframe/config/env_config.dart';
import 'package:appframe/config/locator.dart'; import 'package:appframe/config/locator.dart';
import 'package:appframe/services/im_service.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:archive/archive.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
...@@ -17,6 +19,7 @@ void main() async { ...@@ -17,6 +19,7 @@ void main() async {
await setupLocator(); await setupLocator();
await _initH5Version(); await _initH5Version();
await _initImSdk(); await _initImSdk();
await _initIOSGesture();
runApp(const App()); runApp(const App());
} }
...@@ -60,3 +63,10 @@ Future<void> _initImSdk() async { ...@@ -60,3 +63,10 @@ Future<void> _initImSdk() async {
await getIt.get<ImService>().initSdk(); 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:appframe/bloc/link_cubit.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
...@@ -17,12 +19,7 @@ class LinkPage extends StatelessWidget { ...@@ -17,12 +19,7 @@ class LinkPage extends StatelessWidget {
create: (context) => LinkCubit(LinkState(loaded: false, url: url!, title: title ?? '')), create: (context) => LinkCubit(LinkState(loaded: false, url: url!, title: title ?? '')),
child: BlocConsumer<LinkCubit, LinkState>( child: BlocConsumer<LinkCubit, LinkState>(
builder: (ctx, state) { builder: (ctx, state) {
return PopScope( final scaffold = Scaffold(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
ctx.read<LinkCubit>().handleBack(ctx);
},
child: Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(state.title, style: TextStyle(color: Colors.white, fontSize: 18)), title: Text(state.title, style: TextStyle(color: Colors.white, fontSize: 18)),
centerTitle: true, centerTitle: true,
...@@ -37,7 +34,21 @@ class LinkPage extends StatelessWidget { ...@@ -37,7 +34,21 @@ class LinkPage extends StatelessWidget {
), ),
) )
: const Center(child: CircularProgressIndicator(color: Color(0xFF7691fa))), : 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) {}, listener: (context, state) {},
......
import 'dart:io';
import 'package:appframe/bloc/web_cubit.dart'; import 'package:appframe/bloc/web_cubit.dart';
import 'package:appframe/config/constant.dart'; import 'package:appframe/config/constant.dart';
import 'package:appframe/config/env_config.dart'; import 'package:appframe/config/env_config.dart';
import 'package:appframe/config/locator.dart'; import 'package:appframe/config/locator.dart';
import 'package:appframe/config/routes.dart'; import 'package:appframe/config/routes.dart';
import 'package:appframe/ui/widgets/tip_overlay_widget.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/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
...@@ -39,7 +39,8 @@ class WebPage extends StatelessWidget { ...@@ -39,7 +39,8 @@ class WebPage extends StatelessWidget {
} }
return BlocProvider( return BlocProvider(
create: (context) => WebCubit( create: (context) {
final webCubit = WebCubit(
WebState( WebState(
loginOpFlag: loginOpFlag, loginOpFlag: loginOpFlag,
sessionCode: sessionCode, sessionCode: sessionCode,
...@@ -48,15 +49,12 @@ class WebPage extends StatelessWidget { ...@@ -48,15 +49,12 @@ class WebPage extends StatelessWidget {
userType: userType, userType: userType,
stuId: stuId, stuId: stuId,
), ),
), );
return webCubit;
},
child: BlocConsumer<WebCubit, WebState>( child: BlocConsumer<WebCubit, WebState>(
builder: (ctx, state) { builder: (ctx, state) {
return PopScope( final scaffold = Scaffold(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
ctx.read<WebCubit>().handleBack();
},
child: Scaffold(
appBar: _buildAppBar(ctx, state), appBar: _buildAppBar(ctx, state),
endDrawer: _buildDrawer(ctx, state), endDrawer: _buildDrawer(ctx, state),
body: Stack( body: Stack(
...@@ -124,7 +122,22 @@ class WebPage extends StatelessWidget { ...@@ -124,7 +122,22 @@ class WebPage extends StatelessWidget {
], ],
) )
: null, : 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) { 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!