尝试消除ios播放页全屏底部空白条

添加flutter_launcher_icons生成ios平台图标
This commit is contained in:
rang 2025-10-28 17:34:25 +08:00
parent 23169a2738
commit 688291e401
28 changed files with 276 additions and 374 deletions

View file

@ -23,6 +23,7 @@
"Vaani" "Vaani"
], ],
"dart.flutterSdkPath": ".fvm/versions/3.32.0", "dart.flutterSdkPath": ".fvm/versions/3.32.0",
"dart.lineLength": 80,
"files.exclude": { "files.exclude": {
"**/*.freezed.dart": true, "**/*.freezed.dart": true,
"**/*.g.dart": true "**/*.g.dart": true

View file

@ -428,7 +428,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
@ -485,7 +485,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";

View file

@ -1,122 +1 @@
{ {"images":[{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@3x.png","scale":"3x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@3x.png","scale":"3x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@3x.png","scale":"3x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@1x.png","scale":"1x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@3x.png","scale":"3x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@1x.png","scale":"1x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@1x.png","scale":"1x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@1x.png","scale":"1x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@2x.png","scale":"2x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@1x.png","scale":"1x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@2x.png","scale":"2x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@1x.png","scale":"1x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@2x.png","scale":"2x"},{"size":"83.5x83.5","idiom":"ipad","filename":"Icon-App-83.5x83.5@2x.png","scale":"2x"},{"size":"1024x1024","idiom":"ios-marketing","filename":"Icon-App-1024x1024@1x.png","scale":"1x"}],"info":{"version":1,"author":"xcode"}}
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 220 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

After

Width:  |  Height:  |  Size: 983 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 2.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 4.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 B

After

Width:  |  Height:  |  Size: 4.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 7.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 2.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 6.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 11 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 11 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 762 B

After

Width:  |  Height:  |  Size: 5.8 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

View file

@ -144,7 +144,7 @@ class PlayerWhenMinimized extends HookConsumerWidget {
// value: (progress.data ?? Duration.zero).inSeconds / // value: (progress.data ?? Duration.zero).inSeconds /
// player.book!.duration.inSeconds, // player.book!.duration.inSeconds,
value: (progress.data ?? Duration.zero).inSeconds / value: (progress.data ?? Duration.zero).inSeconds /
player.duration!.inSeconds, (player.duration?.inSeconds ?? 1),
color: Theme.of(context).colorScheme.onPrimaryContainer, color: Theme.of(context).colorScheme.onPrimaryContainer,
backgroundColor: Theme.of(context).colorScheme.primaryContainer, backgroundColor: Theme.of(context).colorScheme.primaryContainer,
), ),

View file

@ -36,8 +36,10 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final size = MediaQuery.of(context).size;
final playerProgress = ref.watch(playerHeightProvider); final playerProgress = ref.watch(playerHeightProvider);
final isMobile = Platform.isFuchsia || Platform.isAndroid || Platform.isIOS; final isMobile = Platform.isAndroid || Platform.isIOS || Platform.isFuchsia;
final isVertical = size.height > size.width;
onBackButtonPressed() async { onBackButtonPressed() async {
final isPlayerExpanded = playerProgress != playerMinHeight; final isPlayerExpanded = playerProgress != playerMinHeight;
@ -93,11 +95,14 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
child: Scaffold( child: Scaffold(
body: Stack( body: Stack(
children: [ children: [
isMobile ? navigationShell : buildNavLeft(context, ref), isMobile && isVertical
? navigationShell
: buildNavLeft(context, ref),
const AudiobookPlayer(), const AudiobookPlayer(),
], ],
), ),
bottomNavigationBar: isMobile ? buildNavBottom(context, ref) : null, bottomNavigationBar:
isMobile && isVertical ? buildNavBottom(context, ref) : null,
), ),
); );
} }
@ -165,17 +170,16 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
); );
} }
Widget buildNavBottom(BuildContext context, WidgetRef ref) { Widget? buildNavBottom(BuildContext context, WidgetRef ref) {
// playerExpandProgress is used to animate bottom navigation bar to opacity 0 and slide down when player is expanded final size = MediaQuery.of(context).size;
// final playerProgress =
// useValueListenable(ref.watch(playerExpandProgressNotifierProvider));
final playerProgress = ref.watch(playerHeightProvider); final playerProgress = ref.watch(playerHeightProvider);
final playerMaxHeight = MediaQuery.of(context).size.height; final playerMaxHeight = size.height;
var percentExpandedMiniPlayer = (playerProgress - playerMinHeight) / var percentExpandedMiniPlayer = (playerProgress - playerMinHeight) /
(playerMaxHeight - playerMinHeight); (playerMaxHeight - playerMinHeight);
// Clamp the value between 0 and 1 // Clamp the value between 0 and 1
percentExpandedMiniPlayer = percentExpandedMiniPlayer.clamp(0.0, 1.0); percentExpandedMiniPlayer = percentExpandedMiniPlayer.clamp(0.0, 1.0);
return Opacity( return percentExpandedMiniPlayer == 1
? Opacity(
// Opacity is interpolated from 1 to 0 when player is expanded // Opacity is interpolated from 1 to 0 when player is expanded
opacity: 1 - percentExpandedMiniPlayer, opacity: 1 - percentExpandedMiniPlayer,
child: NavigationBar( child: NavigationBar(
@ -189,7 +193,8 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
// `navigationShell.route.branches`. // `navigationShell.route.branches`.
destinations: _navigationItems(context).map((item) { destinations: _navigationItems(context).map((item) {
final isDestinationLibrary = item.name == S.of(context).library; final isDestinationLibrary = item.name == S.of(context).library;
var currentLibrary = ref.watch(currentLibraryProvider).valueOrNull; var currentLibrary =
ref.watch(currentLibraryProvider).valueOrNull;
final libraryIcon = AbsIcons.getIconByName( final libraryIcon = AbsIcons.getIconByName(
currentLibrary?.icon, currentLibrary?.icon,
); );
@ -211,7 +216,8 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
return GestureDetector( return GestureDetector(
onSecondaryTap: () => showLibrarySwitcher(context, ref), onSecondaryTap: () => showLibrarySwitcher(context, ref),
onDoubleTap: () => showLibrarySwitcher(context, ref), onDoubleTap: () => showLibrarySwitcher(context, ref),
child: destinationWidget, // Wrap the actual NavigationDestination child:
destinationWidget, // Wrap the actual NavigationDestination
); );
} else { } else {
// Return the unwrapped destination for other items // Return the unwrapped destination for other items
@ -221,7 +227,8 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
selectedIndex: navigationShell.currentIndex, selectedIndex: navigationShell.currentIndex,
onDestinationSelected: (int index) => _onTap(context, index, ref), onDestinationSelected: (int index) => _onTap(context, index, ref),
), ),
); )
: null;
} }
List<_NavigationItem> _navigationItems(BuildContext context) { List<_NavigationItem> _navigationItems(BuildContext context) {

File diff suppressed because it is too large Load diff

View file

@ -108,6 +108,7 @@ dev_dependencies:
json_serializable: ^6.8.0 json_serializable: ^6.8.0
riverpod_generator: ^2.4.2 riverpod_generator: ^2.4.2
riverpod_lint: ^2.3.10 riverpod_lint: ^2.3.10
flutter_launcher_icons: "^0.14.4"
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec
@ -156,3 +157,9 @@ flutter:
- asset: assets/fonts/AbsIcons.ttf - asset: assets/fonts/AbsIcons.ttf
flutter_intl: flutter_intl:
enabled: true enabled: true
flutter_launcher_icons:
android: false # 如果只为iOS配置可关闭Android
ios: true
image_path: "assets/icon/logo.png" # 你的1024x1024源图标路径
remove_alpha_ios: true # 建议设为true移除透明度符合App Store审核要求[citation:6]