Skip to content

Instantly share code, notes, and snippets.

@kyo504
Created April 5, 2017 10:07
Show Gist options
  • Save kyo504/98b1fff700828c2773015aa9cb41c917 to your computer and use it in GitHub Desktop.
Save kyo504/98b1fff700828c2773015aa9cb41c917 to your computer and use it in GitHub Desktop.
SwipeableListView Sample
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