-
-
Save ushumpei/2d18f89d0164bce12b9670d2955421b9 to your computer and use it in GitHub Desktop.
TryReactNavigation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { | |
Alert, | |
Button, | |
FlatList, | |
Keyboard, | |
StyleSheet, | |
Text, | |
TextInput, | |
TouchableOpacity, | |
TouchableWithoutFeedback, | |
View, | |
} from 'react-native'; | |
import { StackNavigator, TabNavigator } from 'react-navigation'; | |
import { Entypo } from '@expo/vector-icons'; | |
/* サンプルデータ */ | |
const mathematics = [ | |
{ title: 'Geometry', detail: '幾何学(きかがく)は、図形や空間の性質について研究する数学の分野である。イエズス会マテオ・リッチによるgeometriaの中国語訳である。以前はgeometria の冒頭のgeo-を音訳したものであるという説が広く流布していたが、近年の研究により否定されている。 もともと測量の必要上からエジプトで生まれたものだが、人間に認識できる図形に関する様々な性質を研究する数学の分野としてとくに古代ギリシャにて独自に発達し、これらのおもな成果はB.C.300年ごろユークリッドによってユークリッド原論にまとめられた。その後中世以降のヨーロッパにてユークリッド幾何学を発端とする様々な幾何学が登場することとなる。' }, | |
{ title: 'Analysis', detail: '解析学(かいせきがく)とは、極限や収束といった概念を扱う数学の分野である。代数学、幾何学と合わせ数学の三大分野をなす。数学用語としての解析学は要素還元主義とは異なっており、初等的には微積分や級数などを用いて関数の変化量などの性質を調べる分野と言われることが多い。これは解析学がもともとテイラー級数やフーリエ級数などを用いて関数の性質を研究していたことに由来する。' }, | |
{ title: 'Algebra', detail: '代数学(だいすうがく)は数学の一分野で、「代数」 の名の通り数の代わりに文字を用いて方程式の解法を研究する学問として始まった。しかし19世紀以降の現代数学においては、ヒルベルトの公理主義やブルバキスタイルに見られるように、代数学はその範囲を大きく広げているため、「数の代わりに文字を用いる数学」や「方程式の解法の学問」という理解の仕方は必ずしも適当ではない。現代数学においては、方程式の研究は方程式論(代数方程式論)という代数学の古典的一分野として捉えられている。現在は代数学と言えば以下の抽象代数学をさすのが普通である。' }, | |
]; | |
/* スタイル */ | |
const styles = StyleSheet.create({ | |
container: { | |
flex: 1, | |
backgroundColor: '#fff', | |
alignItems: 'center', | |
justifyContent: 'center', | |
paddingHorizontal: 16, | |
}, | |
heading: { | |
fontSize: 24, | |
color: 'rgba(14, 13, 13, .38)', | |
}, | |
paragraph: { | |
fontSize: 18, | |
color: '#737373', | |
}, | |
listItem: { | |
borderBottomWidth: 1, | |
borderBottomColor: 'rgba(14, 13, 13, .38)', | |
marginVertical: 12, | |
}, | |
inputGroup: { | |
alignItems: 'center', | |
alignSelf: 'stretch', | |
flexDirection: 'row', | |
justifyContent: 'space-between', | |
marginBottom: 8, | |
}, | |
label: { | |
minWidth: 60, | |
}, | |
textInput: { | |
flex: 4, | |
borderColor: 'rgba(14, 13, 13, .38)', | |
borderWidth: 1, | |
paddingHorizontal: 12, | |
height: 40, | |
}, | |
multiTextInput: { | |
flex: 4, | |
borderColor: 'rgba(14, 13, 13, .38)', | |
borderWidth: 1, | |
paddingHorizontal: 9, | |
height: 80, | |
}, | |
}); | |
/* | |
* データのタイトルをリスト表示するコンポーネント | |
*/ | |
const ListScreen = ({ navigation, screenProps }) => ( | |
<FlatList | |
contentContainerStyle={styles.container} | |
data={screenProps.mathematics} | |
keyExtractor={(item, index) => index} | |
removeClippedSubviews={false} | |
renderItem={({ item, index }) => ( | |
<TouchableOpacity | |
style={styles.listItem} | |
/* タイトルが押されたら詳細画面にナビゲート, `index`も引数として渡している */ | |
onPress={() => navigation.navigate('Detail', { ...item, index: index })} | |
> | |
<Text style={styles.heading}>{item.title}</Text> | |
</TouchableOpacity> | |
)} | |
/> | |
); | |
/* | |
* データの詳細を表示するコンポーネント | |
*/ | |
const DetailScreen = ({ navigation }) => ( | |
<View style={styles.container}> | |
<Text style={[styles.heading, { marginBottom: 24 }]}>{navigation.state.params.title}</Text> | |
<Text style={styles.paragraph}>{navigation.state.params.detail}</Text> | |
</View> | |
); | |
DetailScreen.navigationOptions = ({ navigation, screenProps }) => ({ | |
headerRight: ( | |
<TouchableOpacity | |
style={{ marginRight: 8 }} | |
onPress={() => { | |
Alert.alert( | |
'Warning', | |
'項目を削除しますか?', | |
[ | |
{ | |
text: 'Delete', | |
onPress: () => { | |
screenProps.removeMathItem(navigation.state.params.index); | |
navigation.goBack(); | |
}, | |
}, | |
{ text: 'Cancel' }, | |
], | |
); | |
}} | |
> | |
<Entypo size={24} name="trash" color={'red'} /> | |
</TouchableOpacity> | |
), | |
}); | |
/* | |
* StackNavigatorを作成 | |
*/ | |
const MathematicsList = StackNavigator({ | |
List: { | |
screen: ListScreen, | |
navigationOptions: { | |
title: 'Mathematics', | |
}, | |
}, | |
Detail: { | |
screen: DetailScreen, | |
}, | |
}, { | |
initialRouteName: 'List', | |
}); | |
/* | |
* 項目追加画面を作成 | |
*/ | |
class AddMathItemScreen extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = { title: '', detail: '' }; | |
this.handleOnPress = this.handleOnPress.bind(this); | |
} | |
handleOnPress() { | |
const { title, detail } = this.state; | |
if (!title) return Alert.alert('Error', 'titleは必須です'); | |
this.props.screenProps.addNewMathItem({ title, detail }); | |
Alert.alert( | |
'Notice', | |
'項目を追加しました!', | |
[{ text: 'OK', onPress: () => this.props.navigation.navigate('List') }], | |
); | |
this.setState({ title: '', detail: '' }); | |
} | |
render() { | |
return ( | |
<TouchableWithoutFeedback onPress={Keyboard.dismiss}> | |
<View style={styles.container}> | |
<View style={styles.inputGroup}> | |
<Text style={[styles.paragraph, styles.label]}>title</Text> | |
<TextInput | |
blurOnSubmit | |
onChangeText={title => this.setState({ title })} | |
style={[styles.textInput, styles.heading]} | |
value={this.state.title} | |
/> | |
</View> | |
<View style={styles.inputGroup}> | |
<Text style={[styles.paragraph, styles.label]}>detail</Text> | |
<TextInput | |
blurOnSubmit | |
multiline | |
onChangeText={detail => this.setState({ detail })} | |
style={[styles.multiTextInput, styles.paragraph]} | |
value={this.state.detail} | |
/> | |
</View> | |
<Button color={'#037aff'} onPress={this.handleOnPress} title={'Add item to list'} /> | |
</View> | |
</TouchableWithoutFeedback> | |
); | |
} | |
} | |
/* | |
* TabNavigatorを作成 | |
*/ | |
const Tab = TabNavigator({ | |
List: { | |
screen: MathematicsList, | |
navigationOptions: { | |
tabBarIcon: ({ tintColor }) => <Entypo size={24} name="list" color={tintColor} />, | |
}, | |
}, | |
AddItem: { | |
screen: AddMathItemScreen, | |
navigationOptions: { | |
tabBarIcon: ({ tintColor }) => <Entypo size={24} name="add-to-list" color={tintColor} />, | |
}, | |
}, | |
}, { | |
initialRouteName: 'List', | |
tabBarOptions: { | |
activeTintColor: '#037aff', | |
inactiveTintColor: '#737373', | |
showLabel: false, | |
}, | |
}); | |
/* | |
* リストを保持しているAppコンテナコンポーネント | |
*/ | |
export default class App extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
mathematics, | |
}; | |
this.addNewMathItem = this.addNewMathItem.bind(this); | |
this.removeMathItem = this.removeMathItem.bind(this); | |
} | |
addNewMathItem({ title, detail }) { | |
this.setState({ | |
mathematics: [...this.state.mathematics, { title, detail }], | |
}); | |
} | |
removeMathItem(index) { | |
this.setState({ | |
mathematics: this.state.mathematics.filter((_, i) => i !== index), | |
}); | |
} | |
render() { | |
return ( | |
<Tab | |
screenProps={{ | |
mathematics: this.state.mathematics, | |
addNewMathItem: this.addNewMathItem, | |
removeMathItem: this.removeMathItem, | |
}} | |
/> | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment