opt: escape performReassemble (#1864)

This commit is contained in:
My-Responsitories
2026-03-13 18:38:37 +08:00
committed by GitHub
parent 96f9972895
commit aee4424dbf
6 changed files with 69 additions and 65 deletions

View File

@@ -12,6 +12,13 @@ import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'
import 'package:flutter/foundation.dart' show clampDouble; import 'package:flutter/foundation.dart' show clampDouble;
import 'package:flutter/material.dart' hide RefreshIndicator; import 'package:flutter/material.dart' hide RefreshIndicator;
/// The distance from the child's top or bottom [edgeOffset] where
/// the refresh indicator will settle. During the drag that exposes the refresh
/// indicator, its actual displacement may significantly exceed this value.
///
/// In most cases, [displacement] distance starts counting from the parent's
/// edges. However, if [edgeOffset] is larger than zero then the [displacement]
/// value is calculated from that offset instead of the parent's edge.
double displacement = Pref.refreshDisplacement; double displacement = Pref.refreshDisplacement;
// The over-scroll distance that moves the indicator to its maximum // The over-scroll distance that moves the indicator to its maximum
@@ -125,7 +132,6 @@ class RefreshIndicator extends StatefulWidget {
/// The [semanticsValue] may be used to specify progress on the widget. /// The [semanticsValue] may be used to specify progress on the widget.
const RefreshIndicator({ const RefreshIndicator({
super.key, super.key,
this.displacement = 40.0,
this.edgeOffset = 0.0, this.edgeOffset = 0.0,
required this.onRefresh, required this.onRefresh,
this.color, this.color,
@@ -145,15 +151,6 @@ class RefreshIndicator extends StatefulWidget {
/// Typically a [ListView] or [CustomScrollView]. /// Typically a [ListView] or [CustomScrollView].
final Widget child; final Widget child;
/// The distance from the child's top or bottom [edgeOffset] where
/// the refresh indicator will settle. During the drag that exposes the refresh
/// indicator, its actual displacement may significantly exceed this value.
///
/// In most cases, [displacement] distance starts counting from the parent's
/// edges. However, if [edgeOffset] is larger than zero then the [displacement]
/// value is calculated from that offset instead of the parent's edge.
final double displacement;
/// The offset where [RefreshProgressIndicator] starts to appear on drag start. /// The offset where [RefreshProgressIndicator] starts to appear on drag start.
/// ///
/// Depending whether the indicator is showing on the top or bottom, the value /// Depending whether the indicator is showing on the top or bottom, the value
@@ -522,7 +519,7 @@ class RefreshIndicatorState extends State<RefreshIndicator>
axisAlignment: 1.0, axisAlignment: 1.0,
sizeFactor: _positionFactor, // This is what brings it down. sizeFactor: _positionFactor, // This is what brings it down.
child: Padding( child: Padding(
padding: EdgeInsets.only(top: widget.displacement), padding: EdgeInsets.only(top: displacement),
child: Align( child: Align(
alignment: Alignment.topCenter, alignment: Alignment.topCenter,
child: ScaleTransition( child: ScaleTransition(
@@ -571,18 +568,8 @@ class RefreshIndicatorState extends State<RefreshIndicator>
} }
} }
Widget refreshIndicator({ // ignore: camel_case_types
required RefreshCallback onRefresh, typedef refreshIndicator = RefreshIndicator;
required Widget child,
bool isClampingScrollPhysics = false,
}) {
return RefreshIndicator(
displacement: displacement,
onRefresh: onRefresh,
isClampingScrollPhysics: isClampingScrollPhysics,
child: child,
);
}
class RefreshScrollBehavior extends CustomScrollBehavior { class RefreshScrollBehavior extends CustomScrollBehavior {
const RefreshScrollBehavior( const RefreshScrollBehavior(

View File

@@ -250,26 +250,34 @@ class MyApp extends StatelessWidget {
} }
} }
@override static (ThemeData, ThemeData) getAllTheme() {
Widget build(BuildContext context) { final dynamicColor = _light != null && _dark != null && Pref.dynamicColor;
final dynamicColor = Pref.dynamicColor && _light != null && _dark != null;
late final brandColor = colorThemeTypes[Pref.customColor].color; late final brandColor = colorThemeTypes[Pref.customColor].color;
late final variant = Pref.schemeVariant; late final variant = Pref.schemeVariant;
return GetMaterialApp( return (
title: Constants.appName, ThemeUtils.getThemeData(
theme: ThemeUtils.getThemeData(
colorScheme: dynamicColor colorScheme: dynamicColor
? _light! ? _light!
: brandColor.asColorSchemeSeed(variant, .light), : brandColor.asColorSchemeSeed(variant, .light),
isDynamic: dynamicColor, isDynamic: dynamicColor,
), ),
darkTheme: ThemeUtils.getThemeData( ThemeUtils.getThemeData(
isDark: true, isDark: true,
colorScheme: dynamicColor colorScheme: dynamicColor
? _dark! ? _dark!
: brandColor.asColorSchemeSeed(variant, .dark), : brandColor.asColorSchemeSeed(variant, .dark),
isDynamic: dynamicColor, isDynamic: dynamicColor,
), ),
);
}
@override
Widget build(BuildContext context) {
final (light, dark) = getAllTheme();
return GetMaterialApp(
title: Constants.appName,
theme: light,
darkTheme: dark,
themeMode: Pref.themeMode, themeMode: Pref.themeMode,
localizationsDelegates: const [ localizationsDelegates: const [
GlobalCupertinoLocalizations.delegate, GlobalCupertinoLocalizations.delegate,

View File

@@ -42,7 +42,7 @@ import 'package:PiliPlus/utils/update.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart' show kDebugMode; import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart' hide RefreshIndicator;
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
@@ -972,7 +972,7 @@ Future<void> _showRefreshDragDialog(
if (res != null) { if (res != null) {
kDragContainerExtentPercentage = res; kDragContainerExtentPercentage = res;
await GStorage.setting.put(SettingBoxKey.refreshDragPercentage, res); await GStorage.setting.put(SettingBoxKey.refreshDragPercentage, res);
Get.forceAppUpdate(); setState();
} }
} }
@@ -993,7 +993,19 @@ Future<void> _showRefreshDialog(
if (res != null) { if (res != null) {
displacement = res; displacement = res;
await GStorage.setting.put(SettingBoxKey.refreshDisplacement, res); await GStorage.setting.put(SettingBoxKey.refreshDisplacement, res);
Get.forceAppUpdate(); if (WidgetsBinding.instance.rootElement case final context?) {
context.visitChildElements(_visitor);
}
setState();
}
}
void _visitor(Element context) {
if (!context.mounted) return;
if (context.widget is RefreshIndicator) {
context.markNeedsBuild();
} else {
context.visitChildren(_visitor);
} }
} }

View File

@@ -26,6 +26,7 @@ import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart';
import 'package:PiliPlus/pages/setting/widgets/slider_dialog.dart'; import 'package:PiliPlus/pages/setting/widgets/slider_dialog.dart';
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart'; import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
import 'package:PiliPlus/utils/extension/file_ext.dart'; import 'package:PiliPlus/utils/extension/file_ext.dart';
import 'package:PiliPlus/utils/extension/get_ext.dart';
import 'package:PiliPlus/utils/extension/num_ext.dart'; import 'package:PiliPlus/utils/extension/num_ext.dart';
import 'package:PiliPlus/utils/extension/theme_ext.dart'; import 'package:PiliPlus/utils/extension/theme_ext.dart';
import 'package:PiliPlus/utils/global_data.dart'; import 'package:PiliPlus/utils/global_data.dart';
@@ -88,7 +89,7 @@ List<SettingsModel> get styleSettings => [
setKey: SettingBoxKey.appFontWeight, setKey: SettingBoxKey.appFontWeight,
defaultVal: false, defaultVal: false,
leading: const Icon(Icons.text_fields), leading: const Icon(Icons.text_fields),
onChanged: (value) => Get.forceAppUpdate(), onChanged: (_) => Get.updateMyAppTheme(),
onTap: _showFontWeightDialog, onTap: _showFontWeightDialog,
), ),
NormalModel( NormalModel(
@@ -132,7 +133,7 @@ List<SettingsModel> get styleSettings => [
defaultVal: false, defaultVal: false,
onChanged: (value) { onChanged: (value) {
if (value && MyApp.darkThemeData == null) { if (value && MyApp.darkThemeData == null) {
Get.forceAppUpdate(); Get.updateMyAppTheme();
} }
}, },
), ),
@@ -279,7 +280,7 @@ List<SettingsModel> get styleSettings => [
defaultVal: false, defaultVal: false,
onChanged: (value) { onChanged: (value) {
if (Get.isDarkMode || Pref.darkVideoPage) { if (Get.isDarkMode || Pref.darkVideoPage) {
Get.forceAppUpdate(); Get.updateMyAppTheme();
} }
}, },
), ),
@@ -634,7 +635,7 @@ Future<void> _showFontWeightDialog(BuildContext context) async {
); );
if (res != null) { if (res != null) {
await GStorage.setting.put(SettingBoxKey.appFontWeight, res.toInt() - 1); await GStorage.setting.put(SettingBoxKey.appFontWeight, res.toInt() - 1);
Get.forceAppUpdate(); Get.updateMyAppTheme();
} }
} }

View File

@@ -9,6 +9,7 @@ import 'package:PiliPlus/pages/home/view.dart';
import 'package:PiliPlus/pages/mine/controller.dart'; import 'package:PiliPlus/pages/mine/controller.dart';
import 'package:PiliPlus/pages/setting/widgets/popup_item.dart'; import 'package:PiliPlus/pages/setting/widgets/popup_item.dart';
import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart'; import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart';
import 'package:PiliPlus/utils/extension/get_ext.dart';
import 'package:PiliPlus/utils/extension/theme_ext.dart'; import 'package:PiliPlus/utils/extension/theme_ext.dart';
import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/storage_key.dart'; import 'package:PiliPlus/utils/storage_key.dart';
@@ -17,7 +18,6 @@ import 'package:flex_seed_scheme/flex_seed_scheme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:hive/hive.dart';
class ColorSelectPage extends StatefulWidget { class ColorSelectPage extends StatefulWidget {
const ColorSelectPage({super.key}); const ColorSelectPage({super.key});
@@ -44,19 +44,13 @@ class _ColorSelectPageState extends State<ColorSelectPage> {
Future<void> _onChanged([bool? val]) async { Future<void> _onChanged([bool? val]) async {
val ??= !ctr.dynamicColor.value; val ??= !ctr.dynamicColor.value;
if (val) { if (val && !await MyApp.initPlatformState()) {
if (await MyApp.initPlatformState()) { SmartDialog.showToast('设备可能不支持动态取色');
Get.forceAppUpdate();
} else {
SmartDialog.showToast('该设备可能不支持动态取色');
return; return;
} }
} else { ctr.dynamicColor.value = val;
Get.forceAppUpdate(); await GStorage.setting.put(SettingBoxKey.dynamicColor, val);
} Get.updateMyAppTheme();
ctr
..dynamicColor.value = val
..setting.put(SettingBoxKey.dynamicColor, val);
} }
@override @override
@@ -117,8 +111,9 @@ class _ColorSelectPageState extends State<ColorSelectPage> {
.toList(), .toList(),
onSelected: (value, setState) { onSelected: (value, setState) {
_dynamicSchemeVariant = value; _dynamicSchemeVariant = value;
GStorage.setting.put(SettingBoxKey.schemeVariant, value.index); GStorage.setting
Get.forceAppUpdate(); .put(SettingBoxKey.schemeVariant, value.index)
.whenComplete(Get.updateMyAppTheme);
}, },
), ),
), ),
@@ -131,10 +126,7 @@ class _ColorSelectPageState extends State<ColorSelectPage> {
value: ctr.dynamicColor.value, value: ctr.dynamicColor.value,
onChanged: _onChanged, onChanged: _onChanged,
materialTapTargetSize: .shrinkWrap, materialTapTargetSize: .shrinkWrap,
visualDensity: const VisualDensity( visualDensity: const .new(horizontal: -4, vertical: -4),
horizontal: -4,
vertical: -4,
),
), ),
), ),
onTap: _onChanged, onTap: _onChanged,
@@ -162,13 +154,10 @@ class _ColorSelectPageState extends State<ColorSelectPage> {
return GestureDetector( return GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onTap: () { onTap: () {
ctr ctr.currentColor.value = index;
..currentColor.value = index GStorage.setting
..setting.put( .put(SettingBoxKey.customColor, index)
SettingBoxKey.customColor, .whenComplete(Get.updateMyAppTheme);
index,
);
Get.forceAppUpdate();
}, },
child: Column( child: Column(
spacing: 3, spacing: 3,
@@ -236,6 +225,4 @@ class _ColorSelectController extends GetxController {
final RxBool dynamicColor = Pref.dynamicColor.obs; final RxBool dynamicColor = Pref.dynamicColor.obs;
final RxInt currentColor = Pref.customColor.obs; final RxInt currentColor = Pref.customColor.obs;
final Rx<ThemeType> themeType = Pref.themeType.obs; final Rx<ThemeType> themeType = Pref.themeType.obs;
Box get setting => GStorage.setting;
} }

View File

@@ -1,6 +1,15 @@
import 'package:PiliPlus/main.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
extension GetExt on GetInterface { extension GetExt on GetInterface {
S putOrFind<S>(InstanceBuilderCallback<S> dep, {String? tag}) => S putOrFind<S>(InstanceBuilderCallback<S> dep, {String? tag}) =>
GetInstance().putOrFind(dep, tag: tag); GetInstance().putOrFind(dep, tag: tag);
void updateMyAppTheme() {
final (l, d) = MyApp.getAllTheme();
rootController
..theme = l
..darkTheme = d
..update();
}
} }