我正在尝试实现一个基本的抽屉,但我对文档感到困惑。
有一个TouchableHighlight,还有一个TouchableNativeFeedback。
TouchableNativeFeedback仅限Android。那么,我怎样才能最好地处理我的MenuItem组件,以便它同时处理Android和IOS?
这是我到目前为止所得到的,我不知道如何在这里处理不同平台特定的可触摸内容:
import React, { Component, PropTypes } from 'react';
import { TouchableHighlight, TouchableNativeFeedback, Platform, View, Text } from 'react-native';
export class MenuItem extends Component {
handleAndroid() {
}
handleIOS() {
}
renderMenuItem() {
return (
<View style={styles.container}>
<Text style={styles.text}>
{this.props.text}
</Text>
</View>
);
}
render() {
return (
);
}
}
在Android上,我是否只能使用TouchableNativeFeedback?
答案 0 :(得分:18)
就像你说的那样,TouchableNativeFeedback
仅适用于Android,因此它不适用于iOS。如果您想要一个适用于两者的解决方案,请使用TouchableHighlight
并相应地设置样式。例如,它的underlayColor
道具允许您设置“触摸处于活动状态时将显示的参考底图的颜色。”
修改强>
如果您想使用Android的TouchableNativeFeedback
和iOS的TouchableHighlight
,您应该执行以下操作:
import { Platform } from 'react-native'
...
render() {
if (Platform.OS === 'android') {
return (
<TouchableNativeFeedback>
...
</TouchableNativeFeedback>
)
} else {
return (
<TouchableHighlight>
...
</TouchableHighlight>
)
}
}
编辑2:
或者,您可以为每个平台创建自定义组件并使用文件扩展名。例如:
MyButton.ios.js
MyButton.android.js
将这两个放在同一个文件夹中,然后使用MyButton
作为常规组件:
import MyButton from '../path/to/component/MyButton'
...
render() {
<MyButton/>
}
如果您想在多个地方使用此组件,这是非常简洁的,因为您没有使用if-else块填充代码。
您可以在此处详细了解Platform Specific Code。
答案 1 :(得分:3)
您可以通过以下更优雅的方式解决此问题:
render() {
let TouchablePlatformSpecific = Platform.OS === 'ios' ?
TouchableOpacity :
TouchableNativeFeedback;
let touchableStyle = Platform.OS === 'ios' ?
styles.iosTouchable :
styles.androidTouchable
return(
<TouchablePlatformSpecific style={touchableStyle}>
(...)
</TouchablePlatformSpecific>
);
}
我一直在成功使用它,但我看不出它不起作用的原因,对我来说看起来不错。
答案 2 :(得分:2)
一种更好的实现方式是使笨拙的组件产生通用的Touchable,后者可根据平台运行并处理onPress事件。
可触摸组件:
import { Platform } from "react-native"
import { TouchableNativeFeedback, TouchableOpacity } from "react-native"
import React from "react"
export const Touchable = (props: any) => {
return Platform.OS === 'android'
? <TouchableNativeFeedback onPress={props.onPress}>{props.children}</TouchableNativeFeedback>
: <TouchableOpacity onPress={props.onPress}>{props.children}</TouchableOpacity>
}
用法:
import { Touchable } from '../path/to/touchable.component';
...
render() {
<Touchable onPress={() => this.handleClick()}>
.....
</Touchable>
}
感谢@Giorgos的实现,它是此答案的基础。
答案 3 :(得分:0)
或者您可以创建一个这样的自定义组件:
import { TouchableNativeFeedback, TouchableOpacity } from 'react-native'
...
const Touchable = (props) => {
return Platform.OS === 'android'
? <TouchableNativeFeedback>{props.children}</TouchableNativeFeedback>
: <TouchableOpacity>{props.children}</TouchableOpacity>
}
然后像这样使用它:
<Touchable>
<Card>
<Text>Click me!</Text>
</Card>
</Touchable>
答案 4 :(得分:0)
我也有几乎相同的要求,最终我使用了这个库react-native-haptic-feedback。
请记住,触觉反馈仅在某些最新的android设备和iPhone 6s以上的iOS中可用。对于没有触觉电机的设备,会产生振动。这是一个示例代码片段:
import ReactNativeHapticFeedback from "react-native-haptic-feedback";
const options = {
enableVibrateFallback: true,
ignoreAndroidSystemSettings: false
};
ReactNativeHapticFeedback.trigger("impactMedium", options);
对于您而言,它可以直接与按钮的onPress方法配合使用,例如:
<TouchableOpacity onPress={()=>{ReactNativeHapticFeedback.trigger("impactMedium", options);}} />
注意:我发现最多设备支持的最通用类型是
impactMedium
。
答案 5 :(得分:0)
基于@Nithish合资企业和Giorgos Karyofyllis:
import React from "react"
import { Platform } from "react-native"
import { TouchableNativeFeedback, TouchableOpacity } from "react-native"
export const TouchableFeedback = (props: any) => {
const { children, ...rest } = props;
return Platform.OS === 'android'
? <TouchableNativeFeedback {...rest}>{children}</TouchableNativeFeedback>
: <TouchableOpacity {...rest}>{children}</TouchableOpacity>
}
答案 6 :(得分:0)
做到这一点的最佳优雅方式
import { TouchableNativeFeedback, TouchableOpacity } from 'react-native'
在渲染中
TouchableButton = Platform.OS === 'android' ? TouchableNativeFeedback : TouchableOpacity
return (
<TouchableButton>{'bla bla'}</TouchableButton>
)