Giving touch feedback

The React Native examples you've worked with so far in this book have used plain text to act as buttons or links. In web applications, it's pretty easy to make text look like something that can be clicked—you just wrap it with the appropriate link. There's no such thing as mobile links, so you can style your text to look like a button.

Note

The problem with trying to style text as links on mobile devices is that they're too hard to press. Buttons provide a bigger target for my fat fingers, and they're easier to give apply touch feedback on.

So, let's style some text as a button. This is a great first step, making the text look touchable. But, we also want to give visual feedback to the user when they start interacting with the button. React Native provides two components to help with this: TouchableOpacity and TouchableHighlight. But before we dive into the code, let's take a look at what these components look like visually when users interact with them, starting with TouchableOpacity:

Giving touch feedback

There's two buttons rendered here, and the top one labeled Opacity is currently being pressed by the user. The opacity of the button is dimmed when pressed, which provides important visual feedback for the user. Let's see what the Highlight button looks like when pressed:

Giving touch feedback

Instead of changing the opacity when pressed, the TouchableHighlight component adds a highlight layer over the button. In this case, we're highlighting it using a more transparent version of the slate grey used in the font and border colors.

Which approach you use doesn't really matter. The important thing is that you provide the appropriate touch feedback for your users as they interact with your buttons. In fact, you might want to use the two approaches in the same app, but for different things. Let's create a Button component makes it easy to use either approach:

import React, { PropTypes } from 'react'; 
import { 
  Text, 
  TouchableOpacity, 
  TouchableHighlight, 
} from 'react-native'; 
 
import styles from './styles'; 
 
// The "touchables" map is used to get the right 
// component to wrap around the button. The 
// "undefined" key represents the default. 
const touchables = new Map([ 
  ['opacity', TouchableOpacity], 
  ['highlight', TouchableHighlight], 
  [undefined, TouchableOpacity], 
]); 
 
const Button = ({ 
  label, 
  onPress, 
  touchable, 
}) => { 
  // Get's the "Touchable" component to use, 
  // based on the "touchable" property value. 
  const Touchable = touchables.get(touchable); 
 
  // Properties to pass to the "Touchable" 
  // component. 
  const touchableProps = { 
    style: styles.button, 
    underlayColor: 'rgba(112,128,144,0.3)', 
    onPress, 
 
  }; 
 
  // Renders the "<Text>" component that's 
  // styled to look like a button, and is 
  // wrapped in a "<Touchable>" component 
  // to properly handle user interactions. 
  return ( 
    <Touchable {...touchableProps}> 
      <Text style={styles.buttonText}> 
        {label} 
      </Text> 
    </Touchable> 
  ); 
}; 
 
Button.propTypes = { 
  onPress: PropTypes.func.isRequired, 
  label: PropTypes.string.isRequired, 
  touchable: PropTypes.oneOf([ 
    'opacity', 
    'highlight', 
  ]), 
}; 
 
export default Button; 

As you can see, the touchables map is used to determine which React Native touchable component wraps the text, based on the touchable property value. Here's the styles used to create this button:

button: { 
  padding: 10, 
  margin: 5, 
  backgroundColor: 'azure', 
  borderWidth: 1, 
  borderRadius: 4, 
  borderColor: 'slategrey', 
}, 
 
buttonText: { 
  color: 'slategrey', 
} 

Here's how we put those buttons to use in the main app module:

import React from 'react'; 
import { 
  AppRegistry, 
  View, 
} from 'react-native'; 
 
import styles from './styles'; 
import Button from './Button'; 
 
const TouchFeedback = () => ( 
  <View style={styles.container}> 
    { /* Renders a "<Button>" that uses 
         "TouchableOpacity" to handle user 
         gestures, since that is the default */ } 
    <Button 
      onPress={() => {}} 
      label="Opacity" 
    /> 
 
    { /* Renders a "<Button>" that uses 
         "TouchableHighlight" to handle 
         user gestures. */ } 
    <Button 
      onPress={() => {}} 
      label="Highlight" 
      touchable="highlight" 
    /> 
  </View> 
); 
 
AppRegistry.registerComponent( 
  'TouchFeedback', 
  () => TouchFeedback 
); 

Note that the onPress callbacks don't actually do anything, but they are called, and we're passing them because they're a required property.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.85.76