前一回react-native-autocomplete-input(3)參考重構筆記的範例,可以看到還是有一點不完整的地方是在Autocomplete本身的style上面(59及100行),沒有用props傳入,組件化就不太完整,因此這篇簡單補上,完整的組件程式碼如下:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
StyleSheet,
Platform,
Text,
TextInput,
View,
FlatList,
TouchableOpacity,
ViewPropTypes as RNViewPropTypes
} from 'react-native';
const comp = (a, b) => a.toLowerCase().trim() === b.toLowerCase().trim();
const ViewPropTypes = RNViewPropTypes || View.propTypes;
export default class Autocomplete extends Component {
_keyExtractor = (item, index) => item.content;
static propTypes = {
array: PropTypes.array,
placeholder: PropTypes.string,
keyboardShouldPersistTaps: PropTypes.oneOfType([
PropTypes.string,
PropTypes.bool
]),
returnKeyType: PropTypes.string,
keyboardType: PropTypes.string,
AutocompleteStyle: ViewPropTypes.style,
AutocompleteFontStyle: Text.propTypes.style,
};
static defaultProps = {
array: [],
placeholder: '',
keyboardShouldPersistTaps: 'handled',
returnKeyType: 'done',
keyboardType: 'default',
};
constructor(props) {
super(props);
this.state = {
text: '',
flagFocus: false,
};
};
/**
* 從輸入找出陣列符合
*/
findArray(text) {
if (text === '') {
return [];
}
const { array } = this.props;
const regex = new RegExp(`${text.trim()}`, 'i');
return array.filter(array => array.content.search(regex) >= 0);
}
/**
* 回傳提示框
*/
renderItem = (item) => {
const {
AutocompleteFontStyle,
} = this.props;
return (
<TouchableOpacity
activeOpacity={0}
style={{padding:10}}
onPress= {() => this.setState({ text: item.content })}
>
<Text style={[styles.item,AutocompleteFontStyle]}>
{item.content}
</Text>
</TouchableOpacity>
);
};
onFocus() {
this.setState({ flagFocus: true })
};
onBlur() {
this.setState({ flagFocus: false })
};
render() {
const {
keyboardShouldPersistTaps,
returnKeyType,
keyboardType,
placeholder,
AutocompleteStyle,
AutocompleteFontStyle,
} = this.props;
const { text, flagFocus } = this.state;
const array = this.findArray(text);
const showResults = (array.length === 0||(array.length === 1 && comp(text, array[0].content)))?false:true;
/**
* console.log(array.length)
*/
return (
<View style={styles.container}>
<TextInput
ref='Account'
autoCapitalize='none'
autoCorrect={false}
maxLength={10}
underlineColorAndroid='transparent'
keyboardType={keyboardType}
returnKeyType={returnKeyType}
defaultValue={text}
style={[
AutocompleteStyle,
AutocompleteFontStyle,
]}
onFocus={() => this.onFocus()}
onBlur={() => this.onBlur()}
onChangeText={text => this.setState({ text: text })}
placeholder={placeholder}
/>
{ showResults && flagFocus &&
(<FlatList
style={[
styles.flatlist,
{top:AutocompleteFontStyle,},
]}
bounces={false}
keyExtractor={this._keyExtractor}
keyboardShouldPersistTaps={keyboardShouldPersistTaps}
numColumns ={1}
data={array.length === 1 && comp(text, array[0].content) ? [] : array}
renderItem={({item}) => this.renderItem(item)}
/>)}
</View>
);
};
}
const androidStyles = {
container: {
},
};
const iosStyles = {
container: {
zIndex: 1
},
};
const styles = StyleSheet.create({
...Platform.select({
android: { ...androidStyles },
ios: { ...iosStyles }
}),
flatlist: {
flex:1,
maxHeight:120,
position: 'absolute',
left: 0,
right: 0,
borderColor: '#b9b9b9',
borderRadius: 1,
borderWidth: 1,
backgroundColor: 'white',
borderTopWidth: 0,
zIndex: 2,
elevation: 20,
},
item: {
textAlign:'center',
zIndex: 2,
elevation: 20,
},
});
上述範例可以看到在28、29行的地方多了兩個props,分別為AutocompleteStyle、AutocompleteFontStyle,分成兩個的原因目前是因為如果在AutocompleteStyle裡面撰寫到fontSize的屬性,會出現Invalid props.style key `fontSize` supplied to `Autocomplete`的warning,因此查了一些資料目前是將跟Text有關的屬性額外分了一個AutocompleteFontStyle出來,或者是可以採用下列的方法:
static propTypes = {
...View.propTypes,
...TextInput.propTypes,
array: PropTypes.array,
placeholder: PropTypes.string,
returnKeyType: PropTypes.string,
keyboardType: PropTypes.string,
};
這個方法在傳入porps時就可以直接全部寫在style這個屬性內了,最後附上原先採用AutocompleteStyle、AutocompleteFontStyle這個的呼叫範例:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
Platform,
StyleSheet,
Text,
View,
Image,
ImageBackground,
PixelRatio,
TextInput,
TouchableOpacity,
AlertIOS,
ScrollView,
} from 'react-native';
import Autocomplete from './Autocomplete'
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<View style={styles.container}>
<Autocomplete
ref='Account'
placeholder = {'test'}
AutocompleteFontStyle = {{fontSize: 18}}
AutocompleteStyle = {[
styles.textinput,
]}
array= {[
{content:'001'},
{content:'002'},
]}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
textinput: {
flex:1,
padding:0,
marginTop: 10,
minWidth:180,
maxWidth:280,
},
});
沒有留言:
張貼留言