Skip to content
Next Next commit
Add Android Support
  • Loading branch information
Swordsman-Inaction committed Jul 24, 2017
commit e03d23c49ef83317e5dda8c52901c2c98731a5ab
20 changes: 19 additions & 1 deletion lib/KeyboardAwareListView.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import React from 'react'
import createReactClass from 'create-react-class'
import { ListView } from 'react-native'
import { ListView, Platform } from 'react-native'
import PropTypes from 'prop-types'
import KeyboardAwareMixin from './KeyboardAwareMixin'

Expand All @@ -13,6 +13,7 @@ const KeyboardAwareListView = createReactClass({
x: PropTypes.number,
y: PropTypes.number,
}),
enableOnAndroid: React.PropTypes.bool,
},
mixins: [KeyboardAwareMixin],

Expand All @@ -22,6 +23,22 @@ const KeyboardAwareListView = createReactClass({
},

render: function () {
const {
enableOnAndroid,
contentContainerStyle,
} = this.props

const {
keyboardSpace,
} = this.state

let newContentContainerStyle

if (Platform.OS === 'android' && enableOnAndroid) {
newContentContainerStyle = {}
newContentContainerStyle.paddingBottom = (contentContainerStyle ? contentContainerStyle.paddingBottom : 0) + keyboardSpace
}

return (
<ListView
ref='_rnkasv_keyboardView'
Expand All @@ -30,6 +47,7 @@ const KeyboardAwareListView = createReactClass({
showsVerticalScrollIndicator={true}
scrollEventThrottle={0}
{...this.props}
contentContainerStyle={newContentContainerStyle || contentContainerStyle}
onScroll={e => {
this.handleOnScroll(e)
this.props.onScroll && this.props.onScroll(e)
Expand Down
39 changes: 34 additions & 5 deletions lib/KeyboardAwareMixin.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* @flow */

import PropTypes from 'prop-types'
import ReactNative, { TextInput, Keyboard, UIManager } from 'react-native'
import ReactNative, { TextInput, Keyboard, UIManager, Platform } from 'react-native'
import TimerMixin from 'react-timer-mixin'

import type { Event } from 'react-native'
Expand Down Expand Up @@ -72,8 +72,28 @@ const KeyboardAwareMixin = {
if (isAncestor) {
// Check if the TextInput will be hidden by the keyboard
UIManager.measureInWindow(currentlyFocusedField, (x, y, width, height) => {
if (y + height > frames.endCoordinates.screenY - this.props.extraScrollHeight - this.props.extraHeight) {
this.scrollToFocusedInputWithNodeHandle(currentlyFocusedField)
const textInputBottomPosition = y + height
const keyboardPosition = frames.endCoordinates.screenY
const totalExtraHeight = this.props.extraScrollHeight + this.props.extraHeight

if (Platform.OS === 'ios') {
if (textInputBottomPosition > keyboardPosition - totalExtraHeight) {
this.scrollToFocusedInputWithNodeHandle(currentlyFocusedField)
}
} else {

// on android, the system would scroll the text input just above the keyboard
// so we just neet to scroll the extra height part
if (textInputBottomPosition > keyboardPosition) {
// since the system already scrolled the whole view up
// we should reduce that amount
keyboardSpace = keyboardSpace - (textInputBottomPosition - keyboardPosition)
this.setState({keyboardSpace})

this.scrollForExtraHeightOnAndroid(totalExtraHeight)
} else if (textInputBottomPosition > keyboardPosition - totalExtraHeight) {
this.scrollForExtraHeightOnAndroid(totalExtraHeight - (keyboardPosition - textInputBottomPosition))
}
}
})
}
Expand Down Expand Up @@ -108,8 +128,13 @@ const KeyboardAwareMixin = {

componentDidMount: function () {
// Keyboard events
this.keyboardWillShowEvent = Keyboard.addListener('keyboardWillShow', this.updateKeyboardSpace)
this.keyboardWillHideEvent = Keyboard.addListener('keyboardWillHide', this.resetKeyboardSpace)
if (Platform.OS === 'ios') {
this.keyboardWillShowEvent = Keyboard.addListener('keyboardWillShow', this.updateKeyboardSpace)
this.keyboardWillHideEvent = Keyboard.addListener('keyboardWillHide', this.resetKeyboardSpace)
} else if (Platform.OS === 'android' && this.props.enableOnAndroid) {
this.keyboardWillShowEvent = Keyboard.addListener('keyboardDidShow', this.updateKeyboardSpace)
this.keyboardWillHideEvent = Keyboard.addListener('keyboardDidHide', this.resetKeyboardSpace)
}
},

componentWillUnmount: function () {
Expand All @@ -131,6 +156,10 @@ const KeyboardAwareMixin = {
responder && responder.scrollResponderScrollToEnd({animated: animated})
},

scrollForExtraHeightOnAndroid(extraHeight: number) {
this.scrollToPosition(0, this.position.y + extraHeight, true)
},

/**
* @param keyboardOpeningTime: takes a different keyboardOpeningTime in consideration.
* @param extraHeight: takes an extra height in consideration.
Expand Down
20 changes: 19 additions & 1 deletion lib/KeyboardAwareScrollView.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import React from 'react'
import createReactClass from 'create-react-class'
import { ScrollView } from 'react-native'
import { ScrollView, Platform } from 'react-native'
import PropTypes from 'prop-types'
import KeyboardAwareMixin from './KeyboardAwareMixin'

Expand All @@ -14,6 +14,7 @@ const KeyboardAwareScrollView = createReactClass({
x: PropTypes.number,
y: PropTypes.number,
}),
enableOnAndroid: React.PropTypes.bool,
},
mixins: [KeyboardAwareMixin],

Expand All @@ -23,6 +24,22 @@ const KeyboardAwareScrollView = createReactClass({
},

render: function () {
const {
enableOnAndroid,
contentContainerStyle,
} = this.props

const {
keyboardSpace,
} = this.state

let newContentContainerStyle

if (Platform.OS === 'android' && enableOnAndroid) {
newContentContainerStyle = {}
newContentContainerStyle.paddingBottom = (contentContainerStyle ? contentContainerStyle.paddingBottom : 0) + keyboardSpace
}

return (
<ScrollView
ref='_rnkasv_keyboardView'
Expand All @@ -31,6 +48,7 @@ const KeyboardAwareScrollView = createReactClass({
showsVerticalScrollIndicator={true}
scrollEventThrottle={0}
{...this.props}
contentContainerStyle={newContentContainerStyle || contentContainerStyle}
onScroll={e => {
this.handleOnScroll(e)
this.props.onScroll && this.props.onScroll(e)
Expand Down