feat: grid jump to index (#1004)

This commit is contained in:
My-Responsitories
2025-08-12 17:06:33 +08:00
committed by GitHub
parent e00c176bdf
commit 690c4f5786
4 changed files with 38 additions and 12 deletions

View File

@@ -595,7 +595,7 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
height: height,
child: GridView(
padding: const EdgeInsets.only(left: 12, bottom: 12, right: 12),
gridDelegate: const SliverGridDelegateWithExtentAndRatio(
gridDelegate: SliverGridDelegateWithExtentAndRatio(
maxCrossAxisExtent: 65,
mainAxisSpacing: 12,
crossAxisSpacing: 12,

View File

@@ -42,6 +42,8 @@ class _MemberVideoState extends State<MemberVideo>
@override
bool get wantKeepAlive => true;
late final gridDelegate = Grid.videoCardHDelegate(context);
late final _controller = Get.put(
MemberVideoCtr(
type: widget.type,
@@ -89,12 +91,29 @@ class _MemberVideoState extends State<MemberVideo>
top: false,
left: false,
child: FloatingActionButton.extended(
onPressed: () => _controller
onPressed: () {
final fromViewAid = _controller.fromViewAid;
_controller
..isLocating.value = true
..lastAid = _controller.fromViewAid
..lastAid = fromViewAid;
final locatedIndex = _controller
.loadingState
.value
.dataOrNull
?.indexWhere((i) => i.param == fromViewAid);
if (locatedIndex == null || locatedIndex == -1) {
_controller
..page = 0
..loadingState.value = LoadingState.loading()
..queryData(),
..queryData();
} else {
PrimaryScrollController.of(context).jumpTo(
gridDelegate.layoutCache!
.getGeometryForChildIndex(locatedIndex)
.scrollOffset,
);
}
},
label: const Text('定位至上次观看'),
),
),
@@ -217,7 +236,7 @@ class _MemberVideoState extends State<MemberVideo>
),
),
SliverGrid(
gridDelegate: Grid.videoCardHDelegate(context),
gridDelegate: gridDelegate,
delegate: SliverChildBuilderDelegate(
(context, index) {
if (widget.type != ContributeType.season &&

View File

@@ -301,7 +301,7 @@ class _ReplyPageState extends CommonRichTextPubPageState<ReplyPage> {
height: height,
child: GridView(
padding: const EdgeInsets.only(left: 12, bottom: 12, right: 12),
gridDelegate: const SliverGridDelegateWithExtentAndRatio(
gridDelegate: SliverGridDelegateWithExtentAndRatio(
maxCrossAxisExtent: 65,
mainAxisSpacing: 12,
crossAxisSpacing: 12,

View File

@@ -26,7 +26,7 @@ class SliverGridDelegateWithExtentAndRatio extends SliverGridDelegate {
/// The [maxCrossAxisExtent], [mainAxisExtent], [mainAxisSpacing],
/// and [crossAxisSpacing] arguments must not be negative.
/// The [childAspectRatio] argument must be greater than zero.
const SliverGridDelegateWithExtentAndRatio({
SliverGridDelegateWithExtentAndRatio({
required this.maxCrossAxisExtent,
this.mainAxisSpacing = 0.0,
this.crossAxisSpacing = 0.0,
@@ -76,9 +76,13 @@ class SliverGridDelegateWithExtentAndRatio extends SliverGridDelegate {
return true;
}
SliverGridLayout? layoutCache;
@override
SliverGridLayout getLayout(SliverConstraints constraints) {
// invoked before each frame
assert(_debugAssertIsValid(constraints.crossAxisExtent));
if (layoutCache != null) return layoutCache!;
int crossAxisCount =
((constraints.crossAxisExtent - crossAxisSpacing) /
(maxCrossAxisExtent + crossAxisSpacing))
@@ -95,7 +99,7 @@ class SliverGridDelegateWithExtentAndRatio extends SliverGridDelegate {
minHeight,
childCrossAxisExtent / childAspectRatio + mainAxisExtent,
);
return SliverGridRegularTileLayout(
return layoutCache = SliverGridRegularTileLayout(
crossAxisCount: crossAxisCount,
mainAxisStride: childMainAxisExtent + mainAxisSpacing,
crossAxisStride: childCrossAxisExtent + crossAxisSpacing,
@@ -107,10 +111,13 @@ class SliverGridDelegateWithExtentAndRatio extends SliverGridDelegate {
@override
bool shouldRelayout(SliverGridDelegateWithExtentAndRatio oldDelegate) {
return oldDelegate.maxCrossAxisExtent != maxCrossAxisExtent ||
final flag =
oldDelegate.maxCrossAxisExtent != maxCrossAxisExtent ||
oldDelegate.mainAxisSpacing != mainAxisSpacing ||
oldDelegate.crossAxisSpacing != crossAxisSpacing ||
oldDelegate.childAspectRatio != childAspectRatio ||
oldDelegate.mainAxisExtent != mainAxisExtent;
if (flag) layoutCache = null;
return flag;
}
}