Skip to content

Commit 544d75e

Browse files
authored
Move from KeyboardAwareListView to KeyboardAwareFlatList (#960)
* KeyboardAwareFlatList - add new type to the KeyboardAware views (deprecate KeyboardAwareListView) * Fix screen * Fix scrollToBottom (wrong offset, FlatList not working properly) + use scrollToEnd and remove ScrollViewManager (which is iOS only) * Remove inline method for onScroll * Allow overriding scrollEventThrottle * Fix name of screen's method * Fix keyboard closing on Android on TextFields near the end of the screen * Remove inline method for onScroll + Allow overriding scrollEventThrottle in ListView
1 parent 5e2bf0e commit 544d75e

File tree

8 files changed

+225
-212
lines changed

8 files changed

+225
-212
lines changed

demo/src/screens/componentScreens/KeyboardAwareScrollViewScreen.js

Lines changed: 119 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1,204 +1,164 @@
1+
import _ from 'lodash';
12
import React, {Component} from 'react';
2-
import {StyleSheet, TouchableHighlight, RecyclerViewBackedScrollView} from 'react-native';
3+
import {StyleSheet} from 'react-native';
34
import {
4-
Button,
55
Colors,
66
KeyboardAwareScrollView,
7-
KeyboardAwareListView,
7+
KeyboardAwareFlatList,
88
TextField,
99
Text,
1010
Typography,
1111
View
1212
} from 'react-native-ui-lib';
13+
import {renderBooleanOption} from '../ExampleScreenPresenter';
1314

14-
const LOREM_IPSUM =
15-
'Lorem ipsum dolor sit amet, ius ad pertinax oportere accommodare, an vix civibus corrumpit referrentur. Te nam case ludus inciderint, te mea facilisi adipiscing. Sea id integre luptatum. In tota sale consequuntur nec. Erat ocurreret mei ei. Eu paulo sapientem vulputate est, vel an accusam intellegam interesset. Nam eu stet pericula reprimique, ea vim illud modus, putant invidunt reprehendunt ne qui.';
16-
const hashCode = function (str) {
17-
let hash = 15;
18-
for (let ii = str.length - 1; ii >= 0; ii--) {
19-
// eslint-disable-next-line no-bitwise
20-
hash = (hash << 5) - hash + str.charCodeAt(ii);
15+
const data = [
16+
{
17+
placeholder: 'First Name',
18+
ref: '_firstNameTI',
19+
nextRef: '_lastNameTI'
20+
},
21+
{
22+
placeholder: 'Last Name',
23+
ref: '_lastNameTI',
24+
nextRef: '_countryTI'
25+
},
26+
{
27+
placeholder: 'Country',
28+
ref: '_countryTI',
29+
nextRef: '_stateTI'
30+
},
31+
{
32+
placeholder: 'State',
33+
ref: '_stateTI',
34+
nextRef: '_addrTI'
35+
},
36+
{
37+
placeholder: 'Address',
38+
ref: '_addrTI',
39+
nextRef: '_emailTI'
40+
},
41+
{
42+
placeholder: 'Email',
43+
keyboardType: 'email-address',
44+
ref: '_emailTI',
45+
nextRef: '_msgTI'
46+
},
47+
{
48+
placeholder: 'Message',
49+
ref: '_msgTI',
50+
nextRef: '_notesTI'
51+
},
52+
{
53+
placeholder: 'Notes',
54+
ref: '_notesTI'
2155
}
22-
return hash;
23-
};
56+
];
2457

2558
export default class KeyboardAwareScrollViewScreen extends Component {
2659
constructor(props) {
2760
super(props);
2861
this.state = {
29-
listToggle: false,
30-
data: {}
62+
isFlatList: false
3163
};
3264
}
3365

34-
_genRows(pressData) {
35-
const dataBlob = [];
36-
for (let ii = 0; ii < 10; ii++) {
37-
const pressedText = pressData[ii] ? ' (pressed)' : '';
38-
dataBlob.push('Row ' + ii + pressedText);
39-
}
40-
return dataBlob;
41-
}
42-
43-
_renderRow(rowData, sectionID, rowID) {
44-
const rowHash = Math.abs(hashCode(rowData));
66+
renderItem = (data) => {
67+
const {isFlatList} = this.state;
68+
const item = isFlatList ? data.item : data;
69+
const {placeholder, ref, nextRef, keyboardType} = item;
70+
const returnKeyType = nextRef ? 'next' : 'go';
71+
const onSubmitEditing = nextRef ? () => this[nextRef].focus() : undefined;
4572
return (
46-
<TouchableHighlight>
47-
<View>
48-
<View style={styles.row}>
49-
<Text style={styles.text}>{rowData + ' - ' + LOREM_IPSUM.substr(0, (rowHash % 301) + 10)}</Text>
50-
</View>
51-
<View style={{backgroundColor: Colors.white}}>
52-
<TextField style={[styles.text, {borderWidth: 0.5}]} placeholder={'Text goes here'}/>
53-
</View>
54-
</View>
55-
</TouchableHighlight>
73+
<TextField
74+
key={placeholder}
75+
text70R
76+
placeholder={placeholder}
77+
ref={(r) => {
78+
this[ref] = r;
79+
}}
80+
returnKeyType={returnKeyType}
81+
keyboardType={keyboardType}
82+
onSubmitEditing={onSubmitEditing}
83+
/>
5684
);
57-
}
85+
};
86+
87+
keyExtractor = (item) => item.placeholder;
5888

59-
_renderBodyButton(bodyHeaderTitle) {
89+
renderKeyboardAwareFlatList() {
6090
return (
61-
<Button
62-
text80
63-
link
64-
label={bodyHeaderTitle}
65-
labelStyle={{color: Colors.black}}
66-
onPress={() => this.setState({listToggle: !this.state.listToggle})}
67-
style={styles.topButton}
91+
<KeyboardAwareFlatList
92+
showsVerticalScrollIndicator={false}
93+
keyboardDismissMode="interactive"
94+
keyboardShouldPersistTaps="always"
95+
data={data}
96+
contentContainerStyle={{paddingTop: 20}}
97+
keyExtractor={this.keyExtractor}
98+
renderItem={this.renderItem}
99+
getTextInputRefs={() => {
100+
return [
101+
this._firstNameTI,
102+
this._lastNameTI,
103+
this._countryTI,
104+
this._stateTI,
105+
this._addrTI,
106+
this._emailTI,
107+
this._msgTI,
108+
this._notesTI
109+
];
110+
}}
68111
/>
69112
);
70113
}
71114

72-
_renderKeyboardAwareListView() {
115+
renderKeyboardAwareScrollView() {
73116
return (
74-
<View style={styles.container}>
75-
{this._renderBodyButton('Switch to ScrollView')}
76-
<KeyboardAwareListView
77-
keyboardDismissMode="interactive"
78-
keyboardShouldPersistTaps="always"
79-
dataSource={this.state.data}
80-
renderRow={this._renderRow}
81-
renderScrollComponent={props => <RecyclerViewBackedScrollView {...props}/>}
82-
renderSeparator={(sectionID, rowID) => <View key={`${sectionID}-${rowID}`} style={styles.separator}/>}
83-
/>
84-
</View>
117+
<KeyboardAwareScrollView
118+
showsVerticalScrollIndicator={false}
119+
keyboardDismissMode="interactive"
120+
keyboardShouldPersistTaps="always"
121+
getTextInputRefs={() => {
122+
return [
123+
this._firstNameTI,
124+
this._lastNameTI,
125+
this._countryTI,
126+
this._stateTI,
127+
this._addrTI,
128+
this._emailTI,
129+
this._msgTI,
130+
this._notesTI
131+
];
132+
}}
133+
>
134+
{_.map(data, (item) => this.renderItem(item))}
135+
</KeyboardAwareScrollView>
85136
);
86137
}
87138

88-
_renderKeyboardAwareScrollView() {
139+
render() {
140+
const {isFlatList} = this.state;
141+
const switchText = `${
142+
isFlatList ? 'KeyboardAwareFlatList' : 'KeyboardAwareScrollView'
143+
}`;
89144
return (
90145
<View style={styles.container}>
91146
<Text text65 marginB-20>
92-
KeyboardAwareScrollView
147+
KeyboardAware example form
93148
</Text>
94-
<Text text65R style={{marginBottom: 10}}>Example Form</Text>
95-
96-
{this.state.listToggle && this._renderBodyButton('Switch to ListView')}
97-
<KeyboardAwareScrollView
98-
showsVerticalScrollIndicator={false}
99-
keyboardDismissMode="interactive"
100-
keyboardShouldPersistTaps="always"
101-
getTextInputRefs={() => {
102-
return [
103-
this._firstNameTI,
104-
this._lastNameTI,
105-
this._countryTI,
106-
this._stateTI,
107-
this._addrTI,
108-
this._emailTI,
109-
this._msgTI,
110-
this._notesTI
111-
];
112-
}}
113-
>
114-
<TextField
115-
style={styles.TextField}
116-
placeholder={'First Name'}
117-
ref={r => {
118-
this._firstNameTI = r;
119-
}}
120-
returnKeyType={'next'}
121-
onSubmitEditing={event => this._lastNameTI.focus()}
122-
/>
123-
<TextField
124-
style={styles.TextField}
125-
placeholder={'Last Name'}
126-
ref={r => {
127-
this._lastNameTI = r;
128-
}}
129-
returnKeyType={'next'}
130-
onSubmitEditing={event => this._countryTI.focus()}
131-
/>
132-
<TextField
133-
style={styles.TextField}
134-
placeholder={'Country'}
135-
ref={r => {
136-
this._countryTI = r;
137-
}}
138-
returnKeyType={'next'}
139-
onSubmitEditing={event => this._stateTI.focus()}
140-
/>
141-
<TextField
142-
style={styles.TextField}
143-
placeholder={'State'}
144-
ref={r => {
145-
this._stateTI = r;
146-
}}
147-
returnKeyType={'next'}
148-
onSubmitEditing={event => this._addrTI.focus()}
149-
/>
150-
<TextField
151-
style={styles.TextField}
152-
placeholder={'Address'}
153-
ref={r => {
154-
this._addrTI = r;
155-
}}
156-
returnKeyType={'next'}
157-
onSubmitEditing={event => this._emailTI.focus()}
158-
/>
159-
<TextField
160-
style={styles.TextField}
161-
keyboardType="email-address"
162-
placeholder={'Email'}
163-
ref={r => {
164-
this._emailTI = r;
165-
}}
166-
returnKeyType={'next'}
167-
onSubmitEditing={event => this._msgTI.focus()}
168-
/>
169-
<TextField
170-
style={styles.TextField}
171-
placeholder={'Message'}
172-
ref={r => {
173-
this._msgTI = r;
174-
}}
175-
returnKeyType={'next'}
176-
onSubmitEditing={event => this._notesTI.focus()}
177-
/>
178-
<TextField
179-
style={styles.TextField}
180-
placeholder={'Notes'}
181-
ref={r => {
182-
this._notesTI = r;
183-
}}
184-
returnKeyType={'go'}
185-
/>
186-
</KeyboardAwareScrollView>
149+
{renderBooleanOption.call(this, switchText, 'isFlatList')}
150+
<View height={40}/>
151+
{isFlatList
152+
? this.renderKeyboardAwareFlatList()
153+
: this.renderKeyboardAwareScrollView()}
187154
</View>
188155
);
189156
}
190-
191-
render() {
192-
if (this.state.listToggle) {
193-
return this._renderKeyboardAwareListView();
194-
} else {
195-
return this._renderKeyboardAwareScrollView();
196-
}
197-
}
198157
}
199158

200159
const styles = StyleSheet.create({
201160
container: {
161+
flex: 1,
202162
padding: 20
203163
},
204164
TextField: {

0 commit comments

Comments
 (0)