refactor(ui): redesign TabBar to border-bottom indicator style
- Remove pill container styling with shadows and rounded corners - Simplify tab styling and reduce font weights - Change active indicator from 20px to span 50% width - Add channel tag display to PostDetailScreen - Simplify SafeAreaView edge handling in embedded screens
This commit is contained in:
@@ -135,33 +135,21 @@ function createTabBarStyles(colors: AppColors) {
|
|||||||
modernContainer: {
|
modernContainer: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
backgroundColor: colors.background.paper,
|
backgroundColor: colors.background.paper,
|
||||||
borderRadius: borderRadius['2xl'],
|
borderBottomWidth: 1,
|
||||||
marginHorizontal: spacing.lg,
|
borderBottomColor: colors.divider,
|
||||||
marginVertical: spacing.sm,
|
alignItems: 'center',
|
||||||
padding: spacing.xs,
|
paddingRight: spacing.xs,
|
||||||
shadowColor: colors.chat.shadow,
|
|
||||||
shadowOffset: { width: 0, height: 4 },
|
|
||||||
shadowOpacity: 0.1,
|
|
||||||
shadowRadius: 16,
|
|
||||||
elevation: 6,
|
|
||||||
},
|
},
|
||||||
modernTab: {
|
modernTab: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
paddingVertical: spacing.md,
|
paddingVertical: spacing.md,
|
||||||
paddingHorizontal: spacing.sm,
|
|
||||||
borderRadius: borderRadius.lg,
|
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
},
|
},
|
||||||
modernTabActive: {
|
modernTabActive: {
|
||||||
backgroundColor: colors.primary.main + '12',
|
backgroundColor: 'transparent',
|
||||||
shadowColor: colors.primary.main + '20',
|
|
||||||
shadowOffset: { width: 0, height: 2 },
|
|
||||||
shadowOpacity: 0.1,
|
|
||||||
shadowRadius: 8,
|
|
||||||
elevation: 3,
|
|
||||||
},
|
},
|
||||||
modernTabContent: {
|
modernTabContent: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
@@ -172,19 +160,21 @@ function createTabBarStyles(colors: AppColors) {
|
|||||||
marginRight: spacing.xs,
|
marginRight: spacing.xs,
|
||||||
},
|
},
|
||||||
modernTabText: {
|
modernTabText: {
|
||||||
fontWeight: '600',
|
fontWeight: '500',
|
||||||
fontSize: fontSizes.md,
|
fontSize: fontSizes.md,
|
||||||
},
|
},
|
||||||
modernTabTextActive: {
|
modernTabTextActive: {
|
||||||
fontWeight: '700',
|
fontWeight: '600',
|
||||||
},
|
},
|
||||||
modernTabIndicator: {
|
modernTabIndicator: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
bottom: 4,
|
bottom: 0,
|
||||||
width: 20,
|
left: '25%',
|
||||||
|
right: '25%',
|
||||||
height: 3,
|
height: 3,
|
||||||
backgroundColor: colors.primary.main,
|
backgroundColor: colors.primary.main,
|
||||||
borderRadius: borderRadius.full,
|
borderTopLeftRadius: borderRadius.sm,
|
||||||
|
borderTopRightRadius: borderRadius.sm,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -942,7 +942,7 @@ export const HomeScreen: React.FC = () => {
|
|||||||
// 搜索页面内嵌模式
|
// 搜索页面内嵌模式
|
||||||
if (showSearch) {
|
if (showSearch) {
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={styles.container} edges={['top', 'bottom']}>
|
<SafeAreaView style={styles.container} edges={['bottom']}>
|
||||||
<StatusBar barStyle={statusBarStyle} backgroundColor={colors.background.paper} />
|
<StatusBar barStyle={statusBarStyle} backgroundColor={colors.background.paper} />
|
||||||
<SearchScreen
|
<SearchScreen
|
||||||
onBack={() => setShowSearch(false)}
|
onBack={() => setShowSearch(false)}
|
||||||
|
|||||||
@@ -1140,6 +1140,18 @@ export const PostDetailScreen: React.FC = () => {
|
|||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* 所属板块 */}
|
||||||
|
{!!post.channel?.name && (
|
||||||
|
<View style={[styles.channelTagContainer, { marginTop: responsiveGap }]}>
|
||||||
|
<View style={styles.channelTag}>
|
||||||
|
<MaterialCommunityIcons name="tag-outline" size={11} color={colors.primary.main} />
|
||||||
|
<Text style={styles.channelTagText} numberOfLines={1}>
|
||||||
|
{post.channel.name}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* 发帖时间和浏览量 - 放在图片下方 */}
|
{/* 发帖时间和浏览量 - 放在图片下方 */}
|
||||||
<View style={[styles.postMetaInfo, { marginTop: responsiveGap }]}>
|
<View style={[styles.postMetaInfo, { marginTop: responsiveGap }]}>
|
||||||
<View style={styles.metaInfoMain}>
|
<View style={styles.metaInfoMain}>
|
||||||
@@ -2226,6 +2238,27 @@ function createPostDetailStyles(colors: AppColors) {
|
|||||||
marginTop: spacing.md,
|
marginTop: spacing.md,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
|
// 所属板块标签
|
||||||
|
channelTagContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
channelTag: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
maxWidth: 140,
|
||||||
|
paddingHorizontal: 6,
|
||||||
|
paddingVertical: 2,
|
||||||
|
borderRadius: borderRadius.sm,
|
||||||
|
backgroundColor: `${colors.primary.main}12`,
|
||||||
|
gap: 4,
|
||||||
|
},
|
||||||
|
channelTagText: {
|
||||||
|
fontSize: fontSizes.xs,
|
||||||
|
color: colors.primary.main,
|
||||||
|
fontWeight: '600',
|
||||||
|
flexShrink: 1,
|
||||||
|
},
|
||||||
// 评论加载更多样式
|
// 评论加载更多样式
|
||||||
commentsLoadingFooter: {
|
commentsLoadingFooter: {
|
||||||
paddingVertical: spacing.md,
|
paddingVertical: spacing.md,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
ScrollView,
|
ScrollView,
|
||||||
RefreshControl,
|
RefreshControl,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||||
import { useRouter } from 'expo-router';
|
import { useRouter } from 'expo-router';
|
||||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||||
import { spacing, fontSizes, borderRadius, useAppColors, type AppColors } from '../../theme';
|
import { spacing, fontSizes, borderRadius, useAppColors, type AppColors } from '../../theme';
|
||||||
@@ -41,7 +41,6 @@ export const SearchScreen: React.FC<SearchScreenProps> = ({ onBack }) => {
|
|||||||
const colors = useAppColors();
|
const colors = useAppColors();
|
||||||
const styles = useMemo(() => createSearchScreenStyles(colors), [colors]);
|
const styles = useMemo(() => createSearchScreenStyles(colors), [colors]);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const insets = useSafeAreaInsets();
|
|
||||||
const { searchHistory: history, addSearchHistory, clearSearchHistory } = useUserStore();
|
const { searchHistory: history, addSearchHistory, clearSearchHistory } = useUserStore();
|
||||||
|
|
||||||
// 使用响应式 hook
|
// 使用响应式 hook
|
||||||
@@ -494,13 +493,13 @@ export const SearchScreen: React.FC<SearchScreenProps> = ({ onBack }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={styles.container} edges={['bottom']}>
|
<SafeAreaView style={styles.container} edges={['top', 'bottom']}>
|
||||||
{/* 搜索输入框 */}
|
{/* 搜索输入框 */}
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
styles.searchHeader,
|
styles.searchHeader,
|
||||||
{
|
{
|
||||||
paddingTop: Math.max(spacing.sm, insets.top + spacing.xs),
|
paddingTop: spacing.sm,
|
||||||
paddingHorizontal: responsivePadding,
|
paddingHorizontal: responsivePadding,
|
||||||
paddingBottom: spacing.xs,
|
paddingBottom: spacing.xs,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -677,7 +677,7 @@ export const MessageListScreen: React.FC = () => {
|
|||||||
const renderSearchMode = () => (
|
const renderSearchMode = () => (
|
||||||
<View style={styles.searchModeContainer}>
|
<View style={styles.searchModeContainer}>
|
||||||
{/* 搜索头部 */}
|
{/* 搜索头部 */}
|
||||||
<View style={[styles.searchHeader, { paddingTop: Math.max(spacing.sm, insets.top + spacing.xs) }]}>
|
<View style={[styles.searchHeader, { paddingTop: spacing.sm }]}>
|
||||||
<View style={styles.searchShell}>
|
<View style={styles.searchShell}>
|
||||||
<SearchBar
|
<SearchBar
|
||||||
value={searchText}
|
value={searchText}
|
||||||
|
|||||||
Reference in New Issue
Block a user