webview_render.dart 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_riverpod/flutter_riverpod.dart';
  3. import 'package:webview_flutter/webview_flutter.dart';
  4. import '../services/api_service.dart';
  5. import '../providers/app_provider.dart';
  6. import '../models/problem.dart';
  7. /// 题目预览 Widget — WebView 渲染服务端 HTML+MathML(Android)
  8. class ProblemPreview extends ConsumerStatefulWidget {
  9. final Problem problem;
  10. final bool showAnswer;
  11. const ProblemPreview({super.key, required this.problem, this.showAnswer = true});
  12. @override
  13. ConsumerState<ProblemPreview> createState() => _ProblemPreviewState();
  14. }
  15. class _ProblemPreviewState extends ConsumerState<ProblemPreview> {
  16. WebViewController? _controller;
  17. @override
  18. void initState() {
  19. super.initState();
  20. _initController();
  21. }
  22. @override
  23. void didUpdateWidget(ProblemPreview oldWidget) {
  24. super.didUpdateWidget(oldWidget);
  25. if (oldWidget.problem.id != widget.problem.id || oldWidget.showAnswer != widget.showAnswer) {
  26. _initController();
  27. }
  28. }
  29. void _initController() {
  30. _controller = WebViewController()
  31. ..setJavaScriptMode(JavaScriptMode.unrestricted);
  32. _loadContent();
  33. }
  34. Future<void> _loadContent() async {
  35. final api = ref.read(apiServiceProvider);
  36. final baseUrl = api.baseUrl ?? '';
  37. final token = api.token ?? '';
  38. final answerParam = widget.showAnswer ? 'true' : 'false';
  39. final viewUrl = '$baseUrl/api/problems/${widget.problem.id}/view'
  40. '?include_answer=$answerParam&token=$token';
  41. _controller?.loadRequest(Uri.parse(viewUrl));
  42. }
  43. @override
  44. Widget build(BuildContext context) {
  45. if (_controller == null) {
  46. return const Center(child: CircularProgressIndicator());
  47. }
  48. return WebViewWidget(controller: _controller!);
  49. }
  50. }