cccc
This commit is contained in:
parent
3efb94a0d2
commit
1a6721cbb0
|
|
@ -28,7 +28,7 @@ class TestQuestionsImageInfo extends Object {
|
||||||
@JsonKey(name: 'actualImgHeight') // 实际展示图片高度
|
@JsonKey(name: 'actualImgHeight') // 实际展示图片高度
|
||||||
double actualImgHeight;
|
double actualImgHeight;
|
||||||
|
|
||||||
@JsonKey(name: 'remainingHeight') // 视图剩余高度 实际展示图片展示高度下 剩余高度.(若伟负数就是超出视图的高度值)
|
@JsonKey(name: 'remainingHeight') // 视图剩余高度 实际展示图片展示高度下 剩余高度.(若为负数就是超出视图的高度值)
|
||||||
double remainingHeight;
|
double remainingHeight;
|
||||||
|
|
||||||
@JsonKey(name: 'imageHeightOffsetStart') // 顶部坐标Y
|
@JsonKey(name: 'imageHeightOffsetStart') // 顶部坐标Y
|
||||||
|
|
@ -62,8 +62,8 @@ class TestQuestionsImageInfo extends Object {
|
||||||
}) {
|
}) {
|
||||||
// 图片已视图宽为基准,高度自适应可滑动 图片的实际宽高都需要乘此基准值
|
// 图片已视图宽为基准,高度自适应可滑动 图片的实际宽高都需要乘此基准值
|
||||||
scaleRatio = boxWidth / imageWidth;
|
scaleRatio = boxWidth / imageWidth;
|
||||||
actualImgWidth = imageWidth * scaleRatio;
|
actualImgWidth = imageWidth * scaleRatio * zoom;
|
||||||
actualImgHeight = imageHeight * scaleRatio;
|
actualImgHeight = imageHeight * scaleRatio * zoom;
|
||||||
remainingHeight = boxHeight - actualImgHeight;
|
remainingHeight = boxHeight - actualImgHeight;
|
||||||
imageHeightOffsetStart = remainingHeight / 2;
|
imageHeightOffsetStart = remainingHeight / 2;
|
||||||
imageHeightOffsetend = imageHeightOffsetStart + actualImgHeight;
|
imageHeightOffsetend = imageHeightOffsetStart + actualImgHeight;
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,7 @@ import 'package:flutter/material.dart';
|
||||||
VoidCallback debounce(Function func, [Duration delay = const Duration(milliseconds: 2000)]) {
|
VoidCallback debounce(Function func, [Duration delay = const Duration(milliseconds: 2000)]) {
|
||||||
Timer? timer;
|
Timer? timer;
|
||||||
target() {
|
target() {
|
||||||
if (timer?.isActive ?? false) {
|
|
||||||
timer?.cancel();
|
timer?.cancel();
|
||||||
}
|
|
||||||
timer = Timer(delay, () {
|
timer = Timer(delay, () {
|
||||||
func.call();
|
func.call();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -249,10 +249,53 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@swidget
|
||||||
|
Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic, HomeworkReviewState sateData) {
|
||||||
|
return Obx(() {
|
||||||
|
var imageVal = sateData.imageScale.value;
|
||||||
|
if (imageVal == null) return const SizedBox();
|
||||||
|
|
||||||
|
var studentQuestions = sateData.studentQuestions.value ?? [];
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
height: double.infinity,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color.fromRGBO(159, 159, 159, 0.97),
|
||||||
|
boxShadow: [BoxShadow(color: const Color.fromRGBO(46, 91, 255, 0.2), offset: Offset(0, 8.w), blurRadius: 1, spreadRadius: 2)],
|
||||||
|
),
|
||||||
|
child: GestureDetector(
|
||||||
|
onPanDown: (_) => sateData.panQuestView = false,
|
||||||
|
child: $QuestionNumberScrollView(
|
||||||
|
logic: logic,
|
||||||
|
sateData: sateData,
|
||||||
|
imageVal: imageVal,
|
||||||
|
studentQuestions: studentQuestions,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 试题题号视图
|
// 试题题号视图
|
||||||
@hwidget
|
@hwidget
|
||||||
Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic, HomeworkReviewState sateData) {
|
Widget $questionNumberScrollView(
|
||||||
|
BuildContext context, {
|
||||||
|
required HomeworkReviewLogic logic,
|
||||||
|
required HomeworkReviewState sateData,
|
||||||
|
required TestQuestionsImageInfo imageVal,
|
||||||
|
required List<StudentQuestions> studentQuestions,
|
||||||
|
}) {
|
||||||
|
var boxHeight = imageVal.boxHeight;
|
||||||
final scrollControllerNum = useScrollController(); // 试题题号区域
|
final scrollControllerNum = useScrollController(); // 试题题号区域
|
||||||
|
var usePiddingTop = useState<double>(logic.state.imageScaleZoom.value?.imageHeightOffsetStart ?? 0);
|
||||||
|
var useImageInfo = useState<TestQuestionsImageInfo?>(imageVal);
|
||||||
|
|
||||||
|
// var initScale = useState<double>(logic.state.initScale.value ?? 1);
|
||||||
|
|
||||||
|
// useValueChanged<double?, void>(logic.state.initScale.value, (_, __) {
|
||||||
|
// initScale.value = logic.state.initScale.value ?? 1;
|
||||||
|
// print("变化了.......... ${initScale.value}");
|
||||||
|
// });
|
||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
scrollControllerNum.addListener(() {
|
scrollControllerNum.addListener(() {
|
||||||
|
|
@ -265,62 +308,55 @@ Widget $questionNumberView(BuildContext context, HomeworkReviewLogic logic, Home
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var stream = logic.state.imageScaleZoom.listen((e) {
|
||||||
|
useImageInfo.value = e;
|
||||||
|
usePiddingTop.value = e?.imageHeightOffsetStart ?? 0;
|
||||||
|
});
|
||||||
|
|
||||||
return () {
|
return () {
|
||||||
|
stream.cancel();
|
||||||
listenVal.cancel();
|
listenVal.cancel();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return Container(
|
var actualImgHeight = useImageInfo.value?.actualImgHeight ?? 0; // 实际图片高度
|
||||||
height: double.infinity,
|
|
||||||
decoration: BoxDecoration(
|
print("容器高度:$boxHeight");
|
||||||
color: const Color.fromRGBO(159, 159, 159, 0.97),
|
print("图片高度:$actualImgHeight");
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
print("数据长度:${studentQuestions.length}");
|
||||||
color: const Color.fromRGBO(46, 91, 255, 0.2),
|
return SingleChildScrollView(
|
||||||
offset: Offset(0, 8.w), //阴影y轴偏移量
|
|
||||||
blurRadius: 1, //阴影模糊程度
|
|
||||||
spreadRadius: 2, //阴影扩散程度
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: GestureDetector(
|
|
||||||
onPanDown: (_) => sateData.panQuestView = false,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
controller: scrollControllerNum,
|
controller: scrollControllerNum,
|
||||||
physics: const BouncingScrollPhysics(),
|
physics: const BouncingScrollPhysics(),
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
scrollDirection: Axis.vertical, // 设置垂直滚动
|
scrollDirection: Axis.vertical, // 设置垂直滚动
|
||||||
child: Obx(() {
|
child: Container(
|
||||||
var imageVal = sateData.imageScale.value;
|
height: actualImgHeight,
|
||||||
if (imageVal == null) return const SizedBox();
|
margin: EdgeInsets.only(top: usePiddingTop.value > 0 ? usePiddingTop.value : 0),
|
||||||
var studentQuestions = sateData.studentQuestions.value;
|
color: Colors.red,
|
||||||
var boxHeight = imageVal.boxHeight;
|
|
||||||
var actualImgHeight = imageVal.actualImgHeight; // 实际图片高度
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: (boxHeight > actualImgHeight ? boxHeight : actualImgHeight) * (logic.state.initScale.value ?? 1),
|
|
||||||
padding: EdgeInsets.only(top: imageVal.remainingHeight > 0 ? imageVal.remainingHeight / 2 : 0),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: studentQuestions
|
children: studentQuestions
|
||||||
?.asMap()
|
.asMap()
|
||||||
.keys
|
.keys
|
||||||
.map((e) => $ScoringQuestionsView(logic, studentQuestions[e], imageVal.scaleRatio, studentQuestions))
|
.map((e) => $ScoringQuestionsView(
|
||||||
.toList() ??
|
logic,
|
||||||
[],
|
studentQuestions[e],
|
||||||
|
imageVal.scaleRatio,
|
||||||
|
studentQuestions,
|
||||||
|
useImageInfo.value?.zoom ?? 1,
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
|
||||||
}),
|
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 单道题得分框
|
// 单道题得分框
|
||||||
@hwidget
|
@hwidget
|
||||||
Widget $scoringQuestionsView(
|
Widget $scoringQuestionsView(BuildContext context, HomeworkReviewLogic logic, StudentQuestions item, double scaleRatio,
|
||||||
BuildContext context, HomeworkReviewLogic logic, StudentQuestions item, double scaleRatio, List<StudentQuestions>? studentQuestions) {
|
List<StudentQuestions>? studentQuestions, double initScale) {
|
||||||
var studentScore = useState<int?>(item.studentScore);
|
var studentScore = useState<int?>(item.studentScore);
|
||||||
var initScale = useState<double>(logic.state.initScale.value ?? 1);
|
|
||||||
|
|
||||||
useValueChanged<int?, void>(studentScore.value, (_, __) {
|
useValueChanged<int?, void>(studentScore.value, (_, __) {
|
||||||
item.studentScore = studentScore.value;
|
item.studentScore = studentScore.value;
|
||||||
|
|
@ -333,11 +369,6 @@ Widget $scoringQuestionsView(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
useValueChanged<double?, void>(logic.state.initScale.value, (_, __) {
|
|
||||||
print("数据了啦啦啦啦: ${logic.state.initScale}");
|
|
||||||
initScale.value = logic.state.initScale.value ?? 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
useValueChanged<StudentQuestions, void>(item, (_, __) {
|
useValueChanged<StudentQuestions, void>(item, (_, __) {
|
||||||
studentScore.value = item.studentScore;
|
studentScore.value = item.studentScore;
|
||||||
});
|
});
|
||||||
|
|
@ -346,9 +377,8 @@ Widget $scoringQuestionsView(
|
||||||
return () {};
|
return () {};
|
||||||
}, []);
|
}, []);
|
||||||
var padinVal = item.correctRate > 0 ? EdgeInsets.only(top: 6.4.h) : EdgeInsets.symmetric(vertical: 2.h);
|
var padinVal = item.correctRate > 0 ? EdgeInsets.only(top: 6.4.h) : EdgeInsets.symmetric(vertical: 2.h);
|
||||||
print("高度: ${item.height! * scaleRatio * initScale.value}");
|
|
||||||
return Container(
|
return Container(
|
||||||
height: item.height! * scaleRatio * initScale.value,
|
height: item.height! * scaleRatio * initScale,
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
child: item.useTime == 0
|
child: item.useTime == 0
|
||||||
? Container()
|
? Container()
|
||||||
|
|
@ -520,6 +550,7 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
||||||
sateData.zoomOffset = Offset(sateData.zoomOffset!.dx, -sateData.slide.value);
|
sateData.zoomOffset = Offset(sateData.zoomOffset!.dx, -sateData.slide.value);
|
||||||
}
|
}
|
||||||
initPosition.value = sateData.zoomOffset;
|
initPosition.value = sateData.zoomOffset;
|
||||||
|
print("赋值 initPosition.value ${initPosition.value}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return () {
|
return () {
|
||||||
|
|
@ -539,7 +570,7 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
||||||
imageHeight: info.image.height.toDouble(),
|
imageHeight: info.image.height.toDouble(),
|
||||||
url: sateData.data.value!.zgtAnswer,
|
url: sateData.data.value!.zgtAnswer,
|
||||||
);
|
);
|
||||||
print("这里的高度 ${theMaxHeight.value} $actualHeight ${sateData.imageScale.value?.actualImgHeight}");
|
// print("这里的高度 ${theMaxHeight.value} $actualHeight ${sateData.imageScale.value?.actualImgHeight}");
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
@ -636,6 +667,7 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
||||||
print("++++++++++++++++++++++ ${theMaxHeight.value}");
|
print("++++++++++++++++++++++ ${theMaxHeight.value}");
|
||||||
print("+++++ 位置:${initPosition.value}");
|
print("+++++ 位置:${initPosition.value}");
|
||||||
print("+++++ 缩放:${sateData.initScale.value}");
|
print("+++++ 缩放:${sateData.initScale.value}");
|
||||||
|
// sateData.slide.value
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
// decoration: BoxDecoration(
|
// decoration: BoxDecoration(
|
||||||
|
|
@ -704,13 +736,13 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
||||||
child: Obx(() {
|
child: Obx(() {
|
||||||
var isPen = annotationState.pen.value;
|
var isPen = annotationState.pen.value;
|
||||||
var showZgtAnnotate = sateData.data.value?.showZgtAnnotate;
|
var showZgtAnnotate = sateData.data.value?.showZgtAnnotate;
|
||||||
|
// sateData.slide.value
|
||||||
print("55555高度: ${actualHeight} ${initPosition.value}");
|
// print("55555高度: ${actualHeight} ${initPosition.value}");
|
||||||
return IgnorePointer(
|
return IgnorePointer(
|
||||||
ignoring: isPen,
|
ignoring: isPen,
|
||||||
child: Zoom(
|
child: Zoom(
|
||||||
key: zoomKey,
|
key: zoomKey,
|
||||||
// initTotalZoomOut: true, // 展示全部内容 初始化不产生滚动条
|
initTotalZoomOut: true, // 展示全部内容 初始化不产生滚动条
|
||||||
zoomSensibility: 0.05,
|
zoomSensibility: 0.05,
|
||||||
scrollWeight: 4.r,
|
scrollWeight: 4.r,
|
||||||
doubleTapAnimDuration: Duration.zero,
|
doubleTapAnimDuration: Duration.zero,
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import 'package:making_school_asignment_app/common/job/marking_models/do_test_qu
|
||||||
import 'package:making_school_asignment_app/common/job/marking_models/favor_param.dart';
|
import 'package:making_school_asignment_app/common/job/marking_models/favor_param.dart';
|
||||||
import 'package:making_school_asignment_app/common/job/marking_models/review_submission_params.dart';
|
import 'package:making_school_asignment_app/common/job/marking_models/review_submission_params.dart';
|
||||||
import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dart';
|
import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dart';
|
||||||
|
import 'package:making_school_asignment_app/common/utils/anti_shake_throttling.dart' as anti_shake_throttling;
|
||||||
import 'package:making_school_asignment_app/common/utils/permission_describe_util.dart';
|
import 'package:making_school_asignment_app/common/utils/permission_describe_util.dart';
|
||||||
import 'package:making_school_asignment_app/common/utils/toast_utils.dart';
|
import 'package:making_school_asignment_app/common/utils/toast_utils.dart';
|
||||||
import 'package:making_school_asignment_app/common/utils/upload_oss_img_utils.dart';
|
import 'package:making_school_asignment_app/common/utils/upload_oss_img_utils.dart';
|
||||||
|
|
@ -34,6 +35,9 @@ class HomeworkReviewState {
|
||||||
late Rx<double> slide; // 滑动位置
|
late Rx<double> slide; // 滑动位置
|
||||||
bool? panQuestView = null;
|
bool? panQuestView = null;
|
||||||
late Rx<TestQuestionsImageInfo?> imageScale;
|
late Rx<TestQuestionsImageInfo?> imageScale;
|
||||||
|
late Rx<TestQuestionsImageInfo?> imageScaleZoom = Rx<TestQuestionsImageInfo?>(null);
|
||||||
|
|
||||||
|
/// 图片放大后的操作存放数据
|
||||||
List<dynamic> handwritings = [];
|
List<dynamic> handwritings = [];
|
||||||
bool needRefresh = false;
|
bool needRefresh = false;
|
||||||
bool lastQuestionPrompt = false; // 最后一题提示
|
bool lastQuestionPrompt = false; // 最后一题提示
|
||||||
|
|
@ -75,6 +79,8 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
||||||
final HomeworkReviewState state = HomeworkReviewState();
|
final HomeworkReviewState state = HomeworkReviewState();
|
||||||
final HomeworkReviewAnnotationsControlState annotationState = HomeworkReviewAnnotationsControlState();
|
final HomeworkReviewAnnotationsControlState annotationState = HomeworkReviewAnnotationsControlState();
|
||||||
double appBarHeight = 56;
|
double appBarHeight = 56;
|
||||||
|
StreamSubscription<double?>? initScaleStream;
|
||||||
|
StreamSubscription<TestQuestionsImageInfo?>? imageScaleZoomStream;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
|
|
@ -103,6 +109,25 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
||||||
state.imageScale.value = null;
|
state.imageScale.value = null;
|
||||||
if (state.favorite.value != e.isFav) state.favorite.value = !state.favorite.value;
|
if (state.favorite.value != e.isFav) state.favorite.value = !state.favorite.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
imageScaleZoomStream = state.imageScale.listen((e) {
|
||||||
|
// state.imageScaleZoom.value = theImageScale;
|
||||||
|
var theImageScaleZoom = state.imageScaleZoom.value;
|
||||||
|
if (theImageScaleZoom == null || theImageScaleZoom.url != e?.url) state.imageScaleZoom.value = e;
|
||||||
|
});
|
||||||
|
|
||||||
|
initScaleStream = state.initScale.listen((e) {
|
||||||
|
anti_shake_throttling.debounce(() {
|
||||||
|
var theImageScale = state.imageScale.value;
|
||||||
|
if (theImageScale != null) {
|
||||||
|
theImageScale = TestQuestionsImageInfo.fromJson(theImageScale.toJson());
|
||||||
|
theImageScale.zoom = e ?? 1;
|
||||||
|
theImageScale = TestQuestionsImageInfo.fromJson(theImageScale.toJson());
|
||||||
|
}
|
||||||
|
state.imageScaleZoom.value = theImageScale;
|
||||||
|
}, const Duration(milliseconds: 100))();
|
||||||
|
});
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) => getData());
|
WidgetsBinding.instance.addPostFrameCallback((_) => getData());
|
||||||
super.onInit();
|
super.onInit();
|
||||||
}
|
}
|
||||||
|
|
@ -129,6 +154,8 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); // 屏幕刘海
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); // 屏幕刘海
|
||||||
_dataListen.cancel();
|
_dataListen.cancel();
|
||||||
_paramListen.cancel();
|
_paramListen.cancel();
|
||||||
|
initScaleStream?.cancel();
|
||||||
|
imageScaleZoomStream?.cancel();
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -338,8 +365,8 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
||||||
|
|
||||||
// 缩放组件 ==> 缩放监听
|
// 缩放组件 ==> 缩放监听
|
||||||
void onScaleUpdate(double scale, double zoom) async {
|
void onScaleUpdate(double scale, double zoom) async {
|
||||||
|
print("$scale $zoom");
|
||||||
state.initScale.value = zoom;
|
state.initScale.value = zoom;
|
||||||
// print("$scale $zoom");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> toFavorite() async {
|
Future<void> toFavorite() async {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue