Skip to main content

电视设备构建

实现电视设备支持的目的是使现有的 React Native 应用可以在 Apple TV 和 Android TV 上运行,而应用的 JavaScript 代码只需很少或无需更改。

¥TV devices support has been implemented with the intention of making existing React Native applications work on Apple TV and Android TV, with few or no changes needed in the JavaScript code for the applications.

已弃用。电视支持已移至 React Native for TV 存储库。

¥Deprecated. TV support has moved to the React Native for TV repository.

构建变更

¥Build changes

  • 原生层:要在 Android TV 上运行 React Native 项目,请确保对 AndroidManifest.xml 进行以下更改

    ¥Native layer: To run React Native project on Android TV make sure to make the following changes to AndroidManifest.xml

  <!-- 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>
  • JavaScript 层:Platform.android.js 中添加了对 Android TV 的支持。你可以通过执行以下操作来检查代码是否在 Android TV 上运行

    ¥JavaScript layer: Support for Android TV has been added to Platform.android.js. You can check whether code is running on Android TV by doing

const Platform = require('Platform');
const running_on_android_tv = Platform.isTV;

代码变更

¥Code changes

  • 访问可触摸控件:在 Android TV 上运行时,Android 框架将根据视图中可聚焦元素的相对位置自动应用定向导航方案。Touchable mixin 添加了代码来检测焦点变化,并使用现有方法正确设置组件样式,并在使用电视遥控器选择视图时启动适当的操作,因此 TouchableWithoutFeedbackTouchableHighlightTouchableOpacityTouchableNativeFeedback 将按预期工作。尤其:

    ¥Access to touchable controls: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on 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

      ¥onFocus will be executed when the touchable view goes into focus

    • 当可触摸视图失去焦点时将执行 onBlur

      ¥onBlur will be executed when the touchable view goes out of focus

    • 当按下电视遥控器上的 "select" 按钮实际选择可触摸视图时,将执行 onPress

      ¥onPress will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.

  • 电视遥控器/键盘输入:新的原生类 ReactAndroidTVRootViewHelper 为电视远程事件设置关键事件处理程序。当电视远程事件发生时,此类会触发 JS 事件。该事件将被 TVEventHandler JavaScript 对象的实例拾取。需要实现电视远程事件自定义处理的应用代码可以创建 TVEventHandler 的实例并监听这些事件,如以下代码所示:

    ¥TV remote/keyboard input: A new native class, ReactAndroidTVRootViewHelper, sets up key events handlers for TV remote events. When TV remote events occur, this class fires a JS event. This event will be picked up by instances of the TVEventHandler JavaScript object. Application code that needs to implement custom handling of TV remote events can create an instance of TVEventHandler and listen for these events, as in the following code:

const TVEventHandler = require('TVEventHandler');

class Game2048 extends React.Component {
_tvEventHandler: any;

_enableTVEventHandler() {
this._tvEventHandler = new TVEventHandler();
this._tvEventHandler.enable(this, function (cmp, evt) {
if (evt && evt.eventType === 'right') {
cmp.setState({board: cmp.state.board.move(2)});
} else if (evt && evt.eventType === 'up') {
cmp.setState({board: cmp.state.board.move(1)});
} else if (evt && evt.eventType === 'left') {
cmp.setState({board: cmp.state.board.move(0)});
} else if (evt && evt.eventType === 'down') {
cmp.setState({board: cmp.state.board.move(3)});
} else if (evt && evt.eventType === 'playPause') {
cmp.restartGame();
}
});
}

_disableTVEventHandler() {
if (this._tvEventHandler) {
this._tvEventHandler.disable();
delete this._tvEventHandler;
}
}

componentDidMount() {
this._enableTVEventHandler();
}

componentWillUnmount() {
this._disableTVEventHandler();
}
}
  • 开发菜单支持:在模拟器上,cmd-M 将调出开发菜单,类似于 Android。要在真正的 Android TV 设备上启动它,请按菜单按钮或长按遥控器上的快进按钮。(请不要摇晃 Android TV 设备,否则将无法工作:))

    ¥Dev Menu support: On the emulator, cmd-M will bring up the Dev Menu, similar to Android. To bring it up on a real Android TV device, press the menu button or long press the fast-forward button on the remote. (Please do not shake the Android TV device, that will not work :) )

  • 已知的问题:

    ¥Known issues:

    • TextInput 组件目前无法工作(即它们无法自动接收焦点,请参阅 这条评论)。

      ¥TextInput components do not work for now (i.e. they cannot receive focus automatically, see this comment).

      • 然而,可以使用参考来手动触发 inputRef.current.focus()

        ¥It is however possible to use a ref to manually trigger inputRef.current.focus().

      • 你可以将输入封装在 TouchableWithoutFeedback 组件内,并在该可触摸组件的 onFocus 事件中触发焦点。这使得可以通过箭头键打开键盘。

        ¥You can wrap your input inside a TouchableWithoutFeedback component and trigger focus in the onFocus event of that touchable. This enables opening the keyboard via the arrow keys.

      • 每次按键后键盘可能会重置其状态(这可能仅发生在 Android TV 模拟器内)。

        ¥The keyboard might reset its state after each keypress (this might only happen inside the Android TV emulator).

    • Modal 组件内容无法获得焦点,具体参见 这个问题

      ¥The content of Modal components cannot receive focus, see this issue for details.