【问题标题】:How do I layout my React Native Fire TV SubtitleView correctly?如何正确布局我的 React Native Fire TV SubtitleView?
【发布时间】:2023-03-31 01:08:02
【问题描述】:

我正在使用他们的 Android SDK 开发 Bitmovin 播放器的 React Native 实现。在这个阶段,我不确定这对 Bitmovin 播放器有多具体,但由于他们现阶段不正式支持 React Native,所以我想先在 SO 上询问这个问题。这是一个带有自定义视图的 React Native UI 组件,使用布局文件。我试图在播放器视图之上呈现一个字幕视图,并且我的布局基于 Bitmovin 的简单示例。事实上,我已经进一步简化了布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">

    <com.bitmovin.player.PlayerView
        android:id="@+id/bitmovinPlayerView"
        app:shutter_background_color="@android:color/transparent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/bootsplash_background">

        <com.bitmovin.player.SubtitleView
            android:id="@+id/bitmovinSubtitleView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:foregroundGravity="center" />

    </com.bitmovin.player.PlayerView>
</LinearLayout>

这会在屏幕顶部显示 SubtitleView。到目前为止,我没有尝试过在屏幕底部以更常见的位置呈现 SubtitleView。据我所知,我已经对所有这些元素的每一个参数进行了试验。下面是初始化视图的代码:

 public void init() {
    inflate(context, R.layout.player_container, this);

    StyleConfig styleConfig = new StyleConfig();
    styleConfig.setUiEnabled(false);

    PlayerConfig playerConfig = new PlayerConfig();
    playerConfig.setStyleConfig(styleConfig);

    playerView = findViewById(R.id.bitmovinPlayerView);
    player = Player.create(context, playerConfig);

    playerView.setPlayer(player);

    player.on(SourceEvent.Loaded.class, this::onLoad);
    player.on(PlayerEvent.Playing.class, this::onPlay);
    player.on(PlayerEvent.Paused.class, this::onPause);
    player.on(PlayerEvent.Seek.class, this::onSeek);
    player.on(PlayerEvent.TimeChanged.class, this::onTimeChanged);
    player.on(PlayerEvent.Destroy.class, this::onDestroy);
    player.on(PlayerEvent.Seeked.class, this::onSeeked);
    player.on(PlayerEvent.PlaybackFinished.class, this::onPlaybackFinished);
    player.on(PlayerEvent.Ready.class, this::onReady);
    player.on(SourceEvent.Error.class, this::onError);
    player.on(SourceEvent.SubtitleChanged.class, this::onSubtitleChanged);
    player.on(PlayerEvent.Error.class, this::onError);


    subtitleView = findViewById(R.id.bitmovinSubtitleView);
    subtitleView.setPlayer(player);

    player.setVolume(100);
}

我读过 React Native 为 UI 组件的顶级视图设置样式,所以这是我现阶段唯一的线索。不过,我不确定如何回复该信息...

编辑:问题可能是在 React Native 中动态更新 Android 中的视图布局并不简单。这已在here 进行了详细讨论。

编辑 2:我尝试监听全局布局更改,这是针对视图布局问题提出的解决方法之一:

        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            requestLayout();
        }
    });

这按预期调用了,但是对subtitleView没有影响,它仍然显示在播放器的顶部,这似乎是因为它的高度为0。

编辑 3:另一个对我不起作用的建议解决方案:

    private void setupLayoutHack() {

        Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
            @Override
            public void doFrame(long frameTimeNanos) {
                manuallyLayoutChildren();
                getViewTreeObserver().dispatchOnGlobalLayout();
                Choreographer.getInstance().postFrameCallback(this);
            }
        });
    }

    private void manuallyLayoutChildren() {
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
            child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
        }
    }

我在构造函数中调用了 setupLayoutHack() 但在应用这些更改后也没有发现任何区别:(

编辑 4:我修复 SubtitleView 布局的最后一次尝试是尝试以各种方式测量和布局:

    private void refreshViewChildrenLayout(View view){
        view.measure(
                View.MeasureSpec.makeMeasureSpec(view.getMeasuredWidth(), View.MeasureSpec.EXACTLY),
                View.MeasureSpec.makeMeasureSpec(view.getMeasuredHeight(), View.MeasureSpec.EXACTLY));
        view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
    }

但是,在我尝试的所有情况下,高度都是 0,这意味着没有任何改变。上述 RN 问题中提到了一个解决方案,建议应该覆盖字幕视图的阴影节点。因此,一种前进的方式可能是构建一个包含该内容的新字幕视图。

然而,在这个阶段,在我看来,在 React Native 中响应字幕提示并在那里执行所有显示和样式设置是一种更简单的方法。

(还有一个较小的问题是如何使文本两侧的背景透明,但在这个阶段布局问题要重要得多)。

【问题讨论】:

  • 您有机会分享与此屏幕相关的代码和依赖项吗?还有关于目标的更多信息(哪个版本的 Android 和 Android API)。另外,或者,我建议检查这个非官方的 React Native 包装器:github.com/take0ffmedia/react-native-bitmovin-player。它得到积极维护,适用于 Android 和 iOS。
  • 感谢您的评论!我已经添加了设置代码,但正如你所看到的,它并没有太多内容。我熟悉那个 repo,但在这种情况下它对我没有帮助,因为我们使用的是自定义 ui。实际上,我的代码与此更相似,除了由于 RN 问题导致字幕位置不正确:github.com/bitmovin/bitmovin-player-android-samples/tree/main/…
  • 顺便说一句:该项目在 SDK 28 上。我的 Fire TV Stick 在 Fire OS 7.2.4.2 上,是第 3 代 Fire TV Stick。其他人也看到了同样的问题,不确定他们有哪些版本的 Fire TV。

标签: android react-native bitmovin-player


【解决方案1】:

免责声明:我不太熟悉 React Native 以及它如何影响布局创建。

但是查看您的布局文件,它表明SubtitleViewPlayerView 的顶部子级FrameLayout,因此被添加到顶部(左)。通过在SubtitleView 上指定android:layout_height="wrap_content",它只会占用视图所需的空间。在 Bitmovin 示例中,它是在代码中生成的,因此应该从父级继承属性,父级是 RelativeLayoutandroid:layout_weight="1",这会导致将其高度拉伸到可用空间。

长话短说,尝试将SubtitleView 的高度设置为match_parent

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-18
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 2019-09-20
    • 1970-01-01
    相关资源
    最近更新 更多