mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-07-22 19:40:10 +08:00
126 lines
3.7 KiB
Dart
126 lines
3.7 KiB
Dart
import 'package:PiliPlus/common/widgets/flutter/page/tabs.dart';
|
|
import 'package:PiliPlus/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart';
|
|
import 'package:PiliPlus/utils/platform_utils.dart';
|
|
import 'package:PiliPlus/utils/storage_pref.dart';
|
|
import 'package:flutter/material.dart' hide TabBarView;
|
|
|
|
Widget tabBarView({
|
|
required List<Widget> children,
|
|
TabController? controller,
|
|
}) => TabBarView<CustomHorizontalDragGestureRecognizer>(
|
|
controller: controller,
|
|
physics: clampingScrollPhysics,
|
|
horizontalDragGestureRecognizer: CustomHorizontalDragGestureRecognizer.new,
|
|
children: children,
|
|
);
|
|
|
|
final _springDescription = _customSpringDescription();
|
|
|
|
SpringDescription _customSpringDescription() {
|
|
final List<double> springDescription = Pref.springDescription;
|
|
return SpringDescription(
|
|
mass: springDescription[0],
|
|
stiffness: springDescription[1],
|
|
damping: springDescription[2],
|
|
);
|
|
}
|
|
|
|
const clampingScrollPhysics = CustomTabBarViewScrollPhysics(
|
|
parent: ClampingScrollPhysics(),
|
|
);
|
|
|
|
class CustomTabBarViewScrollPhysics extends ScrollPhysics {
|
|
const CustomTabBarViewScrollPhysics({super.parent});
|
|
|
|
@override
|
|
CustomTabBarViewScrollPhysics applyTo(ScrollPhysics? ancestor) {
|
|
return CustomTabBarViewScrollPhysics(parent: buildParent(ancestor));
|
|
}
|
|
|
|
@override
|
|
SpringDescription get spring => _springDescription;
|
|
}
|
|
|
|
mixin ReloadMixin {
|
|
late bool reload = false;
|
|
}
|
|
|
|
class ReloadScrollPhysics extends AlwaysScrollableScrollPhysics {
|
|
const ReloadScrollPhysics({super.parent, required this.controller});
|
|
|
|
final ReloadMixin controller;
|
|
|
|
@override
|
|
ReloadScrollPhysics applyTo(ScrollPhysics? ancestor) {
|
|
return ReloadScrollPhysics(
|
|
parent: buildParent(ancestor),
|
|
controller: controller,
|
|
);
|
|
}
|
|
|
|
@override
|
|
double adjustPositionForNewDimensions({
|
|
required ScrollMetrics oldPosition,
|
|
required ScrollMetrics newPosition,
|
|
required bool isScrolling,
|
|
required double velocity,
|
|
}) {
|
|
if (controller.reload) {
|
|
controller.reload = false;
|
|
return 0;
|
|
}
|
|
return super.adjustPositionForNewDimensions(
|
|
oldPosition: oldPosition,
|
|
newPosition: newPosition,
|
|
isScrolling: isScrolling,
|
|
velocity: velocity,
|
|
);
|
|
}
|
|
}
|
|
|
|
final platformClampingPhysics = PlatformUtils.isDarwin
|
|
? const BouncingScrollPhysicsExt()
|
|
: const ClampingScrollPhysics();
|
|
|
|
final platformAlwaysClampingPhysics = PlatformUtils.isDarwin
|
|
? const AlwaysScrollableScrollPhysics(parent: BouncingScrollPhysicsExt())
|
|
: const AlwaysScrollableScrollPhysics(parent: ClampingScrollPhysics());
|
|
|
|
class BouncingScrollPhysicsExt extends BouncingScrollPhysics
|
|
with ClampingBoundaryMixin {
|
|
const BouncingScrollPhysicsExt({super.parent});
|
|
|
|
@override
|
|
BouncingScrollPhysicsExt applyTo(ScrollPhysics? ancestor) {
|
|
return BouncingScrollPhysicsExt(parent: buildParent(ancestor));
|
|
}
|
|
}
|
|
|
|
/// [ClampingScrollPhysics.applyBoundaryConditions]
|
|
mixin ClampingBoundaryMixin on ScrollPhysics {
|
|
@override
|
|
double applyBoundaryConditions(ScrollMetrics position, double value) {
|
|
if (value < position.pixels &&
|
|
position.pixels <= position.minScrollExtent) {
|
|
// Underscroll.
|
|
return value - position.pixels;
|
|
}
|
|
if (position.maxScrollExtent <= position.pixels &&
|
|
position.pixels < value) {
|
|
// Overscroll.
|
|
return value - position.pixels;
|
|
}
|
|
if (value < position.minScrollExtent &&
|
|
position.minScrollExtent < position.pixels) {
|
|
// Hit top edge.
|
|
return value - position.minScrollExtent;
|
|
}
|
|
if (position.pixels < position.maxScrollExtent &&
|
|
position.maxScrollExtent < value) {
|
|
// Hit bottom edge.
|
|
return value - position.maxScrollExtent;
|
|
}
|
|
return 0.0;
|
|
}
|
|
}
|