listview was too slow. Use a single view with text rows. no longer supports vertical picker

This commit is contained in:
Yonah Forst 2016-06-17 17:21:13 +02:00
parent 3b5b693e5c
commit ac6f870028
3 changed files with 60 additions and 56 deletions

View File

@ -22,7 +22,6 @@ class Main extends React.Component {
<View style={styles.container}>
<EmojiPicker
style={styles.emojiPicker}
horizontal={true}
onEmojiSelected={this._emojiSelected}/>
</View>
);
@ -33,12 +32,10 @@ class Main extends React.Component {
#### Component props
- `onEmojiSelected` (Function) - Required. Called when the user taps on an emoji.
- `style` (Object) - Required. Standard view style for the enclosing component. Just like ScrollView, needs a bounded height to work.
- `horizontal` (Bool) - Optional. Should the list of emojis scroll horizontally or vertically (default)
- `style` (Object) - Optional. Standard view style for the enclosing component.
- `clearButtonText` (String) - Optional. Alternate text for the clear button. Defaults to 'Clear'.
- `hideClearButton` (Bool) - Optional. Hide the clear button.
- `listViewProps` (Object) - Optional. Override default ListView props.
- `rows` (Number) - Optional. Number of rows used to show all emojis. Defaults to 7.
### EmojiOverlay component
Optional overlay which wraps the picker in a modal-like component

107
index.js
View File

@ -5,86 +5,85 @@ import React, {
import {
StyleSheet,
ListView,
ScrollView,
Text,
TouchableOpacity,
TouchableWithoutFeedback,
View,
} from 'react-native'
import emoji from 'emojilib'
const dataSource = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
const letterSpacing = 10
const defaultEmojiSize = 30
const EmojiPicker = (props) => {
let contentStyle = {}
if (props.horizontal) {
contentStyle.flexDirection = 'column'
contentStyle.flex = 1
} else {
contentStyle.flexDirection = 'row'
let container = []
let rowCount = props.rows || 7
let ordered = emoji.ordered
for (var i = 0; i < rowCount; i++) {
let row = []
for (var n = 0; n < ordered.length/rowCount; n++) {
let index = i + n * rowCount + 1
if (index < ordered.length) {
row.push(ordered[index])
}
}
container.push(row)
}
return (
<View style={props.style}>
<ListView
dataSource={dataSource.cloneWithRows(emoji.ordered)}
contentContainerStyle={[styles.container, contentStyle]}
renderRow={name => EmojiButton(name, props.onEmojiSelected)}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
horizontal={props.horizontal}
initialListSize={80}
pageSize={5}
scrollRenderAheadDistance={500}
{...props.listViewProps}
/>
{props.hideClearButton ? null : ClearButon(props)}
<ScrollView horizontal={true}>
<View style={styles.innerContainer}>
{container.map(array => <Row {...props} array={array} key={array[0]} />)}
</View>
</ScrollView>
{props.hideClearButton ? null : <ClearButon {...props} />}
</View>
)
}
const Row = props => {
let size = props.emojiSize || defaultEmojiSize
function handlePress(event) {
let i = Math.floor(event.nativeEvent.locationX/(size + 5 + letterSpacing/2))
let name = props.array[i]
props.onEmojiSelected(emoji.lib[name].char)
}
return (
<TouchableWithoutFeedback onPress={handlePress}>
<View>
<Text style={[styles.rowText, {fontSize: size}]} >
{props.array.map(name => emoji.lib[name].char)}
</Text>
</View>
</TouchableWithoutFeedback>
)
}
const ClearButon = props => {
return (
<Text
style={styles.clearButton}
<TouchableOpacity
onPress={() => props.onEmojiSelected(null)}>
{props.clearButtonText || 'Clear'}
</Text>
<Text style={styles.clearButton}>
{props.clearButtonText || 'Clear'}
</Text>
</TouchableOpacity>
)
}
const EmojiButton = (name, onPress) => {
let char = emoji.lib[name].char
return (
<Text
style={styles.text}
onPress={() => onPress(char)}
key={name}>{char}</Text>
)
}
export const EmojiOverlay = props => (
const EmojiOverlay = props => (
<View style={[styles.absolute, props.visible ? styles.visible : styles.hidden]}>
<TouchableOpacity style={styles.absolute} onPress={props.onTapOutside}>
<View style={styles.background} />
</TouchableOpacity>
<View>
{props.visible ? <EmojiPicker {...props}/> : null}
</View>
{props.visible ? <EmojiPicker {...props}/> : null}
</View>
)
let styles = StyleSheet.create({
container: {
justifyContent: 'space-around',
flexWrap: 'wrap',
},
text: {
fontSize: 20,
padding: 10,
},
clearButton: {
padding: 15,
textAlign: 'center',
@ -110,10 +109,18 @@ let styles = StyleSheet.create({
backgroundColor: 'grey',
opacity: 0.5,
},
innerContainer: {
flexWrap: 'wrap',
flexDirection: 'column',
},
rowText: {
letterSpacing: letterSpacing,
paddingHorizontal: 5,
}
})
EmojiPicker.propTypes = {
onEmojiSelected: PropTypes.func.isRequired,
}
export default EmojiPicker
export { EmojiPicker as default, EmojiOverlay as EmojiOverlay }

View File

@ -1,6 +1,6 @@
{
"name": "react-native-emoji-picker",
"version": "0.1.1",
"version": "0.1.2",
"description": "Simple emoji picker for react-native",
"main": "index.js",
"scripts": {