- 新增删除营养分析记录功能,支持本地状态更新和API调用 - 添加图片全屏预览功能,支持缩放和手势操作 - 实现Liquid Glass风格的删除按钮,包含兼容性处理 - 优化历史记录页面布局和交互体验 - 更新Memory Bank文档,添加Liquid Glass按钮实现指南
148 lines
4.3 KiB
Markdown
148 lines
4.3 KiB
Markdown
# 常见任务和模式
|
||
|
||
## HeaderBar 顶部距离处理
|
||
|
||
**最后更新**: 2025-10-16
|
||
|
||
### 问题描述
|
||
当使用 HeaderBar 组件时,需要正确处理内容区域的顶部距离,确保内容不会被状态栏或刘海屏遮挡。
|
||
|
||
### 解决方案
|
||
使用 `useSafeAreaTop` hook 获取安全区域顶部距离,并应用到内容容器的样式中。
|
||
|
||
### 实现模式
|
||
|
||
#### 1. 导入必要的 hook
|
||
```typescript
|
||
import { useSafeAreaTop } from '@/hooks/useSafeAreaWithPadding';
|
||
```
|
||
|
||
#### 2. 在组件中获取 safeAreaTop
|
||
```typescript
|
||
const safeAreaTop = useSafeAreaTop()
|
||
```
|
||
|
||
#### 3. 应用到内容容器
|
||
```typescript
|
||
// 方式1: 直接应用到 View 组件
|
||
<View style={[styles.filterContainer, { paddingTop: safeAreaTop }]}>
|
||
|
||
// 方式2: 应用到 ScrollView 的 contentContainerStyle
|
||
<ScrollView
|
||
contentContainerStyle={{ paddingTop: safeAreaTop }}
|
||
>
|
||
|
||
// 方式3: 应用到 SectionList 的 style
|
||
<SectionList
|
||
style={{ paddingTop: safeAreaTop }}
|
||
>
|
||
```
|
||
|
||
### 重要注意事项
|
||
1. **不要在 StyleSheet 中使用变量**:不能在 `StyleSheet.create()` 中直接使用 `safeAreaTop` 变量
|
||
2. **使用动态样式**:必须通过内联样式或数组样式的方式动态应用 `safeAreaTop`
|
||
3. **不需要额外偏移**:通常只需要 `safeAreaTop`,不需要添加额外的固定像素值
|
||
|
||
### 示例代码
|
||
```typescript
|
||
// ❌ 错误写法 - 在 StyleSheet 中使用变量
|
||
const styles = StyleSheet.create({
|
||
filterContainer: {
|
||
paddingTop: safeAreaTop, // 这会导致错误
|
||
},
|
||
});
|
||
|
||
// ✅ 正确写法 - 使用动态样式
|
||
<View style={[styles.filterContainer, { paddingTop: safeAreaTop }]}>
|
||
```
|
||
|
||
### 参考页面
|
||
- `app/steps/detail.tsx`
|
||
- `app/water/detail.tsx`
|
||
- `app/profile/goals.tsx`
|
||
- `app/workout/history.tsx`
|
||
- `app/challenges/[id]/leaderboard.tsx`
|
||
|
||
## Liquid Glass 风格图标按钮实现
|
||
|
||
**最后更新**: 2025-10-16
|
||
|
||
### 问题描述
|
||
在应用中实现符合 Liquid Glass 设计风格的图标按钮,需要考虑毛玻璃效果和兼容性处理。
|
||
|
||
### 解决方案
|
||
使用 `GlassView` 组件实现毛玻璃效果,并提供不支持 Liquid Glass 的设备的降级方案。
|
||
|
||
### 实现模式
|
||
|
||
#### 1. 导入必要的组件和函数
|
||
```typescript
|
||
import { GlassView, isLiquidGlassAvailable } from 'expo-glass-effect';
|
||
```
|
||
|
||
#### 2. 检查设备支持情况
|
||
```typescript
|
||
const isGlassAvailable = isLiquidGlassAvailable();
|
||
```
|
||
|
||
#### 3. 实现条件渲染的按钮
|
||
```typescript
|
||
<TouchableOpacity
|
||
onPress={handlePress}
|
||
disabled={isLoading}
|
||
activeOpacity={0.7}
|
||
>
|
||
{isGlassAvailable ? (
|
||
<GlassView
|
||
style={styles.glassButton}
|
||
glassEffectStyle="clear" // 或 "regular"
|
||
tintColor="rgba(244, 67, 54, 0.2)" // 自定义色调
|
||
isInteractive={true} // 启用交互反馈
|
||
>
|
||
<Ionicons name="trash-outline" size={20} color="#F44336" />
|
||
</GlassView>
|
||
) : (
|
||
<View style={[styles.glassButton, styles.fallbackButton]}>
|
||
<Ionicons name="trash-outline" size={20} color="#F44336" />
|
||
</View>
|
||
)}
|
||
</TouchableOpacity>
|
||
```
|
||
|
||
#### 4. 定义样式
|
||
```typescript
|
||
const styles = StyleSheet.create({
|
||
glassButton: {
|
||
width: 36,
|
||
height: 36,
|
||
borderRadius: 18, // 圆形按钮
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
overflow: 'hidden', // 保证玻璃边界圆角效果
|
||
},
|
||
fallbackButton: {
|
||
borderWidth: 1,
|
||
borderColor: 'rgba(244, 67, 54, 0.3)',
|
||
backgroundColor: 'rgba(244, 67, 54, 0.1)',
|
||
},
|
||
});
|
||
```
|
||
|
||
### 重要注意事项
|
||
1. **兼容性处理**:必须使用 `isLiquidGlassAvailable()` 检查设备支持情况
|
||
2. **overflow: 'hidden'**:GlassView 组件需要设置此属性以保证圆角效果
|
||
3. **降级样式**:为不支持 Liquid Glass 的设备提供视觉上相似的替代方案
|
||
4. **交互反馈**:设置 `isInteractive={true}` 启用原生的触觉反馈
|
||
5. **色调自定义**:通过 `tintColor` 属性自定义按钮的颜色主题
|
||
|
||
### 常用配置
|
||
- **glassEffectStyle**: "clear"(透明)或 "regular"(常规)
|
||
- **tintColor**: 根据按钮功能选择合适的颜色
|
||
- 删除操作:红色系 `rgba(244, 67, 54, 0.2)`
|
||
- 确认操作:绿色系 `rgba(76, 175, 80, 0.2)`
|
||
- 信息操作:蓝色系 `rgba(33, 150, 243, 0.2)`
|
||
|
||
### 参考实现
|
||
- `app/food/nutrition-analysis-history.tsx` - 删除按钮实现
|
||
- `components/glass/button.tsx` - 通用 Glass 按钮组件
|
||
- `app/(tabs)/_layout.tsx` - 标签栏按钮实现 |