fix: listsheet scrolled multiple times

This commit is contained in:
bggRGjQaUbCoE
2024-08-28 19:14:25 +08:00
parent c7ebe92f4e
commit f404fece2b

View File

@@ -7,13 +7,6 @@ import '../../utils/storage.dart';
import '../../utils/utils.dart'; import '../../utils/utils.dart';
class ListSheet { class ListSheet {
final dynamic episodes;
final String? bvid;
final int? aid;
final int currentCid;
final Function changeFucCall;
final BuildContext context;
PersistentBottomSheetController? bottomSheetController;
ListSheet({ ListSheet({
required this.episodes, required this.episodes,
this.bvid, this.bvid,
@@ -22,13 +15,71 @@ class ListSheet {
required this.changeFucCall, required this.changeFucCall,
required this.context, required this.context,
}); });
final dynamic episodes;
final String? bvid;
final int? aid;
final int currentCid;
final Function changeFucCall;
final BuildContext context;
late PersistentBottomSheetController bottomSheetController;
void buildShowBottomSheet() {
bottomSheetController = showBottomSheet(
context: context,
builder: (context) => ListSheetContent(
episodes: episodes,
bvid: bvid,
aid: aid,
currentCid: currentCid,
changeFucCall: changeFucCall,
onClose: bottomSheetController.close,
));
}
}
class ListSheetContent extends StatefulWidget {
const ListSheetContent({
super.key,
required this.episodes,
this.bvid,
this.aid,
required this.currentCid,
required this.changeFucCall,
required this.onClose,
});
final dynamic episodes;
final String? bvid;
final int? aid;
final int currentCid;
final Function changeFucCall;
final Function() onClose;
@override
State<ListSheetContent> createState() => _ListSheetContentState();
}
class _ListSheetContentState extends State<ListSheetContent> {
final ItemScrollController itemScrollController = ItemScrollController();
late final int currentIndex =
widget.episodes!.indexWhere((dynamic e) => e.cid == widget.currentCid) ??
0;
bool reverse = false; bool reverse = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
itemScrollController.jumpTo(index: currentIndex);
});
}
Widget buildEpisodeListItem( Widget buildEpisodeListItem(
dynamic episode, dynamic episode,
int index, int index,
bool isCurrentIndex, bool isCurrentIndex,
PersistentBottomSheetController bottomSheetController,
) { ) {
Color primary = Theme.of(context).colorScheme.primary; Color primary = Theme.of(context).colorScheme.primary;
late String title; late String title;
@@ -58,11 +109,11 @@ class ListSheet {
} }
} }
SmartDialog.showToast('切换到:$title'); SmartDialog.showToast('切换到:$title');
bottomSheetController.close(); widget.onClose();
if (episode.runtimeType.toString() == "EpisodeItem") { if (episode.runtimeType.toString() == "EpisodeItem") {
changeFucCall(episode.bvid, episode.cid, episode.aid); widget.changeFucCall(episode.bvid, episode.cid, episode.aid);
} else { } else {
changeFucCall(bvid!, episode.cid, aid!); widget.changeFucCall(widget.bvid!, episode.cid, widget.aid!);
} }
}, },
dense: false, dense: false,
@@ -95,102 +146,90 @@ class ListSheet {
); );
} }
void buildShowBottomSheet() { @override
int currentIndex = Widget build(BuildContext context) {
episodes!.indexWhere((dynamic e) => e.cid == currentCid) ?? 0; return Container(
final ItemScrollController itemScrollController = ItemScrollController(); height: Utils.getSheetHeight(context),
bottomSheetController = showBottomSheet( color: Theme.of(context).colorScheme.surface,
context: context, child: Column(
builder: (BuildContext context) { children: [
return StatefulBuilder( Container(
builder: (BuildContext context, StateSetter setState) { height: 45,
WidgetsBinding.instance.addPostFrameCallback((_) async { padding: const EdgeInsets.only(left: 14, right: 14),
itemScrollController.jumpTo(index: currentIndex); child: Row(
});
return Container(
height: Utils.getSheetHeight(context),
color: Theme.of(context).colorScheme.background,
child: Column(
children: [ children: [
Container( Text(
height: 45, '合集(${widget.episodes!.length}',
padding: const EdgeInsets.only(left: 14, right: 14), style: Theme.of(context).textTheme.titleMedium,
child: Row(
children: [
Text(
'合集(${episodes!.length}',
style: Theme.of(context).textTheme.titleMedium,
),
IconButton(
tooltip: '跳至顶部',
icon: const Icon(Icons.vertical_align_top),
onPressed: () {
itemScrollController.jumpTo(
index: !reverse ? 0 : episodes!.length - 1,
);
},
),
IconButton(
tooltip: '跳至底部',
icon: const Icon(Icons.vertical_align_bottom),
onPressed: () {
itemScrollController.jumpTo(
index: !reverse ? episodes!.length - 1 : 0,
);
},
),
const Spacer(),
IconButton(
tooltip: '反序',
icon: Icon(!reverse
? MdiIcons.sortAscending
: MdiIcons.sortDescending),
onPressed: () {
setState(() {
reverse = !reverse;
});
},
),
IconButton(
tooltip: '关闭',
icon: const Icon(Icons.close),
onPressed: () => bottomSheetController!.close(),
),
],
),
), ),
Divider( IconButton(
height: 1, tooltip: '跳至顶部',
color: Theme.of(context).dividerColor.withOpacity(0.1), icon: const Icon(Icons.vertical_align_top),
onPressed: () {
itemScrollController.scrollTo(
index: !reverse ? 0 : widget.episodes!.length - 1,
duration: const Duration(milliseconds: 200),
);
},
), ),
Expanded( IconButton(
child: Material( tooltip: '跳至底部',
child: ScrollablePositionedList.separated( icon: const Icon(Icons.vertical_align_bottom),
padding: EdgeInsets.only( onPressed: () {
bottom: MediaQuery.of(context).padding.bottom + 20), itemScrollController.scrollTo(
reverse: reverse, index: !reverse ? widget.episodes!.length - 1 : 0,
itemCount: episodes!.length, duration: const Duration(milliseconds: 200),
itemBuilder: (BuildContext context, int index) { );
return buildEpisodeListItem( },
episodes![index], ),
index, const Spacer(),
currentIndex == index, IconButton(
bottomSheetController!, tooltip: '反序',
); icon: Icon(!reverse
}, ? MdiIcons.sortAscending
itemScrollController: itemScrollController, : MdiIcons.sortDescending),
separatorBuilder: (_, index) => Divider( onPressed: () {
height: 1, setState(() {
color: Theme.of(context).dividerColor.withOpacity(0.1), reverse = !reverse;
), });
), },
), ),
IconButton(
tooltip: '关闭',
icon: const Icon(Icons.close),
onPressed: widget.onClose,
), ),
], ],
), ),
); ),
}); Divider(
}, height: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
),
Expanded(
child: Material(
child: ScrollablePositionedList.separated(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).padding.bottom + 20),
reverse: reverse,
itemCount: widget.episodes!.length,
itemBuilder: (BuildContext context, int index) {
return buildEpisodeListItem(
widget.episodes![index],
index,
currentIndex == index,
);
},
itemScrollController: itemScrollController,
separatorBuilder: (_, index) => Divider(
height: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
),
),
),
),
],
),
); );
} }
} }