JmJ*_*JmJ 5 javascript android react-native
我已经编写了一个 React Native 应用程序,iOS 是首要任务,所以我首先构建了它。它在 App Store 中并且工作完美,但是我刚刚开始在 Android 上工作,尽管除了触摸事件之外一切似乎都工作正常,而触摸事件根本没有触发。
没有任何可触摸元素正在调用回调onPress
,该元素也没有Button
。我什至尝试完全剥离应用程序,删除导航器,并向初始屏幕添加大量可触摸元素,但仍然没有onPress
触发任何回调。
下面是我的应用程序初始屏幕的代码,尽管我怀疑这些代码是否导致了问题:
// @flow
import React, { type Element } from 'react';
import { View, Text, Image, TouchableOpacity } from 'react-native';
import type { NavigatorScreenProps } from 'react-navigation';
import i18n from '../../i18n';
import style from './style';
type Props = {
navigation: NavigatorScreenProps
}
export default function SignIn ({ navigation }: Props): Element<typeof View> {
return (
<View style={style.container}>
<View style={style.top}>
<Image source={require('../../assets/images/purpleWithTransparentBackground.png')} style={style.logo} />
</View>
<View style={style.bottom}>
<TouchableOpacity activeOpacity={0.97} onPressIn={() => console.log('in')} onPressOut={() => console.log('out')} onPress={() => { console.log('do something!'); navigation.navigate('EnterEmail'); }} style={[style.submit, { zIndex: 99999, elevation: 99999 }]}>
<Text style={style.submitText}>
{i18n.t('SIGN_IN')}
</Text>
</TouchableOpacity>
</View>
<Image source={require('../../assets/images/cityscapeGrey.png')} style={style.cityscape} />
</View>
);
}
Run Code Online (Sandbox Code Playgroud)
组件样式:
import { StyleSheet, Dimensions } from 'react-native';
import defaultStyles from '../../style';
const { width: screenWidth } = Dimensions.get('window');
export default StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: defaultStyles.white
},
top: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
width: '100%'
},
bottom: {
flex: 1,
width: '100%'
},
animatedContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
width: '100%'
},
postcode: {
padding: 12,
height: 50,
backgroundColor: 'white',
width: '100%',
borderRadius: 5,
fontSize: 17
},
text: {
width: 296,
height: 44,
fontFamily: 'SFProText-Light',
fontSize: 16,
fontWeight: '500',
fontStyle: 'normal',
lineHeight: 22,
letterSpacing: 0,
textAlign: 'center',
color: defaultStyles.balticSea
},
logo: {
marginBottom: 14
},
error: {
color: defaultStyles.brickRed,
marginVertical: 12,
width: '100%',
textAlign: 'center'
},
submit: {
width: 311,
height: 56,
borderRadius: 4,
backgroundColor: defaultStyles.mountainMeadow,
justifyContent: 'center',
alignItems: 'center',
alignSelf: 'center',
marginTop: 30
},
submitText: {
width: 311,
height: 21,
fontFamily: 'SFProDisplay-Heavy',
fontSize: 18,
fontWeight: 'bold',
fontStyle: 'normal',
letterSpacing: 0,
textAlign: 'center',
color: defaultStyles.white
},
highlight: {
color: defaultStyles.mountainMeadow
},
cityscape: {
position: 'absolute',
left: 0,
bottom: 0,
width: screenWidth,
resizeMode: 'repeat'
}
});
Run Code Online (Sandbox Code Playgroud)
预先感谢您的任何帮助。
我找到了问题的原因。
简短回答:
我的应用程序的根目录中有一个组件正在创建一个不可见的覆盖层。发生这种情况是因为如果应用于 Android 上的同一元素,display: 'none'
则 和position: 'absolute'
不起作用。
长答案:
在我的根组件中,我有一个从屏幕底部出现的菜单,名为OptionsMenu
:
export default function App (): Element<typeof Provider> {
return (
<Provider store={store}>
<ActionSheetProvider>
<OptionsMenuContext.Provider>
<>
<Navigation uriPrefix={DEEP_LINK_URI_PREFIX} ref={setNavigator} />
<Notification />
<OptionsMenu />
</>
</OptionsMenuContext.Provider>
</ActionSheetProvider>
</Provider>
);
}
Run Code Online (Sandbox Code Playgroud)
里面OptionsMenu
有一个覆盖屏幕的覆盖层,这样我们就可以在菜单出现时调暗所有内容。覆盖层(最外层Animated.View
)具有position: 'absolute'
以及display: 'none'
。设置display
来自 prop,并且position
来自style.container
:
function OptionsMenu ({ hideOptionsMenu, overlayDisplay, overlayOpacity, containerPositionBottom, options = [] }: Props): Element<typeof Animated.View> {
return (
<Animated.View style={[style.container, { display: overlayDisplay }]}>
<TouchableWithoutFeedback onPress={hideOptionsMenu}>
<Animated.View style={[style.overlay, { opacity: overlayOpacity }]} />
</TouchableWithoutFeedback>
<Animated.View style={[style.optionsContainer, { bottom: containerPositionBottom }]}>
{options.map(({ icon, text, onPress, type, component: Component }: Option) => !Component
? (
<TouchableOpacity activeOpacity={0.97} key={text} disabled={!onPress} onPress={onPress} style={style.optionContainer}>
{!!icon && (
<Image source={icon} style={[style.optionIcon, optionTypeTintMap[type]]} />
)}
<Text style={[style.optionText, optionTypeColorMap[type || 'neutralColor']]}>
{text}
</Text>
</TouchableOpacity>
) : (
<Component key={text} />
))}
</Animated.View>
</Animated.View>
);
}
export default withOptionsContext(OptionsMenu);
Run Code Online (Sandbox Code Playgroud)
问题是在 Android 上绝对定位将覆盖显示设置。因此,解决方案是将绝对定位的组件包装在控制显示设置的组件内:
选项菜单/style.js:
export default StyleSheet.create({
container: {
flex: 1,
// Removed these:
// position: 'absolute',
// left: 0,
// bottom: 0,
// width: screenWidth,
// height: screenHeight,
// zIndex: 19,
// elevation: 19
},
// Moved styles to new property:
overlayContainer: {
flex: 1,
position: 'absolute',
left: 0,
bottom: 0,
width: screenWidth,
height: screenHeight,
zIndex: 19,
elevation: 19
},
Run Code Online (Sandbox Code Playgroud)
选项菜单/OptionsMenu.js:
function OptionsMenu ({ hideOptionsMenu, overlayDisplay, overlayOpacity, containerPositionBottom, options = [] }: Props): Element<typeof Animated.View> {
return (
// Added new <View /> to control display setting separately:
<View style={[style.container, { display: overlayDisplay }]}>
<Animated.View style={style.overlayContainer}>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2522 次 |
最近记录: |