Joh*_*ell 6 reactjs react-native
我一直在尝试调整样式和元素的渲染顺序,以使Android和iOS的行为相同。做了大量研究,当前的答案似乎无法解决问题。
问题是此确切代码可在iOS上使用,但不能在Android设备上使用。
class Dropdown extends React.Component {
constructor() {
super()
this.state = {
open: false,
selected: undefined,
}
}
handleSelectPress = () => {
this.setState({open: !this.state.open});
}
handleOptionPress = (item) => {
this.setState({selected: item, open: !this.state.open});
this.props.onSelectOption(item);
}
render () {
const { selected = {}, open } = this.state
const { placeholder = '', options = [] } = this.props
return (
<Select
onPress={this.handleSelectPress}
value={selected.name || placeholder}
open={open}
options={options}
onOptionPress={this.handleOptionPress} />
)
}
}
const shadowStyles = {
ios: {
shadowOpacity: 0.3,
shadowRadius: 3,
shadowOffset: {
height: 1,
width: 1,
},
},
android: {
elevation: 5,
},
}
class Select extends React.PureComponent {
render () {
const { value, open, options, onOptionPress } = this.props
const shadowStyle = shadowStyles[Platform.OS]
return (
<View style={[shadowStyle, styles.wrap]}>
<TouchableWithoutFeedback onPress={this.props.onPress}>
<View style={styles.selectContainer}>
<Text>{value}</Text>
</View>
</TouchableWithoutFeedback>
{open && <View style={styles.menu}>
{ options.map( (item, idx) => <Option value={item} key={idx} onPress={onOptionPress} />)}
</View>}
</View>
)
}
}
class Option extends React.PureComponent {
handlePress = () => {
this.props.onPress(this.props.value)
}
render () {
const { value } = this.props
return (
<TouchableOpacity onPress={this.handlePress}>
<View style={styles.optionContainer}>
<Text>{value.name}</Text>
</View>
</TouchableOpacity>
)
}
}
class App extends React.Component {
render() {
return (
<View style={styles.root}>
<Dropdown
placeholder="--- SELECT ---"
options={
[
{ name: "Press me!", id: "1" },
{ name: "No Me!", id: "2" },
{ name: "Cmon guys, here!", id: "3" },
]
}
onSelectOption={ (item) => console.log(`item pressed! ${item}`)}
/>
</View>
)
}
}
const styles = StyleSheet.create({
root: {
width: 360,
height: 640,
backgroundColor: '#292c2e'
},
wrap: {
position: 'relative',
zIndex: 10,
backgroundColor: 'rgb(73,75,77)'
},
selectContainer: {
padding: 16,
},
menu: {
backgroundColor: 'rgb(73,75,77)',
position: 'absolute',
top: '100%',
left: 0,
right: 0,
maxHeight: 300
},
optionContainer: {
padding: 16
}
});
Run Code Online (Sandbox Code Playgroud)
React Native版本-0.59.3
几件事要注意:
zIndex菜单元素,使其呈现在其他元素之上(在下拉组件之后呈现)。TouchableHighlight,TouchableOpacity,TouchableWithoutFeedback和Android的唯一TouchableNativeFeedbackView和a 之间更改“菜单”元素ScrollView(最初是滚动)Select切换open标志的触摸在Android和iOS上均可正常使用,因此我很确定它的作用范围已缩小到绝对定位的父级。你必须设置位置Select而不是Option
这是小吃: https: //snack.expo.io/HkDHHo6YV
更改wrap和menu样式如下:
wrap: {
position: 'absolute',
zIndex: 10,
width: "100%",
backgroundColor: 'rgb(73,75,77)',
},
menu: {
backgroundColor: 'rgb(73,75,77)',
maxHeight: 300,
},
Run Code Online (Sandbox Code Playgroud)
缺少的部分是考虑下拉菜单下方的空间,因为它是完全绝对定位的。我必须更改Select组件以呈现“填充”元素以占用空间。
class Select extends React.PureComponent {
render() {
const { value, open, options, onOptionPress } = this.props;
const shadowStyle = shadowStyles[Platform.OS];
return (
<>
<View style={{height: 60}}></View>
<View style={[shadowStyle, styles.wrap]}>
<TouchableWithoutFeedback onPress={this.props.onPress}>
<View style={styles.selectContainer}>
<Text>{value}</Text>
</View>
</TouchableWithoutFeedback>
{open && (
<View style={styles.menu}>
{options.map((item, idx) => (
<Option value={item} key={idx} onPress={onOptionPress} />
))}
</View>
)}
</View>
</>
);
}
}
Run Code Online (Sandbox Code Playgroud)
然后将高度调整styles.selectContainer为相同高度60
selectContainer: {
padding: 16,
height: 60
},
Run Code Online (Sandbox Code Playgroud)
import * as React from 'react';
import {
Text,
Button,
View,
StyleSheet,
Platform,
TouchableWithoutFeedback,
TouchableOpacity,
} from 'react-native';
class Dropdown extends React.Component {
constructor() {
super();
this.state = {
open: false,
selected: undefined,
};
}
handleSelectPress = () => {
this.setState({ open: !this.state.open });
};
handleOptionPress = item => {
this.setState({ selected: item, open: !this.state.open });
this.props.onSelectOption(item);
};
render() {
const { selected = {}, open } = this.state;
const { placeholder = '', options = [] } = this.props;
return (
<Select
onPress={this.handleSelectPress}
value={selected.name || placeholder}
open={open}
options={options}
onOptionPress={this.handleOptionPress}
/>
);
}
}
const shadowStyles = {
ios: {
shadowOpacity: 0.3,
shadowRadius: 3,
shadowOffset: {
height: 1,
width: 1,
},
},
android: {
elevation: 5,
},
};
class Select extends React.PureComponent {
render() {
const { value, open, options, onOptionPress } = this.props;
const shadowStyle = shadowStyles[Platform.OS];
return (
<>
<View style={{height: 60}}></View>
<View style={[shadowStyle, styles.wrap]}>
<TouchableWithoutFeedback onPress={this.props.onPress}>
<View style={styles.selectContainer}>
<Text>{value}</Text>
</View>
</TouchableWithoutFeedback>
{open && (
<View style={styles.menu}>
{options.map((item, idx) => (
<Option value={item} key={idx} onPress={onOptionPress} />
))}
</View>
)}
</View>
</>
);
}
}
class Option extends React.PureComponent {
handlePress = () => {
this.props.onPress(this.props.value);
};
render() {
const { value } = this.props;
return (
<TouchableOpacity onPress={this.handlePress}>
<View style={styles.optionContainer}>
<Text>{value.name}</Text>
</View>
</TouchableOpacity>
);
}
}
export default class App extends React.Component {
render() {
return (
<View style={styles.root}>
<Dropdown
placeholder="--- SELECT ---"
options={[
{ name: 'Press me!', id: '1' },
{ name: 'No Me!', id: '2' },
{ name: 'Cmon guys, here!', id: '3' },
]}
onSelectOption={item => console.log(`item pressed! ${item}`)}
/>
<Text>hellof</Text>
<View style={{backgroundColor: "red", height: 250}} />
</View>
);
}
}
const styles = StyleSheet.create({
root: {
width: 360,
height: 640,
backgroundColor: '#292c2e',
marginTop: 100
},
wrap: {
position: 'absolute',
zIndex: 10,
width: "100%",
backgroundColor: 'rgb(73,75,77)',
},
selectContainer: {
padding: 16,
height: 60
},
menu: {
backgroundColor: 'rgb(73,75,77)',
maxHeight: 300,
},
optionContainer: {
padding: 16,
height: 60
},
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
580 次 |
| 最近记录: |