调整详情页样式

This commit is contained in:
yuchenglong
2026-01-14 10:34:59 +08:00
parent ef7e4ae142
commit c936f3ba6b
4 changed files with 175 additions and 127 deletions

View File

@@ -9,7 +9,10 @@ interface BasketballScoreTableProps {
isDark: boolean;
}
export function BasketballScoreTable({ data, isDark }: BasketballScoreTableProps) {
export function BasketballScoreTable({
data,
isDark,
}: BasketballScoreTableProps) {
const { t } = useTranslation();
const { match } = data;
const bgColor = isDark ? "#1C1C1E" : "#FFF";
@@ -29,10 +32,10 @@ export function BasketballScoreTable({ data, isDark }: BasketballScoreTableProps
const headers = [
t("detail.score_table.team"),
t("detail.score_table.total"),
"Q1",
"Q2",
"Q3",
"Q4",
"1",
"2",
"3",
"4",
];
const rows = [
@@ -84,7 +87,9 @@ export function BasketballScoreTable({ data, isDark }: BasketballScoreTableProps
{row.name}
</ThemedText>
</View>
<ThemedText style={styles.cellText}>{row.total}</ThemedText>
<ThemedText style={[styles.cellText, styles.totalText]}>
{row.total}
</ThemedText>
<ThemedText style={styles.cellText}>{row.q1}</ThemedText>
<ThemedText style={styles.cellText}>{row.q2}</ThemedText>
<ThemedText style={styles.cellText}>{row.q3}</ThemedText>
@@ -97,54 +102,61 @@ export function BasketballScoreTable({ data, isDark }: BasketballScoreTableProps
const styles = StyleSheet.create({
container: {
margin: 16,
borderRadius: 12,
padding: 16,
marginHorizontal: 16,
marginBottom: 16,
borderRadius: 16,
padding: 20,
elevation: 2,
shadowColor: "#000",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
shadowOpacity: 0.05,
shadowRadius: 8,
},
header: {
flexDirection: "row",
paddingBottom: 12,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: "rgba(150,150,150,0.2)",
paddingBottom: 16,
borderBottomWidth: 1,
borderBottomColor: "rgba(150,150,150,0.1)",
},
headerText: {
fontSize: 12,
fontWeight: "500",
fontWeight: "600",
opacity: 0.8,
},
row: {
flexDirection: "row",
alignItems: "center",
paddingVertical: 12,
paddingVertical: 14,
},
rowBorder: {
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomWidth: 1,
borderBottomColor: "rgba(150,150,150,0.1)",
},
teamCell: {
flex: 3,
flexDirection: "row",
alignItems: "center",
gap: 8,
gap: 10,
},
teamLogo: {
width: 24,
height: 24,
width: 28,
height: 28,
resizeMode: "contain",
},
teamName: {
flex: 1,
fontSize: 14,
fontWeight: "500",
fontWeight: "700",
},
cellText: {
flex: 1,
textAlign: "center",
fontSize: 14,
fontWeight: "500",
opacity: 0.8,
},
totalText: {
fontWeight: "700",
opacity: 1,
},
});

View File

@@ -11,8 +11,10 @@ interface LeagueInfoProps {
export function LeagueInfo({ data, isDark }: LeagueInfoProps) {
const { match } = data;
const bgColor = isDark ? "#1C1C1E" : "#FFF";
const borderColor = isDark ? "#2C2C2E" : "#EEE";
// Force dark style for this component to match the header design language
const bgColor = "#121212";
const borderColor = "rgba(255,255,255,0.1)";
const textColor = "#FFF";
return (
<TouchableOpacity
@@ -26,26 +28,15 @@ export function LeagueInfo({ data, isDark }: LeagueInfoProps) {
{match.leagueLogo ? (
<Image source={{ uri: match.leagueLogo }} style={styles.leagueLogo} />
) : (
<View
style={[
styles.fallbackLogo,
{ backgroundColor: isDark ? "#333" : "#F0F0F0" },
]}
>
<IconSymbol
name="trophy-outline"
size={14}
color={isDark ? "#AAA" : "#888"}
/>
<View style={[styles.fallbackLogo, { backgroundColor: "#333" }]}>
<IconSymbol name="trophy-outline" size={14} color="#AAA" />
</View>
)}
<ThemedText style={styles.leagueName}>{match.leagueName}</ThemedText>
<ThemedText style={[styles.leagueName, { color: textColor }]}>
{match.leagueName}
</ThemedText>
</View>
<IconSymbol
name="chevron-forward"
size={16}
color={isDark ? "#666" : "#CCC"}
/>
<IconSymbol name="chevron-forward" size={16} color="#888" />
</TouchableOpacity>
);
}
@@ -56,7 +47,7 @@ const styles = StyleSheet.create({
alignItems: "center",
justifyContent: "space-between",
paddingHorizontal: 16,
paddingVertical: 12,
paddingVertical: 14,
borderBottomWidth: 1,
},
left: {

View File

@@ -1,4 +1,5 @@
import { ThemedText } from "@/components/themed-text";
import { IconSymbol, IconSymbolName } from "@/components/ui/icon-symbol";
import React from "react";
import { useTranslation } from "react-i18next";
import { ScrollView, StyleSheet, TouchableOpacity, View } from "react-native";
@@ -10,35 +11,62 @@ interface MatchTabsProps {
sportId: number;
}
export function MatchTabs({ activeTab, onTabChange, isDark, sportId }: MatchTabsProps) {
export function MatchTabs({
activeTab,
onTabChange,
isDark,
sportId,
}: MatchTabsProps) {
const { t } = useTranslation();
const containerBg = isDark ? "#121212" : "#F8F8F8";
const containerBg = isDark ? "#121212" : "#F5F5F5";
// 根据 sportId 动态生成标签
const getTabs = () => {
// 使用 Ionicons 名称
const commonTabs = [
{
id: "info",
label: t("detail.tabs.info"),
icon: "document-text-outline",
},
{
id: "h2h",
label: t("detail.tabs.h2h"),
icon: "swap-horizontal-outline",
},
{ id: "chat", label: t("detail.tabs.chat"), icon: "chatbubbles-outline" },
];
if (sportId === 1) {
// 足球: 详情、统计数据、赔率、交锋往绩、聊天
return [
{ id: "info", label: t("detail.tabs.info") },
{ id: "stats", label: t("detail.tabs.stats") },
{ id: "odds", label: t("detail.tabs.odds") },
{ id: "h2h", label: t("detail.tabs.h2h") },
{ id: "chat", label: t("detail.tabs.chat") },
{
id: "info",
label: t("detail.tabs.info"),
icon: "document-text-outline",
},
{
id: "stats",
label: t("detail.tabs.stats"),
icon: "stats-chart-outline",
},
{ id: "odds", label: t("detail.tabs.odds"), icon: "cash-outline" },
{
id: "h2h",
label: t("detail.tabs.h2h"),
icon: "swap-horizontal-outline",
},
{
id: "chat",
label: t("detail.tabs.chat"),
icon: "chatbubbles-outline",
},
];
} else if (sportId === 2) {
// 篮球: 详情、交锋往绩、聊天
return [
{ id: "info", label: t("detail.tabs.info") },
{ id: "h2h", label: t("detail.tabs.h2h") },
{ id: "chat", label: t("detail.tabs.chat") },
];
// 篮球
return commonTabs;
}
// 默认: 详情、交锋往绩、聊天
return [
{ id: "info", label: t("detail.tabs.info") },
{ id: "h2h", label: t("detail.tabs.h2h") },
{ id: "chat", label: t("detail.tabs.chat") },
];
return commonTabs;
};
const tabs = getTabs();
@@ -52,23 +80,40 @@ export function MatchTabs({ activeTab, onTabChange, isDark, sportId }: MatchTabs
>
{tabs.map((tab) => {
const isActive = activeTab === tab.id;
const activeColor = "#FF9800"; // 橙色
const inactiveColor = isDark ? "#AAA" : "#666"; // 增强对比度
const inactiveBg = isDark
? "rgba(255,255,255,0.05)"
: "rgba(0,0,0,0.03)";
return (
<TouchableOpacity
key={tab.id}
onPress={() => onTabChange(tab.id)}
style={[
styles.tabBtn,
isActive && styles.activeTabBtn,
isActive && {
backgroundColor: isDark ? "rgba(255,255,255,0.05)" : "#FFF",
{
backgroundColor: isActive
? isDark
? "#2C2C2E"
: "#FFF"
: inactiveBg,
},
]}
>
<IconSymbol
name={tab.icon as IconSymbolName}
size={16}
color={isActive ? activeColor : inactiveColor}
style={{ marginRight: 6 }}
/>
<ThemedText
style={[
styles.tabText,
isActive && styles.activeTabText,
isActive && { color: "#FF9800" },
{
color: isActive ? activeColor : inactiveColor,
fontWeight: isActive ? "700" : "500", // 强化选中粗体
},
]}
>
{tab.label}
@@ -83,34 +128,23 @@ export function MatchTabs({ activeTab, onTabChange, isDark, sportId }: MatchTabs
const styles = StyleSheet.create({
container: {
paddingVertical: 12,
paddingVertical: 8,
},
scrollContent: {
paddingHorizontal: 16,
gap: 12,
gap: 10,
alignItems: "center", // 确保所有 tabBtn 垂直对齐
},
tabBtn: {
paddingHorizontal: 20,
paddingVertical: 8,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
paddingHorizontal: 15,
paddingVertical: 6,
borderRadius: 20,
borderWidth: 1,
borderColor: "transparent",
},
activeTabBtn: {
borderColor: "rgba(255,152,0,0.3)",
// Shadow for iOS/Android if needed
elevation: 2,
shadowColor: "#000",
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 2,
},
tabText: {
fontSize: 14,
fontWeight: "500",
opacity: 0.6,
},
activeTabText: {
opacity: 1,
includeFontPadding: false, // 移除 Android 字体默认内边距
},
});

View File

@@ -20,8 +20,10 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
return (
<LinearGradient
colors={["#1A2138", "#2A3C5B"]}
style={[styles.container, { paddingTop: Math.max(topInset, 20) }]}
colors={["#521e10", "#0e0e10"]}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
style={[styles.container, { paddingTop: Math.max(topInset, 10) }]}
>
{/* Top Bar */}
<View style={styles.topBar}>
@@ -30,7 +32,7 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
onPress={() => router.back()}
style={styles.iconBtn}
>
<IconSymbol name="chevron-back" size={24} color="#FFF" />
<IconSymbol name="chevron-back" size={28} color="#FFF" />
</TouchableOpacity>
</View>
@@ -42,10 +44,10 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
<View style={styles.rightContainer}>
<TouchableOpacity style={styles.iconBtn}>
<IconSymbol name="notifications-outline" size={22} color="#FFF" />
<IconSymbol name="notifications-outline" size={24} color="#FFF" />
</TouchableOpacity>
<TouchableOpacity style={styles.iconBtn}>
<IconSymbol name="star-outline" size={22} color="#FFF" />
<IconSymbol name="star-outline" size={24} color="#FFF" />
</TouchableOpacity>
</View>
</View>
@@ -95,14 +97,14 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
const styles = StyleSheet.create({
container: {
paddingBottom: 30,
paddingBottom: 24,
paddingHorizontal: 16,
},
topBar: {
flexDirection: "row",
alignItems: "center",
marginBottom: 20,
minHeight: 40,
marginBottom: 16,
minHeight: 44,
},
leftContainer: {
flex: 1,
@@ -119,78 +121,87 @@ const styles = StyleSheet.create({
flexDirection: "row",
justifyContent: "flex-end",
alignItems: "center",
gap: 12,
gap: 4,
},
statusText: {
color: "#FFF",
fontSize: 16,
fontSize: 17,
fontWeight: "600",
opacity: 0.8,
},
rightIcons: {
flexDirection: "row",
gap: 12,
opacity: 0.9,
},
iconBtn: {
width: 36,
height: 36,
width: 40,
height: 40,
justifyContent: "center",
alignItems: "center",
borderRadius: 20,
backgroundColor: "rgba(255,255,255,0.1)",
marginHorizontal: 4,
},
scoreRow: {
flexDirection: "row",
alignItems: "center",
alignItems: "flex-start",
justifyContent: "space-between",
paddingHorizontal: 10,
paddingHorizontal: 0,
marginTop: 10,
},
teamInfo: {
flex: 1.2,
flex: 1,
alignItems: "center",
},
logoContainer: {
width: 64,
height: 64,
borderRadius: 32,
backgroundColor: "rgba(255,255,255,0.1)",
width: 70,
height: 70,
marginBottom: 10,
justifyContent: "center",
alignItems: "center",
marginBottom: 8,
overflow: "hidden",
},
teamLogo: {
width: 48,
height: 48,
width: 60,
height: 60,
resizeMode: "contain",
},
teamName: {
color: "#FFF",
fontSize: 14,
fontWeight: "600",
fontWeight: "700",
textAlign: "center",
lineHeight: 18,
},
centerScore: {
flex: 1,
flex: 1.4,
alignItems: "center",
paddingTop: 8,
},
scoreBox: {
backgroundColor: "#FFF",
borderRadius: 12,
paddingHorizontal: 16,
paddingVertical: 8,
marginBottom: 12,
borderRadius: 16,
paddingHorizontal: 24,
paddingVertical: 12,
marginBottom: 16,
minWidth: 100,
alignItems: "center",
shadowColor: "#000",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.2,
shadowRadius: 4,
elevation: 4,
},
scoreValue: {
color: "#000",
fontSize: 19,
fontWeight: "bold",
letterSpacing: 2,
fontSize: 30,
fontWeight: "700",
lineHeight: 30,
letterSpacing: 1,
},
fieldBtn: {
backgroundColor: "#0055FF",
width: 80,
height: 28,
borderRadius: 14,
backgroundColor: "#0044FF",
width: 60,
height: 32,
borderRadius: 16,
justifyContent: "center",
alignItems: "center",
borderWidth: 1,
borderColor: "rgba(255,255,255,0.2)",
},
});