Files
rn-app/app/(tabs)/paper.tsx
2025-11-05 17:24:55 +08:00

293 lines
8.3 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState } from 'react';
import { ScrollView, StyleSheet, View } from 'react-native';
import {
Button,
Card,
Chip,
FAB,
IconButton,
List,
ProgressBar,
Searchbar,
SegmentedButtons,
Snackbar,
Switch,
Text,
TextInput,
useTheme,
} from 'react-native-paper';
export default function PaperDemo() {
const theme = useTheme();
const [searchQuery, setSearchQuery] = useState('');
const [text, setText] = useState('');
const [switchValue, setSwitchValue] = useState(false);
const [snackbarVisible, setSnackbarVisible] = useState(false);
const [segmentedValue, setSegmentedValue] = useState('walk');
const [expanded, setExpanded] = useState(true);
return (
<View style={styles.container}>
<ScrollView style={styles.scrollView} contentContainerStyle={styles.content}>
{/* 标题 */}
<Text variant="headlineLarge" style={styles.title}>
React Native Paper
</Text>
<Text variant="bodyMedium" style={styles.subtitle}>
Material Design
</Text>
{/* 搜索框 */}
<Card style={styles.card}>
<Card.Content>
<Text variant="titleMedium" style={styles.sectionTitle}>
🔍
</Text>
<Searchbar
placeholder="搜索..."
onChangeText={setSearchQuery}
value={searchQuery}
style={styles.searchbar}
/>
</Card.Content>
</Card>
{/* 输入框 */}
<Card style={styles.card}>
<Card.Content>
<Text variant="titleMedium" style={styles.sectionTitle}>
</Text>
<TextInput
label="标准输入框"
value={text}
onChangeText={setText}
mode="outlined"
style={styles.input}
/>
<TextInput
label="扁平输入框"
value={text}
onChangeText={setText}
mode="flat"
style={styles.input}
/>
</Card.Content>
</Card>
{/* 按钮 */}
<Card style={styles.card}>
<Card.Content>
<Text variant="titleMedium" style={styles.sectionTitle}>
🔘
</Text>
<View style={styles.buttonRow}>
<Button mode="contained" onPress={() => setSnackbarVisible(true)} style={{ marginRight: 8 }}>
Contained
</Button>
<Button mode="outlined" onPress={() => setSnackbarVisible(true)}>
Outlined
</Button>
</View>
<View style={styles.buttonRow}>
<Button mode="text" onPress={() => setSnackbarVisible(true)} style={{ marginRight: 8 }}>
Text
</Button>
<Button mode="elevated" onPress={() => setSnackbarVisible(true)} icon="camera">
With Icon
</Button>
</View>
</Card.Content>
</Card>
{/* 分段按钮 */}
<Card style={styles.card}>
<Card.Content>
<Text variant="titleMedium" style={styles.sectionTitle}>
📊
</Text>
<SegmentedButtons
value={segmentedValue}
onValueChange={setSegmentedValue}
buttons={[
{
value: 'walk',
label: '步行',
icon: 'walk',
},
{
value: 'train',
label: '火车',
icon: 'train',
},
{ value: 'drive', label: '驾车', icon: 'car' },
]}
/>
</Card.Content>
</Card>
{/* 开关和芯片 */}
<Card style={styles.card}>
<Card.Content>
<Text variant="titleMedium" style={styles.sectionTitle}>
🎛
</Text>
<View style={styles.row}>
<Text variant="bodyLarge"></Text>
<Switch value={switchValue} onValueChange={setSwitchValue} />
</View>
<View style={styles.chipContainer}>
<Chip icon="star" onPress={() => {}} style={{ marginRight: 8, marginBottom: 8 }}>
</Chip>
<Chip icon="heart" mode="outlined" onPress={() => {}} style={{ marginRight: 8, marginBottom: 8 }}>
</Chip>
<Chip icon="close" onPress={() => {}} onClose={() => {}} closeIcon="close-circle" style={{ marginBottom: 8 }}>
</Chip>
</View>
</Card.Content>
</Card>
{/* 进度条 */}
<Card style={styles.card}>
<Card.Content>
<Text variant="titleMedium" style={styles.sectionTitle}>
📈
</Text>
<ProgressBar progress={0.7} style={styles.progressBar} />
<ProgressBar progress={0.5} color={theme.colors.secondary} />
</Card.Content>
</Card>
{/* 列表 */}
<Card style={styles.card}>
<Card.Content>
<Text variant="titleMedium" style={styles.sectionTitle}>
📋
</Text>
<List.Section>
<List.Accordion
title="可展开列表"
left={(props) => <List.Icon {...props} icon="folder" />}
expanded={expanded}
onPress={() => setExpanded(!expanded)}
>
<List.Item title="第一项" left={(props) => <List.Icon {...props} icon="file" />} />
<List.Item title="第二项" left={(props) => <List.Icon {...props} icon="file" />} />
</List.Accordion>
</List.Section>
<List.Item
title="带描述的列表项"
description="这是一个描述文本"
left={(props) => <List.Icon {...props} icon="account" />}
right={(props) => <List.Icon {...props} icon="chevron-right" />}
/>
</Card.Content>
</Card>
{/* 卡片示例 */}
<Card style={styles.card}>
<Card.Cover source={{ uri: 'https://picsum.photos/700' }} />
<Card.Title
title="卡片标题"
subtitle="卡片副标题"
left={(props) => <IconButton {...props} icon="image" />}
right={(props) => <IconButton {...props} icon="dots-vertical" />}
/>
<Card.Content>
<Text variant="bodyMedium">
</Text>
</Card.Content>
<Card.Actions>
<Button></Button>
<Button></Button>
</Card.Actions>
</Card>
{/* 底部留白 */}
<View style={styles.bottomSpace} />
</ScrollView>
{/* 浮动操作按钮 */}
<FAB icon="plus" style={styles.fab} onPress={() => setSnackbarVisible(true)} label="添加" />
{/* 提示条 */}
<Snackbar
visible={snackbarVisible}
onDismiss={() => setSnackbarVisible(false)}
duration={3000}
action={{
label: '撤销',
onPress: () => {
// 撤销操作
},
}}
>
</Snackbar>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
scrollView: {
flex: 1,
},
content: {
padding: 16,
},
title: {
marginBottom: 8,
fontWeight: 'bold',
},
subtitle: {
marginBottom: 24,
opacity: 0.7,
},
card: {
marginBottom: 16,
},
sectionTitle: {
marginBottom: 12,
fontWeight: '600',
},
searchbar: {
marginTop: 8,
},
input: {
marginBottom: 12,
},
buttonRow: {
flexDirection: 'row',
marginBottom: 8,
},
row: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 16,
},
chipContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
},
progressBar: {
marginBottom: 12,
},
bottomSpace: {
height: 80,
},
fab: {
position: 'absolute',
margin: 16,
right: 0,
bottom: 0,
},
});