fix: use TouchableHighlight on Android < Lollipop (#115)

Earlier, older Android versions used a ugly blue highlight for touchable items. This commit changes it to a `TouchableHighlight`, which uses the appropriate highlight color. Merged it with the iOS version for now since they have the same behaviour.
This commit is contained in:
Satyajit Sahoo
2017-07-04 16:34:20 +05:30
committed by Ahmed Elhanafy
parent 07d52d49eb
commit c3dba49d8a
4 changed files with 95 additions and 146 deletions

View File

@@ -0,0 +1,95 @@
/* @flow */
import React, { Children, PureComponent } from 'react';
import PropTypes from 'prop-types';
import {
TouchableNativeFeedback,
TouchableHighlight,
Platform,
View,
} from 'react-native';
import color from 'color';
const ANDROID_VERSION_LOLLIPOP = 21;
type Props = {
borderless: boolean,
background?: Object,
onPress?: ?Function,
rippleColor: string,
underlayColor?: string,
children?: any,
style?: any,
};
type DefaultProps = {
borderless: boolean,
rippleColor: string,
};
export default class TouchableItem extends PureComponent<
DefaultProps,
Props,
void
> {
static propTypes = {
borderless: PropTypes.bool,
background: PropTypes.object,
onPress: PropTypes.func,
rippleColor: PropTypes.string,
underlayColor: PropTypes.string,
children: PropTypes.element.isRequired,
style: View.propTypes.style,
};
static defaultProps = {
borderless: false,
rippleColor: 'rgba(0, 0, 0, .32)',
};
render() {
const {
style,
background,
borderless,
rippleColor,
underlayColor,
children,
...rest
} = this.props;
if (
Platform.OS === 'android' &&
Platform.Version >= ANDROID_VERSION_LOLLIPOP
) {
return (
<TouchableNativeFeedback
{...rest}
background={
background != null
? background
: TouchableNativeFeedback.Ripple(rippleColor, borderless)
}
>
<View style={style}>
{Children.only(children)}
</View>
</TouchableNativeFeedback>
);
}
return (
<TouchableHighlight
{...rest}
style={style}
underlayColor={
underlayColor != null
? underlayColor
: color(rippleColor).clearer(0.5).rgbaString()
}
>
{Children.only(children)}
</TouchableHighlight>
);
}
}

View File

@@ -1,74 +0,0 @@
/* @flow */
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { TouchableNativeFeedback, View, Platform } from 'react-native';
type Props = {
borderless: boolean,
delayPressIn?: number,
onPress?: ?Function,
onPressIn?: ?Function,
onPressOut?: ?Function,
rippleColor: string,
children?: any,
style?: any,
};
type DefaultProps = {
borderless: boolean,
rippleColor: string,
};
export default class TouchableRipple extends PureComponent<
DefaultProps,
Props,
void
> {
static propTypes = {
children: PropTypes.element.isRequired,
borderless: PropTypes.bool,
delayPressIn: PropTypes.number,
onPress: PropTypes.func,
onPressIn: PropTypes.func,
onPressOut: PropTypes.func,
rippleColor: PropTypes.string,
style: View.propTypes.style,
};
static defaultProps = {
borderless: false,
rippleColor: 'rgba(0, 0, 0, .32)',
};
render() {
const {
children,
delayPressIn,
onPress,
onPressIn,
onPressOut,
rippleColor,
borderless,
style,
} = this.props;
return (
<TouchableNativeFeedback
delayPressIn={delayPressIn}
onPress={onPress}
onPressIn={onPressIn}
onPressOut={onPressOut}
background={
Platform.Version >= 21
? TouchableNativeFeedback.Ripple(rippleColor, borderless)
: TouchableNativeFeedback.SelectableBackground()
}
>
<View style={style}>
{children}
</View>
</TouchableNativeFeedback>
);
}
}

View File

@@ -1,69 +0,0 @@
/* @flow */
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { TouchableHighlight, View } from 'react-native';
import color from 'color';
type Props = {
borderless: boolean,
delayPressIn?: number,
onPress?: ?Function,
onPressIn?: ?Function,
onPressOut?: ?Function,
rippleColor: string,
children?: any,
style?: any,
};
type DefaultProps = {
borderless: boolean,
rippleColor: string,
};
export default class TouchableRipple extends PureComponent<
DefaultProps,
Props,
void
> {
static propTypes = {
borderless: PropTypes.bool,
delayPressIn: PropTypes.number,
onPress: PropTypes.func,
onPressIn: PropTypes.func,
onPressOut: PropTypes.func,
rippleColor: PropTypes.string,
children: PropTypes.element.isRequired,
style: View.propTypes.style,
};
static defaultProps = {
borderless: false,
rippleColor: 'rgba(0, 0, 0, .32)',
};
render() {
const {
children,
delayPressIn,
onPress,
onPressIn,
onPressOut,
rippleColor,
style,
} = this.props;
return (
<TouchableHighlight
style={style}
underlayColor={color(rippleColor).clearer(0.5).rgbaString()}
delayPressIn={delayPressIn}
onPress={onPress}
onPressIn={onPressIn}
onPressOut={onPressOut}
>
{children}
</TouchableHighlight>
);
}
}

View File

@@ -1,3 +0,0 @@
/* @flow */
export { default } from './TouchableRipple';