Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save nuno/f89ecca02f8c7df70ad5bc46c7e770fa to your computer and use it in GitHub Desktop.
Save nuno/f89ecca02f8c7df70ad5bc46c7e770fa to your computer and use it in GitHub Desktop.
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule KeyboardAvoidingScrollView
* @flow
* @format
*/
'use strict';
const React = require('React');
const ScrollView = require('ScrollView');
const StyleSheet = require('StyleSheet');
const View = require('View');
const Text = require('Text');
const Keyboard = require('Keyboard');
import type EmitterSubscription from 'EmitterSubscription';
type ScreenRect = {
screenX: number,
screenY: number,
width: number,
height: number,
};
type KeyboardChangeEvent = {
startCoordinates?: ScreenRect,
endCoordinates: ScreenRect,
duration?: number,
easing?: string,
};
class Message extends React.PureComponent<*> {
render() {
return (
<View style={styles.textBubbleBackground}>
<Text style={styles.text}>Text Message</Text>
</View>
);
}
}
type State = {
contentInset: number,
lowestStartHeight: number,
};
class KeyboardAvoidingScrollView extends React.Component<*, State> {
_subscriptions: Array<EmitterSubscription> = [];
_scrollView: ?ScrollView;
state: State = {
contentInset: 0,
lowestStartHeight: 1000,
};
UNSAFE_componentWillMount() {
this._subscriptions = [
// Keyboard.addListener('keyboardWillShow', this._onKeyboardChange),
Keyboard.addListener('keyboardDidShow', this._onKeyboardShow),
Keyboard.addListener('keyboardWillHide', this._onKeyboardHide),
// Keyboard.addListener('keyboardDidHide', this._onKeyboardChange),
// Keyboard.addListener('keyboardWillChangeFrame', this._onKeyboardChange),
// Keyboard.addListener('keyboardDidChangeFrame', this._onKeyboardChange),
];
}
_onKeyboardHide = (event: ?KeyboardChangeEvent) => {
this.setState({contentInset: 0});
};
_onKeyboardShow = (event: ?KeyboardChangeEvent) => {
//this also gets called on keyboard close for some reason, only
// do stuff when keyboard is getting bigger
if (
event &&
event.startCoordinates &&
event.startCoordinates.height < event.endCoordinates.height
) {
if (event.startCoordinates.height < this.state.lowestStartHeight) {
this.setState({lowestStartHeight: event.startCoordinates.height});
}
const newInset =
event.endCoordinates.height - this.state.lowestStartHeight;
this.setState({
contentInset: newInset,
});
if (this._scrollView) {
this._scrollView.scrollToEnd();
}
}
};
render(): React.Node {
return (
<ScrollView
ref={scrollView => {
this._scrollView = scrollView;
}}
keyboardDismissMode="interactive"
contentInset={{bottom: this.state.contentInset}}>
{Array(25)
.fill()
.map((_, i) => <Message key={i} />)}
</ScrollView>
);
}
}
const styles = StyleSheet.create({
textInputContainer: {
flexDirection: 'row',
},
textInput: {
flex: 1,
paddingLeft: 10,
},
text: {
padding: 10,
color: 'white',
},
textBubbleBackground: {
backgroundColor: '#2f7bf6',
borderRadius: 20,
width: 110,
margin: 20,
},
});
module.exports = KeyboardAvoidingScrollView;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment