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, height: height,
child: GridView( child: GridView(
padding: const EdgeInsets.only(left: 12, bottom: 12, right: 12), padding: const EdgeInsets.only(left: 12, bottom: 12, right: 12),
gridDelegate: const SliverGridDelegateWithExtentAndRatio( gridDelegate: SliverGridDelegateWithExtentAndRatio(
maxCrossAxisExtent: 65, maxCrossAxisExtent: 65,
mainAxisSpacing: 12, mainAxisSpacing: 12,
crossAxisSpacing: 12, crossAxisSpacing: 12,

View File

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

View File

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

View File

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