mcy_new #1
|
|
@ -28,7 +28,7 @@ class TestQuestionsImageInfo extends Object {
|
|||
@JsonKey(name: 'actualImgHeight') // 实际展示图片高度
|
||||
double actualImgHeight;
|
||||
|
||||
@JsonKey(name: 'remainingHeight') // 视图剩余高度 实际展示图片展示高度下 剩余高度.(若伟负数就是超出视图的高度值)
|
||||
@JsonKey(name: 'remainingHeight') // 视图剩余高度 实际展示图片展示高度下 剩余高度.(若为负数就是超出视图的高度值)
|
||||
double remainingHeight;
|
||||
|
||||
@JsonKey(name: 'imageHeightOffsetStart') // 顶部坐标Y
|
||||
|
|
@ -62,8 +62,8 @@ class TestQuestionsImageInfo extends Object {
|
|||
}) {
|
||||
// 图片已视图宽为基准,高度自适应可滑动 图片的实际宽高都需要乘此基准值
|
||||
scaleRatio = boxWidth / imageWidth;
|
||||
actualImgWidth = imageWidth * scaleRatio;
|
||||
actualImgHeight = imageHeight * scaleRatio;
|
||||
actualImgWidth = imageWidth * scaleRatio * zoom;
|
||||
actualImgHeight = imageHeight * scaleRatio * zoom;
|
||||
remainingHeight = boxHeight - actualImgHeight;
|
||||
imageHeightOffsetStart = remainingHeight / 2;
|
||||
imageHeightOffsetend = imageHeightOffsetStart + actualImgHeight;
|
||||
|
|
|
|||
|
|
@ -12,9 +12,7 @@ import 'package:flutter/material.dart';
|
|||
VoidCallback debounce(Function func, [Duration delay = const Duration(milliseconds: 2000)]) {
|
||||
Timer? timer;
|
||||
target() {
|
||||
if (timer?.isActive ?? false) {
|
||||
timer?.cancel();
|
||||
}
|
||||
timer?.cancel();
|
||||
timer = Timer(delay, () {
|
||||
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
|
||||
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(); // 试题题号区域
|
||||
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(() {
|
||||
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 () {
|
||||
stream.cancel();
|
||||
listenVal.cancel();
|
||||
};
|
||||
}, []);
|
||||
|
||||
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), //阴影y轴偏移量
|
||||
blurRadius: 1, //阴影模糊程度
|
||||
spreadRadius: 2, //阴影扩散程度
|
||||
)
|
||||
],
|
||||
),
|
||||
child: GestureDetector(
|
||||
onPanDown: (_) => sateData.panQuestView = false,
|
||||
child: SingleChildScrollView(
|
||||
controller: scrollControllerNum,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: EdgeInsets.zero,
|
||||
scrollDirection: Axis.vertical, // 设置垂直滚动
|
||||
child: Obx(() {
|
||||
var imageVal = sateData.imageScale.value;
|
||||
if (imageVal == null) return const SizedBox();
|
||||
var studentQuestions = sateData.studentQuestions.value;
|
||||
var boxHeight = imageVal.boxHeight;
|
||||
var actualImgHeight = imageVal.actualImgHeight; // 实际图片高度
|
||||
var actualImgHeight = useImageInfo.value?.actualImgHeight ?? 0; // 实际图片高度
|
||||
|
||||
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(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: studentQuestions
|
||||
?.asMap()
|
||||
.keys
|
||||
.map((e) => $ScoringQuestionsView(logic, studentQuestions[e], imageVal.scaleRatio, studentQuestions))
|
||||
.toList() ??
|
||||
[],
|
||||
),
|
||||
);
|
||||
}),
|
||||
)),
|
||||
print("容器高度:$boxHeight");
|
||||
print("图片高度:$actualImgHeight");
|
||||
|
||||
print("数据长度:${studentQuestions.length}");
|
||||
return SingleChildScrollView(
|
||||
controller: scrollControllerNum,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: EdgeInsets.zero,
|
||||
scrollDirection: Axis.vertical, // 设置垂直滚动
|
||||
child: Container(
|
||||
height: actualImgHeight,
|
||||
margin: EdgeInsets.only(top: usePiddingTop.value > 0 ? usePiddingTop.value : 0),
|
||||
color: Colors.red,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: studentQuestions
|
||||
.asMap()
|
||||
.keys
|
||||
.map((e) => $ScoringQuestionsView(
|
||||
logic,
|
||||
studentQuestions[e],
|
||||
imageVal.scaleRatio,
|
||||
studentQuestions,
|
||||
useImageInfo.value?.zoom ?? 1,
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// 单道题得分框
|
||||
@hwidget
|
||||
Widget $scoringQuestionsView(
|
||||
BuildContext context, HomeworkReviewLogic logic, StudentQuestions item, double scaleRatio, List<StudentQuestions>? studentQuestions) {
|
||||
Widget $scoringQuestionsView(BuildContext context, HomeworkReviewLogic logic, StudentQuestions item, double scaleRatio,
|
||||
List<StudentQuestions>? studentQuestions, double initScale) {
|
||||
var studentScore = useState<int?>(item.studentScore);
|
||||
var initScale = useState<double>(logic.state.initScale.value ?? 1);
|
||||
|
||||
useValueChanged<int?, void>(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, (_, __) {
|
||||
studentScore.value = item.studentScore;
|
||||
});
|
||||
|
|
@ -346,9 +377,8 @@ Widget $scoringQuestionsView(
|
|||
return () {};
|
||||
}, []);
|
||||
var padinVal = item.correctRate > 0 ? EdgeInsets.only(top: 6.4.h) : EdgeInsets.symmetric(vertical: 2.h);
|
||||
print("高度: ${item.height! * scaleRatio * initScale.value}");
|
||||
return Container(
|
||||
height: item.height! * scaleRatio * initScale.value,
|
||||
height: item.height! * scaleRatio * initScale,
|
||||
padding: EdgeInsets.zero,
|
||||
child: item.useTime == 0
|
||||
? Container()
|
||||
|
|
@ -520,6 +550,7 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
|||
sateData.zoomOffset = Offset(sateData.zoomOffset!.dx, -sateData.slide.value);
|
||||
}
|
||||
initPosition.value = sateData.zoomOffset;
|
||||
print("赋值 initPosition.value ${initPosition.value}");
|
||||
}
|
||||
});
|
||||
return () {
|
||||
|
|
@ -539,7 +570,7 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
|||
imageHeight: info.image.height.toDouble(),
|
||||
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("+++++ 位置:${initPosition.value}");
|
||||
print("+++++ 缩放:${sateData.initScale.value}");
|
||||
// sateData.slide.value
|
||||
|
||||
return Container(
|
||||
// decoration: BoxDecoration(
|
||||
|
|
@ -704,13 +736,13 @@ class QuestionImageView extends HookWidget with EventBusMixin<BottomOperationBar
|
|||
child: Obx(() {
|
||||
var isPen = annotationState.pen.value;
|
||||
var showZgtAnnotate = sateData.data.value?.showZgtAnnotate;
|
||||
|
||||
print("55555高度: ${actualHeight} ${initPosition.value}");
|
||||
// sateData.slide.value
|
||||
// print("55555高度: ${actualHeight} ${initPosition.value}");
|
||||
return IgnorePointer(
|
||||
ignoring: isPen,
|
||||
child: Zoom(
|
||||
key: zoomKey,
|
||||
// initTotalZoomOut: true, // 展示全部内容 初始化不产生滚动条
|
||||
initTotalZoomOut: true, // 展示全部内容 初始化不产生滚动条
|
||||
zoomSensibility: 0.05,
|
||||
scrollWeight: 4.r,
|
||||
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/review_submission_params.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/toast_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; // 滑动位置
|
||||
bool? panQuestView = null;
|
||||
late Rx<TestQuestionsImageInfo?> imageScale;
|
||||
late Rx<TestQuestionsImageInfo?> imageScaleZoom = Rx<TestQuestionsImageInfo?>(null);
|
||||
|
||||
/// 图片放大后的操作存放数据
|
||||
List<dynamic> handwritings = [];
|
||||
bool needRefresh = false;
|
||||
bool lastQuestionPrompt = false; // 最后一题提示
|
||||
|
|
@ -75,6 +79,8 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
|||
final HomeworkReviewState state = HomeworkReviewState();
|
||||
final HomeworkReviewAnnotationsControlState annotationState = HomeworkReviewAnnotationsControlState();
|
||||
double appBarHeight = 56;
|
||||
StreamSubscription<double?>? initScaleStream;
|
||||
StreamSubscription<TestQuestionsImageInfo?>? imageScaleZoomStream;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
|
|
@ -103,6 +109,25 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
|||
state.imageScale.value = null;
|
||||
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());
|
||||
super.onInit();
|
||||
}
|
||||
|
|
@ -129,6 +154,8 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
|||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); // 屏幕刘海
|
||||
_dataListen.cancel();
|
||||
_paramListen.cancel();
|
||||
initScaleStream?.cancel();
|
||||
imageScaleZoomStream?.cancel();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
|
|
@ -338,8 +365,8 @@ class HomeworkReviewLogic extends GetxController with RequestToolMixin {
|
|||
|
||||
// 缩放组件 ==> 缩放监听
|
||||
void onScaleUpdate(double scale, double zoom) async {
|
||||
print("$scale $zoom");
|
||||
state.initScale.value = zoom;
|
||||
// print("$scale $zoom");
|
||||
}
|
||||
|
||||
Future<void> toFavorite() async {
|
||||
|
|
|
|||
Loading…
Reference in New Issue