293 lines
8.3 KiB
TypeScript
293 lines
8.3 KiB
TypeScript
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,
|
||
},
|
||
});
|