#javascript #css #reactjs #react-native #uiscrollview
#javascript #css #reactjs #react-native #uiscrollview
Вопрос:
У меня есть экран, на котором я ввожу текст в поле ввода и получаю соответствующие результаты поиска. Список отображается в ScrollView, но он по-прежнему не позволяет мне прокручивать, когда открыта клавиатура (в Android).
Как я могу это исправить?
return (
<>
{addressesFound.length > 0 ? (
<ScrollView
style={styles.searchResultsContainer}
keyboardShouldPersistTaps={'always'}
keyboardDismissMode={'on-drag'}>
{addressesFound.map((addressDetails: addressDetailsType) => {
return (
<View
key={addressDetails.placeName}
style={styles.resultContainer}>
<Text
style={styles.text}>
{addressDetails.placeName}
</Text>
</View>
);
})}
</ScrollView>
) : null}
</>
);
};
const styles = StyleSheet.create({
searchResultsContainer: {
width: moderateScale(400),
paddingHorizontal: moderateScale(50),
paddingRight: moderateScale(65),
marginTop: moderateScale(10),
flex:1,
},
resultContainer: {
marginTop: moderateScale(10),
borderBottomWidth: 1,
borderBottomColor: 'grey',
},
text: {
fontSize: moderateScale(15),
},
});
Я уже пытался добавить nestedScrollEnabled={true}, но это не имеет никакого значения.
Именно здесь вызывается вышеупомянутый компонент:
<View style={styles.dropdown}>
<LocationsFound
addressesFound={locations.addressesFoundList} />
....
dropdown: {
position: 'absolute',
top: moderateScale(215),
zIndex: moderateScale(10),
backgroundColor: '#fff',
flex: 1,
},
Я попытался добавить высоту: 80% к dropdown
. Это позволяет немного прокрутить. Однако, когда клавиатура открыта, я могу прокручивать, но не до конца. Если я добавлю высоту: 100%, я вообще не смогу прокручивать.
Ответ №1:
Я думаю, что если содержимое вашего ScrollView меньше экрана, оно не будет прокручиваться. Итак, вы можете попробовать создать height: «150%» или что-то в этом роде или добавить в пустой вид с высотой, чтобы растянуть ScrollView выше вашего экрана.
Перенос ScrollView в представление с высотой > экран тоже будет работать.
Комментарии:
1. Если я оберну ScrollView другим представлением
<View style={{height: "auto", maxHeight: screenHeight*2}}>
, отображаемый список будет просто обычным представлением, в котором содержимое отсутствует. Я также пытался добавитьheight: "150%"
вsearchResultsContainer
, но это не имеет значения
Ответ №2:
Я думаю, вы можете исправить эту проблему, следуя приведенным ниже советам: 1) Отрегулировав положение тега ScrollView, скорее всего, оно будет выше вашего условия непосредственно внутри <></> или добавьте тег view над тегом ScrollView, например
<><View style={{ Height: "auto", maxHeight: screenHeight}}><ScrollView>....</ScrollView></view></>
2) Путем настройки высоты, свойства maxHeight и свойства flex
Если у вас это сработало, пожалуйста, дайте мне знать
Комментарии:
1. Условие является необходимым. Если я оберну ScrollView другим представлением
<View style={{height: "auto", maxHeight: screenHeight}}>
, отображаемый список будет просто обычным представлением, в котором содержимое отсутствует.2. Что именно я могу попробовать, чтобы «отрегулировать высоту / max-height» и где? Добавление его в
dropdown
не сработало.
Ответ №3:
Я подготовил демонстрационную версию вашей проблемы и изучил ее. Я думаю, что решил это. взгляните на это:
Это ссылка на выставку закусок
Чтобы описать об этом:
Как я выяснил, ваша проблема заключалась в том, что ScrollView
высота не менялась ни в каких ситуациях, даже при увеличении height
или giving paddingBottom
.
поэтому я завернул ScrollView
в View
тег и придал ему этот стиль:
scrollViewWrapper: {
width: '100%',
minHeight: '100%',
paddingBottom: 1.3*keyboardHeight
}
В этом стиле вы видите параметр keyboardHeight
, который state
я устанавливаю в componentDidMount
с помощью приведенных ниже кодов:
import {Keyboard} from 'react-native';
state = {
keyboardHeight: 0,
}
componentDidMount() {
this.keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
this._keyboardDidShow
);
this.keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
this._keyboardDidHide
);
}
_keyboardDidShow = (e) => {
this.setState({
keyboardHeight: e.endCoordinates.height,
});
};
Я должен упомянуть, что вы не можете переместить стиль paddingBottom: 1.3*keyboardHeight
за пределы компонента класса и поместить его в styles
object, потому что keyboardHeight
это state
, он может быть известен только внутри компонента.
Я предлагаю вам взглянуть на мой код в expo snack, чтобы лучше понять мои описания.
Я надеюсь, что это решит вашу проблему.
Редактировать для функциональных компонентов
используйте приведенный ниже код для определения высоты клавиатуры при написании функциональных компонентов:
const [keyboardHeight, setKeyboardHeight] = useState(0)
const [scrollViewVisibility, setScrollViewVisibility] = useState(false)
useEffect(() => {
Keyboard.addListener("keyboardDidShow", _keyboardDidShow);
// cleanup function
return () => {
Keyboard.removeListener("keyboardDidShow", _keyboardDidShow);
};
}, []);
const _keyboardDidShow = (e) => {
console.log("============in keyboardDidShow")
setKeyboardHeight(e.endCoordinates.height)
};
Я также отредактировал expo snack. вы можете взглянуть на это, чтобы увидеть рабочий пример.
Комментарии:
1. Не могли бы вы изменить его в соответствии с функциональными компонентами? Для состояния мы можем использовать useState, а для componentDidMount мы можем использовать useEffect, но я не могу понять, как заменить
this.keyboardDidShowListener
в моем случае.2. Кроме того, я не могу оценить вашу выставку закусок, поскольку она немного отличается от моей. В моем случае, как только список отображается, клавиатура все еще открыта. Однако в вашей выставке клавиатура исчезает, когда я выполняю поиск по отображаемому списку.
3. @Jnl Я изменил expo snack и написал правку для этого решения. проверьте это. что касается разницы между моим кодом и вашим, да, есть некоторые различия, но я думаю, вы проверили мой snack в веб-режиме, проверьте его в режиме iPhone. Вы увидите, что он так похож на ваш.
4.Это вроде как работает, если я добавлю дополнительную высоту: ‘80%’ к моей
dropdown
View
, которая является родительской для всего компонента LocationsFound list. Возможно ли также переместить стиль высоты в LocationsFound? Такое, что его можно автоматически вычислять на разных экранах.5. Мой LocationFound похож на вашу выставку, за вычетом представления контейнера и ввода текста в самом верху. Если я не добавлю высоту в выпадающий список отдельно, он не прокручивается.
Ответ №4:
Я могу придумать три решения (вы можете попробовать любое из них):
1-Попробуйте обернуть вид прокрутки внутри тега view с помощью flex = 1, например:
<View style={{ flex:1 }}>
<ScrollView>
</ScrollView>
</View>
2-если вы не хотите использовать представление, вы можете установить ScrollView flex равным 1
3-в первом решении вы можете использовать пустой тег вместо представления следующим образом:
<>
</>
Комментарии:
1. К сожалению, ни один из них не сработал для меня. Кроме того, в моем возврате уже есть один пустой тег.
2. Вы пробовали использовать flatlist вместо scrollview?
3. Нет, по крайней мере, пока. Я добавил еще немного информации в qs, чтобы
Ответ №5:
Если ваша проблема связана только с открытой клавиатурой, возможно, вам захочется взглянуть на KeyboardAvoidingView
У меня было много проблем с этим! Вы хотите попробовать все настройки для prop behavior
. вероятно, есть один, который работает для вас!
Из их примеров:
import React from 'react';
import { View, KeyboardAvoidingView, TextInput, StyleSheet, Text, Platform,
TouchableWithoutFeedback, Button, Keyboard } from 'react-native';
const KeyboardAvoidingComponent = () => {
return (
<KeyboardAvoidingView
behavior={Platform.OS == "ios" ? "padding" : "height"}
style={styles.container}
>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.inner}>
<Text style={styles.header}>Header</Text>
<TextInput placeholder="Username" style={styles.textInput} />
<View style={styles.btnContainer}>
<Button title="Submit" onPress={() => null} />
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1
},
inner: {
padding: 24,
flex: 1,
justifyContent: "space-around"
},
header: {
fontSize: 36,
marginBottom: 48
},
textInput: {
height: 40,
borderColor: "#000000",
borderBottomWidth: 1,
marginBottom: 36
},
btnContainer: {
backgroundColor: "white",
marginTop: 12
}
});
export default KeyboardAvoidingComponent;
Ответ №6:
просто измените стиль ScrollView, попробуйте указать высоту, и это сработает, а затем вы можете указать высоту в соответствии со стандартным Android.
Комментарии:
1. Привет, @jozem, вы отвечаете на старый вопрос, и кажется, что ваш ответ не добавляет много информации относительно других. Пожалуйста, подумайте о том, чтобы расширить свою точку зрения