Created
April 5, 2017 10:07
-
-
Save kyo504/98b1fff700828c2773015aa9cb41c917 to your computer and use it in GitHub Desktop.
SwipeableListView Sample
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, { Component } from 'react'; | |
import { | |
Image, | |
Text, | |
View, | |
StyleSheet, | |
TouchableHighlight, | |
StatusBar, | |
ListView, | |
} from 'react-native'; | |
import SwipeableListView from 'SwipeableListView'; | |
import SwipeableQuickActions from 'SwipeableQuickActions'; | |
import SwipeableQuickActionButton from 'SwipeableQuickActionButton'; | |
import Icon from 'react-native-vector-icons/SimpleLineIcons'; | |
let tracks = [ | |
{ artist: 'ZAYN(제인)', title: 'Still Got Time (feat. PARTYNEXTDOOR)', image_url: 'https://unsplash.it/300/300?image=0' }, | |
{ artist: 'Set The Tone', title: 'The Boulevards', image_url: 'https://unsplash.it/300/300?image=1' }, | |
{ artist: 'Light My Body Up (feat. Nicki Minaj & Lil Wayne)', title: 'David Guetta(데이빗)', image_url: 'https://unsplash.it/300/300?image=2' }, | |
{ artist: 'The Way I Feel (Original Mix)', title: 'The Node', image_url: 'https://unsplash.it/300/300?image=3' }, | |
{ artist: 'I\'ll Catch You (Original Mix)', title: 'Angemi', image_url: 'https://unsplash.it/300/300?image=4' }, | |
{ artist: 'Connected', title: 'ATB & Andrew Rayel', image_url: 'https://unsplash.it/300/300?image=5' }, | |
{ artist: 'Gang Up', title: 'Young Thug', image_url: 'https://unsplash.it/300/300?image=6' }, | |
{ artist: 'Some Kinda Wonderful', title: 'Betty Who(베티 후)', image_url: 'https://unsplash.it/300/300?image=7' }, | |
{ artist: 'Light My Body Up (feat. Nicki Minaj & Lil Wayne)', title: 'David Guetta(데이빗)', image_url: 'https://unsplash.it/300/300?image=8' }, | |
{ artist: 'The Way I Feel (Original Mix)', title: 'The Node', image_url: 'https://unsplash.it/300/300?image=9' }, | |
{ artist: 'I\'ll Catch You (Original Mix)', title: 'Angemi', image_url: 'https://unsplash.it/300/300?image=100' }, | |
{ artist: 'ZAYN(제인)', title: 'Still Got Time (feat. PARTYNEXTDOOR)', image_url: 'https://unsplash.it/300/300?image=101' }, | |
{ artist: 'Set The Tone', title: 'The Boulevards', image_url: 'https://unsplash.it/300/300?image=102' }, | |
{ artist: 'Light My Body Up (feat. Nicki Minaj & Lil Wayne)', title: 'David Guetta(데이빗)', image_url: 'https://unsplash.it/300/300?image=103' }, | |
{ artist: 'The Way I Feel (Original Mix)', title: 'The Node', image_url: 'https://unsplash.it/300/300?image=104' }, | |
{ artist: 'I\'ll Catch You (Original Mix)', title: 'Angemi', image_url: 'https://unsplash.it/300/300?image=110' }, | |
{ artist: 'Connected', title: 'ATB & Andrew Rayel', image_url: 'https://unsplash.it/300/300?image=106' }, | |
{ artist: 'Gang Up', title: 'Young Thug', image_url: 'https://unsplash.it/300/300?image=107' }, | |
{ artist: 'Some Kinda Wonderful', title: 'Betty Who(베티 후)', image_url: 'https://unsplash.it/300/300?image=108' }, | |
{ artist: 'Light My Body Up (feat. Nicki Minaj & Lil Wayne)', title: 'David Guetta(데이빗)', image_url: 'https://unsplash.it/300/300?image=109' }, | |
]; | |
export default class App extends Component { | |
constructor(props) { | |
super(props); | |
const ds = SwipeableListView.getNewDataSource(); | |
this.state = { | |
dataSource: ds.cloneWithRowsAndSections(...this.genDataSource(tracks)), | |
}; | |
this.renderStandardQuickActions = this.renderStandardQuickActions.bind(this); | |
this.renderCustomQuickActions = this.renderCustomQuickActions.bind(this); | |
this.renderSeparator = this.renderSeparator.bind(this); | |
this.renderRow = this.renderRow.bind(this); | |
} | |
genDataSource(rowData: Array<any>) { | |
const dataBlob = {}; | |
const sectionIDs = ['Section 0']; | |
const rowIDs = [[]]; | |
/** | |
* dataBlob example below: | |
{ | |
'Section 0': { | |
'Row 0': { | |
id: '0', | |
text: 'row 0 text' | |
}, | |
'Row 1': { | |
id: '1', | |
text: 'row 1 text' | |
} | |
} | |
} | |
*/ | |
dataBlob['Section 0'] = {}; | |
rowData.forEach((el, index) => { | |
const rowName = `${index}`; | |
dataBlob[sectionIDs[0]][rowName] = { | |
id: rowName, | |
...el, | |
}; | |
rowIDs[0].push(rowName); | |
}); | |
return [dataBlob, sectionIDs, rowIDs]; | |
} | |
renderSeparator(sectionID, rowID) { | |
return ( | |
<View key={`${sectionID}-${rowID}`} style={styles.separator} /> | |
); | |
} | |
renderStandardQuickActions(rowData: object, sectionID: string, rowID: string) { | |
return ( | |
<SwipeableQuickActions> | |
<SwipeableQuickActionButton | |
imageSource={{ uri: 'https://unsplash.it/300/300?random' }} | |
imageStyle={styles.thumbnail} | |
onPress={() => { }} | |
// style: View.propTypes.style, | |
text={'Action'} | |
textStyle={{ color: 'white' }} | |
/> | |
<SwipeableQuickActionButton | |
imageSource={{ uri: 'https://unsplash.it/300/300?random' }} | |
imageStyle={styles.thumbnail} | |
onPress={() => { }} | |
// style: View.propTypes.style, | |
text={'Action'} | |
textStyle={{ color: 'white' }} | |
/> | |
</SwipeableQuickActions> | |
); | |
} | |
renderCustomQuickActions(rowData: object, sectionID: string, rowID: string) { | |
return ( | |
<View style={styles.actionsContainer}> | |
<TouchableHighlight | |
style={[styles.actionButton, { backgroundColor: 'gold' }]} | |
underlayColor="transparent" | |
onPress={() => console.log(rowID)} | |
> | |
<Icon name="pin" size={20} /> | |
</TouchableHighlight> | |
<TouchableHighlight | |
style={[styles.actionButton, { backgroundColor: 'goldenrod' }]} | |
underlayColor="transparent" | |
onPress={() => this.onDeleteRow(parseInt(rowID))} | |
> | |
<Icon name="trash" size={20} /> | |
</TouchableHighlight> | |
</View> | |
); | |
} | |
onDeleteRow(index) { | |
tracks = [ | |
...tracks.slice(0, index), | |
...tracks.slice(index + 1), | |
]; | |
const ds = SwipeableListView.getNewDataSource(); | |
this.setState({ | |
dataSource: ds.cloneWithRowsAndSections(...this.genDataSource(tracks)), | |
}); | |
} | |
onSelectRow(rowID) { | |
const openID = this.state.dataSource.getOpenRowID(); | |
if (openID && (openID === rowID)) { | |
this.setState({ | |
dataSource: this.state.dataSource.setOpenRowID(null), | |
}); | |
} | |
// Add more codes | |
} | |
renderRow(rowData, sectionID, rowID) { | |
const { title, artist, image_url } = rowData; | |
return ( | |
<TouchableHighlight | |
style={{ flex: 1 }} | |
underlayColor="gray" | |
onPress={() => this.onSelectRow(rowID)} | |
> | |
<View style={styles.rowContainer}> | |
<Image style={styles.thumbnail} source={{ uri: image_url }} /> | |
<View style={styles.textContainer}> | |
<Text numberOfLines={1} style={styles.trackTitle}>{title}</Text> | |
<Text style={styles.artistName}>{artist}</Text> | |
</View> | |
</View> | |
</TouchableHighlight> | |
); | |
} | |
render() { | |
return ( | |
<View style={{ flex: 1 }}> | |
<StatusBar | |
backgroundColor="black" | |
barStyle="light-content" | |
/> | |
<SwipeableListView | |
style={styles.list} | |
contentContainerStyle={styles.contentContainer} | |
dataSource={this.state.dataSource} | |
maxSwipeDistance={140} | |
renderQuickActions={this.renderCustomQuickActions} | |
renderRow={this.renderRow} | |
renderSeparator={this.renderSeparator} | |
enableEmptySections={true} | |
/> | |
</View> | |
); | |
} | |
} | |
const styles = StyleSheet.create({ | |
list: { | |
flex: 1, | |
backgroundColor: 'black', | |
}, | |
contentContainer: { | |
paddingTop: 20, | |
}, | |
rowContainer: { | |
flex: 1, | |
flexDirection: 'row', | |
paddingLeft: 20, | |
paddingRight: 5, | |
paddingVertical: 10, | |
alignItems: 'center', | |
backgroundColor: 'black', | |
justifyContent: 'space-between', | |
height: 70, | |
}, | |
thumbnail: { | |
width: 48, | |
height: 48, | |
borderWidth: 0.5, | |
borderColor: 'lightgray', | |
marginRight: 5, | |
}, | |
textContainer: { | |
flex: 1, | |
alignSelf: 'stretch', | |
justifyContent: 'space-around', | |
paddingHorizontal: 12, | |
}, | |
trackTitle: { | |
fontSize: 13, | |
color: 'white', | |
}, | |
artistName: { | |
fontSize: 12, | |
color: 'lightgray', | |
}, | |
separator: { | |
height: 0.5, | |
alignSelf: 'stretch', | |
backgroundColor: 'lightgray', | |
}, | |
actionsContainer: { | |
flex: 1, | |
flexDirection: 'row', | |
justifyContent: 'flex-end', | |
alignItems: 'center', | |
}, | |
actionButton: { | |
width: 70, | |
height: 70, | |
alignItems: 'center', | |
justifyContent: 'center', | |
}, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment