[英]Scrollview not working on android, but works on iOS in react native
I want to have a scroll in the list.我想在列表中滚动。
In ios its working fine but in android scroll is not working.在 ios 中它工作正常但在 android 中滚动不工作。 In the below code, if I give height to the green view its working, but I want to achieve it without giving height to the green view, because of my usecase, it should always overlap the white text.
在下面的代码中,如果我为绿色视图提供高度,但我想在不为绿色视图提供高度的情况下实现它,因为我的用例,它应该始终与白色文本重叠。
Please see the below code -请看下面的代码 -
App.tsx应用程序.tsx
import {View, Text, Alert, StyleSheet} from 'react-native';
import React, {useState} from 'react';
import SearchableDropdown from './searchableDropdown';
var items = [
{
id: 1,
name: 'JavaScript',
},
{
id: 2,
name: 'Java',
},
{
id: 3,
name: 'Ruby',
},
{
id: 4,
name: 'React Native',
},
{
id: 5,
name: 'PHP',
},
{
id: 6,
name: 'Python',
},
{
id: 7,
name: 'Go',
},
{
id: 8,
name: 'Swift',
},
];
const App = () => {
const [selectedItem, setSelectedItem] = useState<any>(null);
return (
<View style={{backgroundColor: 'blue', flex: 1}}>
<SearchableDropdown
onItemSelect={(item: any) => {
console.log('on item selected :', item);
setSelectedItem(item.name);
}}
containerStyle={{
zIndex: 200,
backgroundColor: 'green',
padding: 5,
width: 200,
marginTop: 100,
}}
onRemoveItem={(item: any, index: number) => {
setSelectedItem(null);
}}
itemStyle={styles.itemStyle}
itemTextStyle={{color: '#222'}}
itemsContainerStyle={{maxHeight: 140}}
items={items}
resetValue={false}
textInputProps={{
value: selectedItem,
placeholder: 'Select Location',
underlineColorAndroid: 'transparent',
onTextChange: (text: string) => console.log('on text change :', text),
}}
listProps={{
nestedScrollEnabled: true,
}}
/>
<Text>fjsdkfjka</Text>
<Text>fjsdkfjka</Text>
<Text>fjsdkfjka</Text>
<Text>fjsdkfjka</Text>
<Text>fjsdkfjka</Text>
<Text>fjsdkfjka</Text>
</View>
);
};
export default App;
const styles = StyleSheet.create({
itemStyle: {
padding: 10,
backgroundColor: '#ddd',
borderColor: '#bbb',
borderWidth: 1,
borderRadius: 5,
},
});
searchableDropdown.tsx searchableDropdown.tsx
import React, {Component, useEffect, useState} from 'react';
import {
Text,
FlatList,
TextInput,
View,
TouchableOpacity,
Keyboard,
} from 'react-native';
import Entypo from 'react-native-vector-icons/Entypo';
const defaultItemValue = {
name: '',
id: 0,
};
const SearchableDropdown = (props: any) => {
const [item, setItem] = useState<any>({});
const [listItems, setListItems] = useState<any>([]);
const [focus, setFocus] = useState<any>(false);
const [viewHeight, setViewHeight] = useState<any>(0);
let input: any = null;
const renderFlatList = () => {
if (focus) {
const flatListPorps = {...props.listProps};
const oldSupport = [
{key: 'keyboardShouldPersistTaps', val: 'always'},
{key: 'nestedScrollEnabled', val: false},
{key: 'style', val: {...props.itemsContainerStyle}},
{key: 'data', val: listItems},
{
key: 'keyExtractor',
val: (item: any, index: number) => index.toString(),
},
{
key: 'renderItem',
val: ({item, index}: any) => renderItems(item, index),
},
{
key: 'contentContainerStyle',
val: {...props.contentContainerStyle},
},
];
oldSupport.forEach(kv => {
if (!Object.keys(flatListPorps).includes(kv.key)) {
flatListPorps[kv.key] = kv.val;
} else {
if (kv.key === 'style') {
flatListPorps['style'] = kv.val;
}
}
});
return (
<View
style={{
position: 'absolute',
backgroundColor: 'red',
width: '100%',
opacity: 1,
zIndex: 1,
marginTop: 60,
}}>
<FlatList {...flatListPorps} />
</View>
);
}
};
useEffect(() => {
const listItems = props.items;
const defaultIndex = props.defaultIndex;
if (defaultIndex && listItems.length > defaultIndex) {
setItem(listItems[defaultIndex]);
setListItems(listItems);
} else {
setListItems(listItems);
}
}, []);
const searchedItems = (searchedText: string) => {
let setSort = props.setSort;
if (!setSort && typeof setSort !== 'function') {
setSort = (item: any, searchedText: string) => {
return item.name.toLowerCase().indexOf(searchedText.toLowerCase()) > -1;
};
}
var ac = props.items.filter((item: any) => {
return setSort(item, searchedText);
});
let item = {
id: -1,
name: searchedText,
};
setItem(item);
setListItems(ac);
const onTextChange =
props.onTextChange ||
props.textInputProps.onTextChange ||
props.onChangeText ||
props.textInputProps.onChangeText;
if (onTextChange && typeof onTextChange === 'function') {
setTimeout(() => {
onTextChange(searchedText);
}, 0);
}
};
const renderItems = (item: any, index: number) => {
if (props.multi && props.selectedItems && props.selectedItems.length > 0) {
return props.selectedItems.find((sitem: any) => sitem.id === item.id) ? (
<TouchableOpacity
style={{...props.itemStyle, flex: 1, flexDirection: 'row'}}>
<View
style={{
flex: 0.9,
flexDirection: 'row',
alignItems: 'flex-start',
}}>
<Text>{item.name}</Text>
</View>
<View
style={{flex: 0.1, flexDirection: 'row', alignItems: 'flex-end'}}>
<TouchableOpacity
onPress={() =>
setTimeout(() => {
props.onRemoveItem(item, index);
}, 0)
}
style={{
backgroundColor: '#f16d6b',
alignItems: 'center',
justifyContent: 'center',
width: 25,
height: 25,
borderRadius: 100,
marginLeft: 10,
}}>
<Text>X</Text>
</TouchableOpacity>
</View>
</TouchableOpacity>
) : (
<TouchableOpacity
onPress={() => {
setItem(item);
setTimeout(() => {
props.onItemSelect(item);
}, 0);
}}
style={{...props.itemStyle, flex: 1, flexDirection: 'row'}}>
<View
style={{flex: 1, flexDirection: 'row', alignItems: 'flex-start'}}>
<Text>{item.name}</Text>
</View>
</TouchableOpacity>
);
} else {
return (
<TouchableOpacity
style={{...props.itemStyle}}
onPress={() => {
setFocus(false);
setItem(item);
Keyboard.dismiss();
setTimeout(() => {
props.onItemSelect(item);
if (props.resetValue) {
setFocus(true);
setItem(defaultItemValue);
input.focus();
}
}, 0);
}}>
{props.selectedItems &&
props.selectedItems.length > 0 &&
props.selectedItems.find((x: any) => x.id === item.id) ? (
<Text style={{...props.itemTextStyle}}>{item.name}</Text>
) : (
<Text style={{...props.itemTextStyle}}>{item.name}</Text>
)}
</TouchableOpacity>
);
}
};
const renderListType = () => {
return renderFlatList();
};
const renderTextInput = () => {
const textInputProps = {...props.textInputProps};
const oldSupport = [
{key: 'ref', val: (e: any) => (input = e)},
{
key: 'onTextChange',
val: (text: string) => {
searchedItems(text);
},
},
{key: 'underlineColorAndroid', val: props.underlineColorAndroid},
{
key: 'onFocus',
val: () => {
props.onFocus && props.onFocus();
setFocus(true);
setItem(defaultItemValue);
setListItems(props.items);
},
},
{
key: 'onBlur',
val: () => {
props.onBlur && props.onBlur(this);
setFocus(false);
setItem(props.selectedItems);
},
},
{
key: 'value',
val: item ? item.name : '',
},
{
key: 'style',
val: {...props.textInputStyle},
},
{
key: 'placeholderTextColor',
val: props.placeholderTextColor,
},
{
key: 'placeholder',
val: props.placeholder,
},
];
oldSupport.forEach(kv => {
if (!Object.keys(textInputProps).includes(kv.key)) {
if (kv.key === 'onTextChange' || kv.key === 'onChangeText') {
textInputProps['onChangeText'] = kv.val;
} else {
textInputProps[kv.key] = kv.val;
}
} else {
if (kv.key === 'onTextChange' || kv.key === 'onChangeText') {
textInputProps['onChangeText'] = kv.val;
}
}
});
return (
<View
onLayout={event => {
let {x, y, width, height} = event.nativeEvent.layout;
setViewHeight(height);
}}
style={{
flexDirection: 'row',
width: 200,
borderWidth: 1,
borderColor: '#ccc',
}}>
{textInputProps.value === null ? (
<TextInput
{...textInputProps}
style={{
padding: 12,
borderRadius: 5,
justifyContent: 'center',
alignItems: 'center',
width: 150,
height: 50,
}}
onBlur={e => {
if (props.onBlur) {
props.onBlur(e);
}
if (props.textInputProps && props.textInputProps.onBlur) {
props.textInputProps.onBlur(e);
}
setFocus(false);
setItem(props.selectedItems);
}}
/>
) : (
<View
style={{
height: 40,
width: 130,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
margin: 5,
marginLeft: 10,
marginRight: 10,
backgroundColor: '#d9c979',
borderRadius: 20,
paddingLeft: 10,
}}>
<Text numberOfLines={1}>{textInputProps.value}</Text>
<TouchableOpacity onPress={props.onRemoveItem}>
<Entypo name={'cross'} style={{fontSize: 20}} />
</TouchableOpacity>
</View>
)}
<View
style={{
width: 48,
backgroundColor: '#454545',
justifyContent: 'center',
alignItems: 'center',
}}>
<Entypo name={'chevron-down'} />
</View>
</View>
);
};
const renderSelectedItems = () => {
let items = props.selectedItems || [];
if (items !== undefined && items.length > 0 && props.chip && props.multi) {
return (
<View
style={{
flexDirection: 'row',
flexWrap: 'wrap',
paddingBottom: 10,
marginTop: 5,
}}>
{items.map((item: any, index: number) => {
return (
<View
key={index}
style={{
width: item.name.length * 8 + 60,
justifyContent: 'center',
flex: 0,
backgroundColor: '#eee',
flexDirection: 'row',
alignItems: 'center',
margin: 5,
padding: 8,
borderRadius: 15,
}}>
<Text style={{color: '#555'}}>{item.name}</Text>
<TouchableOpacity
onPress={() =>
setTimeout(() => {
props.onRemoveItem(item, index);
}, 0)
}
style={{
backgroundColor: '#f16d6b',
alignItems: 'center',
justifyContent: 'center',
width: 25,
height: 25,
borderRadius: 100,
marginLeft: 10,
}}>
<Text>X</Text>
</TouchableOpacity>
</View>
);
})}
</View>
);
}
};
return (
<View
//keyboardShouldPersist="always"
style={{...props.containerStyle}}>
{renderSelectedItems()}
{renderListType()}
{renderTextInput()}
</View>
);
};
export default SearchableDropdown;
I have created an working example based on your code我已经根据您的代码创建了一个工作示例
backgroundColor and zIndex in your App.tsx were the culprit. App.tsx 中的 backgroundColor 和 zIndex 是罪魁祸首。
React Native/JSX is not html and you shouldn't treat it like that. React Native/JSX 不是 html,你不应该那样对待它。 The document flow behaves different and there is no w3c which defines how component should work.
文档流的行为不同,并且没有定义组件应该如何工作的 w3c。
There are a bunch of issues with your approach eg if you want to add the dropdown in another scrollview/flatlist you have a nested scrollview which won't work properly.你的方法有很多问题,例如,如果你想在另一个滚动视图/平面列表中添加下拉列表,你有一个无法正常工作的嵌套滚动视图。
I would suggest to solve your needs with another design approach我建议用另一种设计方法来解决您的需求
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.