6

I'm using the Button component from React Native and I need to change the color of the button when the button is focused with a TV remote (Amazon Fire Stick). I don't see any focus listeners available for the button. Is there anyway to achieve this functionality? Here is my code:

<Button disabled={props.loading} styles={styles.button} title="1" onPress={() => {props.addNumber(1)}}/>

I looked at the TouchableHighlight component but it won't work because I need the color to change when the user has focused on the button before the button is clicked. By default, the opacity change is so small that it's hard to tell the button is currently focused.

6
  • TouchableWithoutFeedback has a onFocus listener Commented Oct 17, 2021 at 22:33
  • @diedu I was really hoping this would work but I was unable to even select the element that was wrapped in TouchableWithoutFeedback via the TV remote. In the emulator, I can use the mouse to click the button however. Commented Oct 17, 2021 at 23:34
  • try passing focusable={true} Commented Oct 18, 2021 at 1:33
  • @diedu That didn't work :( Commented Oct 18, 2021 at 1:50
  • you mention you tried TouchableHighlight but I didn't understand very well what you mean with opacity change is too small, does it mean that TouchableHighlight does show the change you want but is not enough? because I see it has an activeopacity prop that you could set to 1 and set the color with underlaycolor Commented Oct 18, 2021 at 2:26

4 Answers 4

3

you can have onFocus prop in TouchableOpacity or TouchableHighlight, but in order to work it on TV you need to import it from the specific package as mentioned here. as mentioned there you need to move from react-native to react-native-tvos. All TV-related stuff has been moved to that package. It tracks react-native but with additional TV support. It won't be coming back to react-native core package.

read this

Sign up to request clarification or add additional context in comments.

Comments

1

from react-native docs :

When running on Android TV the Android framework will automatically apply a directional navigation scheme based on the relative position of focusable elements in your views. The Touchable mixin has code added to detect focus changes and use existing methods to style the components properly and initiate the proper actions when the view is selected using the TV remote, so TouchableWithoutFeedback, TouchableHighlight, TouchableOpacity, and TouchableNativeFeedback will work as expected. In particular:

onFocus will be executed when the touchable view goes into focus
onBlur will be executed when the touchable view goes out of focus
onPress will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.

so adding onfocus on TouchableOpacity should work for you the reason it is not you need some changes in AndroidManifest.xml to activate android tv mode

  <!-- Add custom banner image to display as Android TV launcher icon -->
 <application
  ...
  android:banner="@drawable/tv_banner"
  >
    ...
    <intent-filter>
      ...
      <!-- Needed to properly create a launch intent when running on Android TV -->
      <category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
    </intent-filter>
    ...
  </application>

also, you can use tvParallaxProperties and hasTVPreferredFocus to show the initial focus but it has limited effects

    <TouchableHighlight
      hasTVPreferredFocus
      tvParallaxProperties={{ magnification: 1.2 }}
    >
      <Text>Button</Text>
    </TouchableHighlight>

https://reactnative.dev/docs/touchableopacity#tvparallaxproperties-android

Comments

1

Replace it for:

      state = {
        buttonStyle: styles.button,
        [...]
      }
      [...]

      <TouchableWithoutFeedback disabled={props.loading} styles={this.state.buttonStyle} 
      onPress={() => {props.addNumber(1)}} 
      onFocus={() => {this.setState({buttonStyle: styles.focusedButton})}} >
          <Text>1</Text>
      </TouchableWithoutFeedback >

If you have all buttons in the same component, you will need to use the state value as array or object and define the key or index to access to the specific one.

https://reactnative.dev/docs/touchablewithoutfeedback#onfocus

3 Comments

TouchableHighlight doesn’t have an onFocus listener though. I tried this also.
Sorry I wanted to say TouchableWithoutFeedback
I did try this but I was unable to focus on the TouchableWithoutFeedback element via the Fire Stick remote.
0

You can use the Pressable component, here's how you can do it:

<Pressable
  onPress={onPressFunction}
  style={({ focused }) => ({ backgroundColor: focused ? 'red' : 'blue' })}
>
  <Text>I'm pressable!</Text>
</Pressable>

You can read more about it in the docs

1 Comment

Focus isn't mentioned in style prop anymore.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.