178 lines
5.1 KiB
Dart
Executable File
178 lines
5.1 KiB
Dart
Executable File
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:webview_flutter/webview_flutter.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:flutter_html/flutter_html.dart';
|
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
|
import '../../../widgets/kr_app_text_style.dart';
|
|
import '../controllers/kr_webview_controller.dart';
|
|
import '../../../services/api_service/api.dart';
|
|
import '../../../utils/kr_log_util.dart';
|
|
|
|
/// WebView 页面组件
|
|
class KRWebView extends GetView<KRWebViewController> {
|
|
const KRWebView({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
backgroundColor: Colors.transparent,
|
|
elevation: 0,
|
|
leading: IconButton(
|
|
icon: Icon(
|
|
Icons.arrow_back_ios,
|
|
size: 20.sp,
|
|
color: Theme.of(context).textTheme.bodyMedium?.color,
|
|
),
|
|
onPressed: () => Get.back(),
|
|
),
|
|
centerTitle: true,
|
|
title: Text(
|
|
controller.kr_title.value,
|
|
style: KrAppTextStyle(
|
|
color: Theme.of(context).textTheme.bodyMedium?.color,
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
),
|
|
body: _buildBody(),
|
|
);
|
|
}
|
|
|
|
/// 构建主体内容
|
|
Widget _buildBody() {
|
|
return Stack(
|
|
children: [
|
|
_buildContent(),
|
|
_buildLoadingIndicator(),
|
|
],
|
|
);
|
|
}
|
|
|
|
/// 构建内容组件
|
|
Widget _buildContent() {
|
|
if (controller.kr_url.contains(Api.kr_getSiteTos) ||
|
|
controller.kr_url.contains(Api.kr_getSitePrivacy)) {
|
|
return _buildProtocolContent();
|
|
} else {
|
|
return _buildWebView();
|
|
}
|
|
}
|
|
|
|
/// 构建协议内容
|
|
Widget _buildProtocolContent() {
|
|
return Obx(() {
|
|
if (controller.kr_isHtml.value) {
|
|
return SingleChildScrollView(
|
|
padding: EdgeInsets.all(16.w),
|
|
child: Html(
|
|
data: controller.kr_content.value,
|
|
style: {
|
|
'body': Style(
|
|
margin: Margins.all(0),
|
|
padding: HtmlPaddings.all(0),
|
|
fontSize: FontSize(14.sp),
|
|
color: Theme.of(Get.context!).textTheme.bodySmall?.color,
|
|
fontFamily: 'AlibabaPuHuiTi-Regular',
|
|
lineHeight: LineHeight(1.4),
|
|
),
|
|
'p': Style(
|
|
margin: Margins.only(bottom: 8.h),
|
|
),
|
|
'b': Style(
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
'i': Style(
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
'a': Style(
|
|
color: Colors.blue,
|
|
textDecoration: TextDecoration.underline,
|
|
),
|
|
},
|
|
shrinkWrap: true,
|
|
),
|
|
);
|
|
} else if (controller.kr_isMarkdown.value) {
|
|
return SingleChildScrollView(
|
|
padding: EdgeInsets.all(16.w),
|
|
child: MarkdownBody(
|
|
data: controller.kr_content.value,
|
|
styleSheet: MarkdownStyleSheet(
|
|
p: TextStyle(
|
|
fontSize: 14.sp,
|
|
color: Theme.of(Get.context!).textTheme.bodySmall?.color,
|
|
fontFamily: 'AlibabaPuHuiTi-Regular',
|
|
height: 1.4,
|
|
),
|
|
strong: TextStyle(
|
|
fontSize: 14.sp,
|
|
fontWeight: FontWeight.bold,
|
|
color: Theme.of(Get.context!).textTheme.bodySmall?.color,
|
|
fontFamily: 'AlibabaPuHuiTi-Regular',
|
|
height: 1.4,
|
|
),
|
|
em: TextStyle(
|
|
fontSize: 14.sp,
|
|
fontStyle: FontStyle.italic,
|
|
color: Theme.of(Get.context!).textTheme.bodySmall?.color,
|
|
fontFamily: 'AlibabaPuHuiTi-Regular',
|
|
height: 1.4,
|
|
),
|
|
a: TextStyle(
|
|
fontSize: 14.sp,
|
|
color: Colors.blue,
|
|
decoration: TextDecoration.underline,
|
|
fontFamily: 'AlibabaPuHuiTi-Regular',
|
|
height: 1.4,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
} else {
|
|
return SingleChildScrollView(
|
|
padding: EdgeInsets.all(16.w),
|
|
child: Text(
|
|
controller.kr_content.value,
|
|
style: TextStyle(
|
|
fontSize: 14.sp,
|
|
color: Theme.of(Get.context!).textTheme.bodySmall?.color,
|
|
fontFamily: 'AlibabaPuHuiTi-Regular',
|
|
height: 1.4,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
});
|
|
}
|
|
|
|
/// 构建 WebView 组件
|
|
Widget _buildWebView() {
|
|
return WebViewWidget(
|
|
controller: controller.kr_webViewController,
|
|
);
|
|
}
|
|
|
|
/// 构建加载指示器
|
|
Widget _buildLoadingIndicator() {
|
|
return Obx(
|
|
() => controller.kr_isLoading.value
|
|
? const Center(
|
|
child: CircularProgressIndicator(),
|
|
)
|
|
: const SizedBox.shrink(),
|
|
);
|
|
}
|
|
|
|
/// 显示错误提示
|
|
void _showErrorSnackbar(String title, String message) {
|
|
Get.snackbar(
|
|
title,
|
|
message,
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
);
|
|
}
|
|
}
|