Permalink
Browse files

Use KeyboardAvoidingView

  • Loading branch information...
jeremybarbet committed Dec 27, 2017
1 parent 6516c71 commit 860c1a24e386e164b3305f751b9933edb5a56137
@@ -3,6 +3,7 @@
"rules": {
"import/extensions": 0,
"function-paren-newline": 0,
"react/prop-types": 2,
},
"globals": {
"__DEV__": true,
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { StyleSheet, Image, View, Text, TouchableOpacity, Platform } from 'react-native';
import { navigatorTypes } from 'utils/types';
import { isIphoneX } from 'utils/utils';
import { v, fonts } from 'Theme';
@@ -13,6 +14,7 @@ const STATUS_BAR_HEIGHT = 20;
export default class Header extends Component {
static propTypes = {
...navigatorTypes,
title: PropTypes.string,
}
@@ -4,6 +4,7 @@ import { Image, StyleSheet, Dimensions, Text, View, TouchableWithoutFeedback } f
import { computed } from 'mobx';
import get from 'lodash/get';
import { navigatorTypes } from 'utils/types';
import { luminosity, colors } from 'utils/colors';
import { fonts } from 'Theme';
@@ -15,6 +16,7 @@ const { width } = Dimensions.get('window');
export default class Item extends Component {
static propTypes = {
...navigatorTypes,
network: PropTypes.string,
data: PropTypes.object,
title: PropTypes.string,
@@ -1,7 +1,6 @@
import React, { Component } from 'react';
import { StyleSheet, Animated, Easing, Dimensions, View, ScrollView, Keyboard, Platform } from 'react-native';
import { StyleSheet, View, ScrollView, Platform, KeyboardAvoidingView } from 'react-native';
import { inject, observer } from 'mobx-react/native';
import get from 'lodash/get';
import Header from 'components/Header';
@@ -11,9 +10,7 @@ import { v } from 'Theme';
import Input from './components/Input';
const { height } = Dimensions.get('window');
const NETWORKS = Object.keys(api);
const HEADER_HEIGHT = 64;
@inject('stats')
@observer
@@ -27,121 +24,47 @@ export default class Settings extends Component {
navBarHidden: true,
}
constructor() {
super();
const scrollHeight = height - HEADER_HEIGHT;
this.state = {
keyboardSpace: new Animated.Value(scrollHeight),
scrollHeight,
size: null,
};
}
input = []
componentWillMount() {
Keyboard.addListener('keyboardWillShow', this.keyboardWillShow);
Keyboard.addListener('keyboardWillHide', this.keyboardWillHide);
}
componentWillUnmount() {
Keyboard.removeListener('keyboardWillShow', this.keyboardWillShow);
Keyboard.removeListener('keyboardWillHide', this.keyboardWillHide);
}
render() {
const { navigator, stats } = this.props;
const { keyboardSpace } = this.state;
return (
<View style={{ flex: 1 }}>
<View style={s.settings}>
<Header navigator={navigator} title="Options" />
<Animated.View style={{ height: keyboardSpace }}>
<KeyboardAvoidingView behavior="padding" style={s.settings}>
<ScrollView
ref={(c) => { this.scrollView = c; }}
style={s.settings}
contentContainerStyle={s.settings__scrollview}
style={s.settings__scrollview}
contentContainerStyle={s.settings__container}
keyboardShouldPersistTaps="always"
keyboardDismissMode="interactive"
onScroll={this.contentSize}
scrollEventThrottle={400}
showsVerticalScrollIndicator={false}
>
{NETWORKS.map(item =>
<Input
key={`addView-${item}`}
internalRef={(c) => { this.input[item] = c; }}
username={stats.getUsername(item)}
network={item}
onPress={() => this.input[item].measure(this.scrollToInput)}
/>,
)}
</ScrollView>
</Animated.View>
</KeyboardAvoidingView>
</View>
);
}
contentSize = ({ nativeEvent }) => {
const { size } = this.state;
const { contentSize } = nativeEvent;
if (get(contentSize, 'height') === get(size, 'height')) {
return;
}
this.setState({ size: nativeEvent.contentSize });
}
scrollToInput = (ox, oy, width, height, px, py) => { // eslint-disable-line
const { scrollHeight, size } = this.state;
const max = get(size, 'height') - scrollHeight;
const y = oy > max ? max : oy;
this.scrollView.scrollTo({
x: 0,
y,
animated: true,
});
}
keyboardWillShow = (e) => {
const { keyboardSpace } = this.state;
const scrollHeight = (height - HEADER_HEIGHT) - e.endCoordinates.height;
this.setState({ scrollHeight });
Animated.timing(keyboardSpace, {
easing: Easing.inOut(Easing.ease),
duration: 250,
toValue: scrollHeight,
}).start();
}
keyboardWillHide() {
const { keyboardSpace } = this.state;
Animated.timing(keyboardSpace, {
easing: Easing.inOut(Easing.ease),
duration: 250,
toValue: height - HEADER_HEIGHT,
}).start();
}
}
const s = StyleSheet.create({
settings: {
flex: 1,
},
settings__scrollview: {
paddingTop: 10,
backgroundColor: v.bgBlue,
},
settings__scrollview: {
settings__container: {
paddingBottom: Platform.select({ ios: 10, android: 40 }),
},
});
@@ -27,9 +27,9 @@ export default class Input extends Component {
isSuccess = false
static propTypes = {
stats: PropTypes.object,
username: PropTypes.string,
network: PropTypes.string,
onPress: PropTypes.func,
internalRef: PropTypes.func,
}
state = {
@@ -38,7 +38,7 @@ export default class Input extends Component {
}
render() {
const { network, onPress, internalRef, username } = this.props;
const { network, username } = this.props;
const { value, showRemoveIcon } = this.state;
const hasText = showRemoveIcon || username;
@@ -49,10 +49,7 @@ export default class Input extends Component {
const remove = hasText && <Remove onPress={() => this.removeItem(network)} network={network} />;
return (
<View
style={[s.input, { backgroundColor: colors(network) }]}
ref={internalRef}
>
<View style={[s.input, { backgroundColor: colors(network) }]}>
<View style={s.input__inline}>
<Image
style={s.input__icon}
@@ -64,9 +61,7 @@ export default class Input extends Component {
{success}
<TextInput
ref={(c) => { this.input = c; }}
style={[s.input__info, { marginRight: hasText ? 46 : 20 }]}
onFocus={onPress}
onChangeText={text => this.handleChange(text)}
onEndEditing={() => this.handleSubmit(inputValue, network)}
value={inputValue}

0 comments on commit 860c1a2

Please sign in to comment.