as

Settings
Sign out
Notifications
Alexa
Amazon Appstore
AWS
Documentation
Support
Contact Us
My Cases
Get Started
Design and Develop
Publish
Reference
Support

Create Focusable Button

Since we will need to add 2 buttons to the VideoDetailScreen that can be focused, we will create our own button component. This also ensures that we are not duplicating code and the button can be re-used across our App.

Define Button component

  • Create a new file under the components folder called Button.tsx.
  • Import React and useState from 'react'.
  • Import StyleSheet, Text and TouchableOpacity from 'react-native'.
  • Create an arrow function called Button that takes in 2 arguments called pressFunction and buttonText.
  • Destructure each argument in the interface and add :IProps to enforce the type of each argument in the object. The pressFunction will be a Function and the buttonText a string.
  • Below the import statements, create an interface that declares the types of the props.
import React, { useState } from 'react';
import { View, StyleSheet, TouchableOpacity, Text } from 'react-native';

export interface IProps {
  pressFunction: Function;
  buttonText: String;
}

const Button = ({ pressFunction, buttonText }: IProps) => { };
  • Add an empty fragment and inside it add a TouchableOpacity element.

To make the Button pressable we need to give it an onPress().

  • Add the onPress prop to TouchableOpacity and set its value to call the pressFunction
  • Add a Text component inside the TouchableOpacity and set it to take in the value of buttonText.
const Button = ({ pressFunction, buttonText }: IProps) => {

  return (
    <>
      <TouchableOpacity onPress={() => pressFunction()}>
        <Text>{buttonText}</Text>
      </TouchableOpacity>
    </>
  );
};

Next we want to make it obvious to the user that the button has been selected, so let's add onFocus() and onBlur() properties to the TouchableOpacity

  • Import useState from react and initialize it with a state of focused and a function of setFocused.
  • Initialize the value of focused to false.
const Button = ({ pressFunction, buttonText }: IProps) => {
    const [focused, setFocused] = useState(false);
}
  • Add an onFocus prop to the TouchableOpacity, and set it to call the setFocused() function with the value true
  • Add an onBlur prop to the TouchableOpacity, and set it to call the setFocused() function with the value false

Your Button.tsx code should look like this:

Copied to clipboard.

import React, { useState } from 'react';
import { View, StyleSheet, TouchableOpacity, Text } from 'react-native';

export interface IProps {
  pressFunction: Function;
  buttonText: String;
}

const Button = ({ pressFunction, buttonText }: IProps) => {
  const [focus, setFocused] = useState(false);

  return (
    <>
      <TouchableOpacity
        onPress={() => pressFunction()}
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}>
        <Text>{buttonText}</Text>
      </TouchableOpacity>
    </>
  );
};

Add Styling

Now let's add some styling:

  • Create a StyleSheet called styles and add it after the Button function.
  • Add buttonContainer, buttonText and focused styles to the StyleSheet with the following values:

Copied to clipboard.

const styles = StyleSheet.create({
  buttonContainer: {
    backgroundColor: '#FF9900',
    padding: 10,
    width: 150,
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
  },
  buttonText: {
    fontSize: 20,
  },
  focused: {
    borderWidth: 5,
    borderColor: 'yellow',
  },
});

The TouchableOpacity will have a style prop that depends on the value of focused:

  • Give the touchable opacity a style prop of buttonInnerContainer and a conditional style prop of focused
     style={[styles.buttonInnerContainer, focus && styles.focused]}
    
  • Add the buttonOuterContainer style to the View component.

The final Button.tsx code should look like this:

Copied to clipboard.

import React, {useState} from 'react';
import {StyleSheet, TouchableOpacity, Text} from 'react-native';

export interface IProps {
  pressFunction: Function;
  buttonText: String;
}

const Button = ({pressFunction, buttonText}: IProps) => {
  const [focus, setFocused] = useState(false);

  return (
    <>
      <TouchableOpacity
        style={[styles.buttonContainer, focus && styles.focused]}
        onPress={() => pressFunction()}
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}>
        <Text style={styles.buttonText}>{buttonText}</Text>
      </TouchableOpacity>
    </>
  );
};

const styles = StyleSheet.create({
  buttonContainer: {
    backgroundColor: '#FF9900',
    padding: 10,
    width: 150,
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
  },
  focused: {
    borderWidth: 3,
    borderColor: 'yellow',
    opacity: 0.8,
  },
  buttonText: {
    fontSize: 20,
  },
});

export default Button;