feat: 支持 glass
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import type { BottomTabNavigationOptions } from '@react-navigation/bottom-tabs';
|
import type { BottomTabNavigationOptions } from '@react-navigation/bottom-tabs';
|
||||||
|
import { GlassContainer, GlassView, isLiquidGlassAvailable } from 'expo-glass-effect';
|
||||||
import * as Haptics from 'expo-haptics';
|
import * as Haptics from 'expo-haptics';
|
||||||
import { Tabs, usePathname } from 'expo-router';
|
import { Tabs, usePathname } from 'expo-router';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -27,6 +28,7 @@ export default function TabLayout() {
|
|||||||
const theme = (useColorScheme() ?? 'light') as 'light' | 'dark';
|
const theme = (useColorScheme() ?? 'light') as 'light' | 'dark';
|
||||||
const colorTokens = Colors[theme];
|
const colorTokens = Colors[theme];
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
|
const glassEffectAvailable = isLiquidGlassAvailable();
|
||||||
|
|
||||||
// Helper function to determine if a tab is selected
|
// Helper function to determine if a tab is selected
|
||||||
const isTabSelected = (routeName: string): boolean => {
|
const isTabSelected = (routeName: string): boolean => {
|
||||||
@@ -96,20 +98,51 @@ export default function TabLayout() {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Custom tab bar background component
|
||||||
|
const TabBarBackground = () => {
|
||||||
|
if (glassEffectAvailable) {
|
||||||
|
return (
|
||||||
|
<GlassContainer
|
||||||
|
spacing={8}
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
borderRadius: 34,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<GlassView
|
||||||
|
isInteractive
|
||||||
|
glassEffectStyle="regular"
|
||||||
|
tintColor={theme === 'dark' ? 'rgba(0,0,0,0.3)' : 'rgba(255,255,255,0.3)'}
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
borderRadius: 34,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</GlassContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
// Common screen options
|
// Common screen options
|
||||||
const getScreenOptions = (routeName: string): BottomTabNavigationOptions => ({
|
const getScreenOptions = (routeName: string): BottomTabNavigationOptions => ({
|
||||||
headerShown: false,
|
headerShown: false,
|
||||||
tabBarActiveTintColor: colorTokens.tabIconSelected,
|
tabBarActiveTintColor: colorTokens.tabIconSelected,
|
||||||
tabBarButton: createTabButton(routeName),
|
tabBarButton: createTabButton(routeName),
|
||||||
|
tabBarBackground: TabBarBackground,
|
||||||
tabBarStyle: {
|
tabBarStyle: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
bottom: TAB_BAR_BOTTOM_OFFSET,
|
bottom: TAB_BAR_BOTTOM_OFFSET,
|
||||||
height: TAB_BAR_HEIGHT,
|
height: TAB_BAR_HEIGHT,
|
||||||
borderRadius: 34,
|
borderRadius: 34,
|
||||||
backgroundColor: colorTokens.tabBarBackground,
|
backgroundColor: glassEffectAvailable ? 'transparent' : colorTokens.tabBarBackground,
|
||||||
shadowColor: '#000',
|
shadowColor: '#000',
|
||||||
shadowOffset: { width: 0, height: 2 },
|
shadowOffset: { width: 0, height: 2 },
|
||||||
shadowOpacity: 0.2,
|
shadowOpacity: glassEffectAvailable ? 0.1 : 0.2,
|
||||||
shadowRadius: 10,
|
shadowRadius: 10,
|
||||||
elevation: 5,
|
elevation: 5,
|
||||||
paddingHorizontal: 10,
|
paddingHorizontal: 10,
|
||||||
@@ -119,6 +152,8 @@ export default function TabLayout() {
|
|||||||
left: 20,
|
left: 20,
|
||||||
right: 20,
|
right: 20,
|
||||||
alignSelf: 'center',
|
alignSelf: 'center',
|
||||||
|
borderWidth: glassEffectAvailable ? 1 : 0,
|
||||||
|
borderColor: glassEffectAvailable ? (theme === 'dark' ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)') : 'transparent',
|
||||||
} as ViewStyle,
|
} as ViewStyle,
|
||||||
tabBarItemStyle: {
|
tabBarItemStyle: {
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ PODS:
|
|||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- ExpoFont (14.0.7):
|
- ExpoFont (14.0.7):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
|
- ExpoGlassEffect (0.1.1):
|
||||||
|
- ExpoModulesCore
|
||||||
- ExpoHaptics (15.0.6):
|
- ExpoHaptics (15.0.6):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- ExpoHead (6.0.0):
|
- ExpoHead (6.0.0):
|
||||||
@@ -3052,6 +3054,7 @@ DEPENDENCIES:
|
|||||||
- ExpoCamera (from `../node_modules/expo-camera/ios`)
|
- ExpoCamera (from `../node_modules/expo-camera/ios`)
|
||||||
- ExpoFileSystem (from `../node_modules/expo-file-system/ios`)
|
- ExpoFileSystem (from `../node_modules/expo-file-system/ios`)
|
||||||
- ExpoFont (from `../node_modules/expo-font/ios`)
|
- ExpoFont (from `../node_modules/expo-font/ios`)
|
||||||
|
- ExpoGlassEffect (from `../node_modules/expo-glass-effect/ios`)
|
||||||
- ExpoHaptics (from `../node_modules/expo-haptics/ios`)
|
- ExpoHaptics (from `../node_modules/expo-haptics/ios`)
|
||||||
- ExpoHead (from `../node_modules/expo-router/ios`)
|
- ExpoHead (from `../node_modules/expo-router/ios`)
|
||||||
- ExpoImage (from `../node_modules/expo-image/ios`)
|
- ExpoImage (from `../node_modules/expo-image/ios`)
|
||||||
@@ -3203,6 +3206,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: "../node_modules/expo-file-system/ios"
|
:path: "../node_modules/expo-file-system/ios"
|
||||||
ExpoFont:
|
ExpoFont:
|
||||||
:path: "../node_modules/expo-font/ios"
|
:path: "../node_modules/expo-font/ios"
|
||||||
|
ExpoGlassEffect:
|
||||||
|
:path: "../node_modules/expo-glass-effect/ios"
|
||||||
ExpoHaptics:
|
ExpoHaptics:
|
||||||
:path: "../node_modules/expo-haptics/ios"
|
:path: "../node_modules/expo-haptics/ios"
|
||||||
ExpoHead:
|
ExpoHead:
|
||||||
@@ -3426,6 +3431,7 @@ SPEC CHECKSUMS:
|
|||||||
ExpoCamera: ae1d6691b05b753261a845536d2b19a9788a8750
|
ExpoCamera: ae1d6691b05b753261a845536d2b19a9788a8750
|
||||||
ExpoFileSystem: 7b4a4f6c67a738e826fd816139bac9d098b3b084
|
ExpoFileSystem: 7b4a4f6c67a738e826fd816139bac9d098b3b084
|
||||||
ExpoFont: 74a14c605637c2d32337a2f542065408a8ca3454
|
ExpoFont: 74a14c605637c2d32337a2f542065408a8ca3454
|
||||||
|
ExpoGlassEffect: 9aa58a46e8abe720971f2b588bc1e10d58728ba8
|
||||||
ExpoHaptics: e0912a9cf05ba958eefdc595f1990b8f89aa1f3f
|
ExpoHaptics: e0912a9cf05ba958eefdc595f1990b8f89aa1f3f
|
||||||
ExpoHead: 275ef6292a9ab92669fd9554f19e1b1bbb5aa986
|
ExpoHead: 275ef6292a9ab92669fd9554f19e1b1bbb5aa986
|
||||||
ExpoImage: 18d9836939f8e271364a5a2a3566f099ea73b2e4
|
ExpoImage: 18d9836939f8e271364a5a2a3566f099ea73b2e4
|
||||||
|
|||||||
12
package-lock.json
generated
12
package-lock.json
generated
@@ -30,6 +30,7 @@
|
|||||||
"expo-camera": "~17.0.7",
|
"expo-camera": "~17.0.7",
|
||||||
"expo-constants": "~18.0.8",
|
"expo-constants": "~18.0.8",
|
||||||
"expo-font": "~14.0.7",
|
"expo-font": "~14.0.7",
|
||||||
|
"expo-glass-effect": "^0.1.1",
|
||||||
"expo-haptics": "~15.0.6",
|
"expo-haptics": "~15.0.6",
|
||||||
"expo-image": "~3.0.7",
|
"expo-image": "~3.0.7",
|
||||||
"expo-image-picker": "~17.0.7",
|
"expo-image-picker": "~17.0.7",
|
||||||
@@ -7910,6 +7911,17 @@
|
|||||||
"react-native": "*"
|
"react-native": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/expo-glass-effect": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/expo-glass-effect/-/expo-glass-effect-0.1.1.tgz",
|
||||||
|
"integrity": "sha512-81xXB2CVjgyg7gaq/fDVAOu/j43uTP0F6bI0sah81v3/guA+YfSM3QjyfegIVQPUkX/9AP2zkU9ihkHEZQv7pg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"expo": "*",
|
||||||
|
"react": "*",
|
||||||
|
"react-native": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/expo-haptics": {
|
"node_modules/expo-haptics": {
|
||||||
"version": "15.0.6",
|
"version": "15.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/expo-haptics/-/expo-haptics-15.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/expo-haptics/-/expo-haptics-15.0.6.tgz",
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
"expo-camera": "~17.0.7",
|
"expo-camera": "~17.0.7",
|
||||||
"expo-constants": "~18.0.8",
|
"expo-constants": "~18.0.8",
|
||||||
"expo-font": "~14.0.7",
|
"expo-font": "~14.0.7",
|
||||||
|
"expo-glass-effect": "^0.1.1",
|
||||||
"expo-haptics": "~15.0.6",
|
"expo-haptics": "~15.0.6",
|
||||||
"expo-image": "~3.0.7",
|
"expo-image": "~3.0.7",
|
||||||
"expo-image-picker": "~17.0.7",
|
"expo-image-picker": "~17.0.7",
|
||||||
@@ -80,4 +81,4 @@
|
|||||||
"typescript": "~5.9.2"
|
"typescript": "~5.9.2"
|
||||||
},
|
},
|
||||||
"private": true
|
"private": true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user