SimpleExoPlayerView是否有控制器可见性更改事件?



我正在尝试使用SimpleExoPlayerView实现全屏模式。我主要使用setSystemUiVisibility工作。

在onCreate期间,我添加了一个OnSystemUiVisibilityChange侦听器以将隐藏播放器控件与操作栏同步。

@Override
public void onCreate(Bundle savedInstanceState) {
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
(onSystemUiChange());
hideSystemUI();
}

在OnSystemUiVisibilityChangeListener中,我还设置了一个与simpleExoplayerViews超时相匹配的超时,因此控件和操作栏同时隐藏。

@NonNull
private View.OnSystemUiVisibilityChangeListener onSystemUiChange() {
return new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
mSimpleExoPlayerView.showController();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
//sync the hide system ui with 
//simpleExoPlayerView's auto hide timeout
hideSystemUI();
}
}, mSimpleExoPlayerView.getControllerShowTimeoutMs());
} else {
mSimpleExoPlayerView.hideController();
}
}
};
}
private void hideSystemUI() {
View rootView = findViewById(R.id.root);
rootView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
);
}

除了一种情况外,这很有效。如果您点击屏幕,然后在 SimpleExoPlayer View 控件超时之前再次点击它,则 SimpleExoPlayerView 将被隐藏,但在超时之前不会设置系统 UI。有什么事件可以代替吗?

我尝试为我的根布局设置 onClick 和 onTouch 侦听器,但这些事件没有触发,我怀疑 SimpleExoPlayerView 可能会吞噬它们?

ExoPlayer 2.10.4 有它。

Exoplayer PlayerView有一个名为

public void setControllerVisibilityListener(PlayerControlView.VisibilityListener listener) {
}

从 2.6.1 开始,SimpleExoPlayerView似乎没有任何控件的可见性更改侦听器,但PlaybackControlView有。但是,它存储在SimpleExoPlayerView的私有字段中,并且没有内置的访问方式。要设置自己的侦听器,您必须:

  • 将SimpleExoPlayerView.java复制到您的项目中并进行所需的更改,
  • 使用反射(如果需要,不要忘记添加 ProGuard 规则(,
  • 覆盖exo_simple_player_view.xml并确保它包含PlaybackControlView,然后使用findViewById找到它,
  • 通过遍历视图层次结构手动查找它。

在我看来,第一个和第三个选项是最好的,但最后一个选项需要的更改量最少,而且效果也很好。下面是一个示例:

import com.google.android.exoplayer2.ui.PlaybackControlView;
import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
public SomeActivity extends Activity implements PlaybackControlView.VisibilityListener {
private initExoPlayer() {
// ...
addPlaybackControlVisibilityListener(mSimpleExoPlayerView, this);
}
@Override
public void onVisibilityChange(int visibility) {
// show/hide system ui here
}
private static void addPlaybackControlVisibilityListener(SimpleExoPlayerView playerView, PlaybackControlView.VisibilityListener listener) {
PlaybackControlView playbackControlView = findPlaybackControlView(playerView);
if (playbackControlView != null)
playbackControlView.setVisibilityListener(listener);
}
private static PlaybackControlView findPlaybackControlView(ViewGroup viewGroup) {
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View child = viewGroup.getChildAt(i);
if (child instanceof PlaybackControlView)
return (PlaybackControlView) child;
if (child instanceof ViewGroup) {
PlaybackControlView result = findPlaybackControlView((ViewGroup) child);
if (result != null)
return result;
}
}
return null;
}
}

使用 Exoplayer2.16.1您可以使用这样的setControllerVisibilityListener

viewBinding.playerView.setControllerVisibilityListener { visibility ->
if (visibility == View.VISIBLE) {
// controller is visible
} else {
// controller is not visible
}
}

我们有两个类 1.PlayerView2.StyledPlayerView. 我在这里回答StyledPlayerView,因为PlayerView现在已被弃用。

首先创建一个扩展StyledPlayerView的类,并且您的类确实实现了此接口class CustomPlayerView extends StyledPlayerView implements StyledPlayerView.ControllerVisibilityListener所以你需要覆盖 onVisibilityChanged 方法:

@Override
public void onVisibilityChanged(int visibility) {
isControllerVisible = visibility == View.VISIBLE;
}

现在,您可以在所有playerView方法都存在的其他类上调用此方法binding.playerView.setControllerVisibilityListener(customPlayerView)

因此,在控件的可见性更改中,您将收到回调。

最新更新