React Native Android TV中TouchableHighlight的onFocus不生效问题求助
Hey there, sorry to hear you're stuck with onFocus not firing on your Android TV app—this can be tricky, but let's walk through some actionable fixes that usually resolve this issue:
1. Confirm Expo is properly configured for TV
First, make sure your app.json explicitly enables TV support. Expo requires specific settings to activate Android TV-focused features:
{ "expo": { "name": "YourTVApp", "tv": true, // Critical flag for TV support "android": { "package": "com.yourcompany.tvpapp", "intentFilters": [ { "action": "android.intent.action.MAIN", "category": [ "android.intent.category.LEANBACK_LAUNCHER" // Required for TV launcher visibility ] } ] } } }
Without these settings, Expo won't enable the TV-specific focus handling layer.
2. Ensure your Touchable has clear, focusable bounds
Looking at your code, the TouchableHighlight wraps a fixed-size Text component but doesn't have explicit dimensions itself. On Android TV, focus is determined by a view's visible bounds—if the Touchable's size isn't properly defined, it might not be recognized as a focusable target. Try adding explicit width/height to the Touchable:
<TouchableHighlight style={{ backgroundColor: 'green', backfaceVisibility: 'visible', shadowColor: 'red', width: 50, // Match the Text component's width height: 50 // Match the Text component's height }} hasTVPreferredFocus tvParallaxProperties={{ magnification: 1.2 }} onPress={() => console.log('press')} onFocus={() => console.log('focus')} > <Text style={{ backgroundColor: 'transparent' }}>1</Text> </TouchableHighlight>
This gives the Touchable a clear, targetable area for the TV remote.
3. Rule out conflicting props or parent view issues
- Temporarily remove
hasTVPreferredFocus—this prop can sometimes override default focus behavior if the component isn't correctly registered as a preferred focus target. - Check parent views for
pointerEvents="none"orfocusable={false}—these properties block focus from reaching child components. - Ensure no other focusable elements in the hierarchy are stealing focus before your Touchable gets it.
4. Use react-native-tvos's FocusManager for debugging
Since you migrated to react-native-tvos, leverage the FocusManager to track focus changes and confirm if your component is ever targeted:
import { FocusManager } from 'react-native'; import { useEffect } from 'react'; // Add this in your component's useEffect hook useEffect(() => { const focusSubscription = FocusManager.addListener('focusChange', (event) => { console.log('Focus shifted to component:', event.target); }); return () => focusSubscription.remove(); }, []);
This log will tell you exactly which component is receiving focus, helping you isolate if the issue is with your Touchable or the app's focus flow.
5. Verify Expo and react-native-tvos compatibility
Make sure your Expo SDK version aligns with the react-native-tvos version you're using. Expo's TV support is tied to specific SDK releases—mismatched versions can break focus handling. If you're on an older Expo SDK, upgrading to a compatible version might resolve underlying bugs.
6. Test with a minimal isolated component
Create a stripped-down test screen to rule out interference from other parts of your app (like navigation libraries or custom components):
import React from 'react'; import { View, TouchableHighlight, Text } from 'react-native'; export default function TestFocusScreen() { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <TouchableHighlight style={{ width: 100, height: 100, backgroundColor: 'blue' }} onFocus={() => console.log('Test focus fired!')} onPress={() => console.log('Test press fired!')} > <Text style={{ color: 'white', fontSize: 24 }}>Test</Text> </TouchableHighlight> </View> ); }
If this works, the issue is likely in your main app's hierarchy or other components.
7. Check TV system settings
Sometimes TV accessibility features or input modes can interfere with focus. Temporarily disable features like "TalkBack" and ensure the TV is set to use a remote control (not touch input) to rule out system-level conflicts.
After trying these steps, your onFocus events should start firing. Let me know if you need further debugging help!
内容的提问来源于stack exchange,提问作者Arekjaar

