flutter_kinetra/lib/kt_pages/kt_home/kt_search_page.dart
2025-09-23 15:09:18 +08:00

275 lines
9.2 KiB
Dart

import 'dart:collection';
import 'dart:convert';
import 'dart:io';
import 'package:flustars/flustars.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_kinetra/kt_pages/kt_routes.dart';
import 'package:flutter_kinetra/kt_utils/kt_string_extend.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart' hide ScreenUtil;
import 'package:get/get.dart';
import '../../../dio_cilent/kt_apis.dart';
import '../../../kt_utils/kt_keys.dart';
import '../../../kt_utils/kt_utils.dart';
import '../../../main.dart';
import '../../kt_widgets/kt_status_widget.dart';
class KtSearchPage extends StatefulWidget {
const KtSearchPage({super.key});
@override
SignInActivityPageState createState() => SignInActivityPageState();
}
class SignInActivityPageState extends State<KtSearchPage> with RouteAware {
InAppWebViewController? _webViewController;
late PullToRefreshController _webRefreshController;
late Map<String, String> _userData;
KtLoadStatusType loadingStatus = KtLoadStatusType.loading;
@override
void initState() {
super.initState();
_initUserData();
_initRefreshController();
}
void _initUserData() {
_userData = {
'time_zone': KtUtils.getTimeZoneOffset(DateTime.now()),
'type': Platform.isAndroid ? 'android' : 'ios',
'lang': 'en',
// 'theme': 'theme_7',
'token': SpUtil.getString(KtKeys.token) ?? '',
};
debugPrint('-----userData:$_userData');
}
_initRefreshController() {
_webRefreshController = PullToRefreshController(
settings: PullToRefreshSettings(enabled: true),
onRefresh: () async {
if (Platform.isAndroid) {
_webViewController?.reload();
} else if (Platform.isIOS) {
_webViewController?.loadUrl(
urlRequest: URLRequest(url: WebUri(KtApis.WEB_SITE_SEARCH)),
);
}
},
);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
routeObserver.subscribe(this, ModalRoute.of(context)! as PageRoute);
}
// 从别的路由回来
@override
void didPopNext() {
super.didPopNext();
_webViewController?.reload();
}
@override
void dispose() {
super.dispose();
_webViewController?.dispose();
}
// 处理传递的消息
void _handleWebMessage(String jsonS) async {
if (jsonS.isEmpty) return;
Map<String, dynamic>? webParams;
webParams = jsonDecode(jsonS);
if (webParams == null) {
debugPrint("没有获取到传递过来的参数");
return;
}
Get.toNamed(
KtRoutes.shortVideo,
arguments: {'shortPlayId': webParams['short_play_id']},
);
}
@override
Widget build(BuildContext context) {
return Container(
width: ScreenUtil().screenWidth,
height: ScreenUtil().screenHeight,
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight + 30.w),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('bg2.png'.ktIcon),
fit: BoxFit.fill,
),
),
child: Column(
children: [
_buildAppBar(context),
Expanded(
child: Stack(
children: [
InAppWebView(
pullToRefreshController: _webRefreshController,
initialSettings: InAppWebViewSettings(
cacheEnabled: false,
javaScriptEnabled: true,
alwaysBounceVertical: true,
allowsBackForwardNavigationGestures: true,
domStorageEnabled: false,
clearCache: true,
transparentBackground: true,
useShouldOverrideUrlLoading: false,
),
// 注入两个handler
initialUserScripts: UnmodifiableListView<UserScript>([
UserScript(
source: """
window.AndroidInterface = {
getUserInfo: function() {
return window.flutter_inappwebview.callHandler('getUserInfo');
},
js2app: function(jsonS) {
return window.flutter_inappwebview.callHandler('js2app',jsonS);
}
};
""",
injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START,
),
]),
onWebViewCreated: (controller) async {
_webViewController = controller;
_webViewController?.addJavaScriptHandler(
handlerName: 'getUserInfo',
callback: (_) => jsonEncode(_userData),
);
await _webViewController?.addWebMessageListener(
WebMessageListener(
jsObjectName: "openDetail",
allowedOriginRules: {"*"},
onPostMessage:
(message, sourceOrigin, isMainFrame, replyProxy) {
debugPrint('----callback--jsonS:$message');
if (message?.data != null) {
_handleWebMessage(message?.data);
}
},
),
);
await _webViewController?.loadUrl(
urlRequest: URLRequest(
url: WebUri(KtApis.WEB_SITE_SEARCH),
),
);
},
onLoadStart: (controller, url) {
setState(() {
loadingStatus = KtLoadStatusType.loading;
});
},
onLoadStop: (controller, url) async {
// await _webViewController?.evaluateJavascript(
// source: '''
// document.body.style.backgroundColor = "transparent"
// document.style.backgroundColor = "transparent"
// ''',
// );
if (Platform.isIOS) {
String userJsonStr = jsonEncode(_userData);
Future.delayed(const Duration(seconds: 1)).then((_) {
controller.evaluateJavascript(
source:
'''
if(typeof window.receiveDataFromNative === 'function') {
window.receiveDataFromNative($userJsonStr);
}
''',
);
});
} else if (Platform.isAndroid) {
await controller.evaluateJavascript(
source: """
window.AndroidInterface = {
getUserInfo: async function () {
return window.flutter_inappwebview.callHandler('getUserInfo');
},
};
""",
);
}
setState(() {
loadingStatus = KtLoadStatusType.loadSuccess;
});
_webRefreshController.endRefreshing();
},
onReceivedError: (controller, request, error) {
_webRefreshController.endRefreshing();
Future.delayed(const Duration(milliseconds: 100)).then((_) {
setState(() {
loadingStatus = KtLoadStatusType.loadFailed;
});
});
},
),
_buildWidget(),
],
),
),
],
),
);
}
Widget _buildAppBar(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: Image.asset('ic_back.png'.ktIcon, width: 10.w),
onPressed: () => Navigator.of(context).maybePop(),
),
Text(
'Search',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w500,
color: Colors.black,
),
),
Container(width: 24.w),
],
);
}
Widget _buildWidget() {
debugPrint('----loadStatus:$loadingStatus');
switch (loadingStatus) {
case KtLoadStatusType.loading:
return Center(child: CircularProgressIndicator());
case KtLoadStatusType.loadFailed:
return KtStatusWidget(
type: KtErrorStatusType.noNetwork,
onPressed: () {
_webViewController?.loadUrl(
urlRequest: URLRequest(url: WebUri(KtApis.WEB_SITE_SEARCH)),
);
},
);
case KtLoadStatusType.loadNoData:
return KtStatusWidget(
type: KtErrorStatusType.notFound,
onPressed: () {
_webViewController?.reload();
},
);
default:
return const SizedBox.shrink();
}
}
}