Ryan Burnham
Ryan Burnham

Reputation: 593

Does SimpleExoPlayerView have controller visibility changed events?

I'm trying to implement a full screen mode with SimpleExoPlayerView. I've got this mostly working using setSystemUiVisibility.

During onCreate i add a OnSystemUiVisibilityChange listener to sync hiding the player controls with the actionbar.

    @Override
public void onCreate(Bundle savedInstanceState) {

    View decorView = getWindow().getDecorView();
    decorView.setOnSystemUiVisibilityChangeListener
            (onSystemUiChange());

    hideSystemUI();
}

In the OnSystemUiVisibilityChangeListener i'm also setting a timeout that matches the simpleExoplayerViews timeout so the controls and action bar are hidden at the same time.

    @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
    );
}

This works pretty well except in one case. If you tap the screen and then tap it again before the SimpleExoPlayerView controls timeout the SimpleExoPlayerView are hidden but the system ui do not get set until the timeout. Is there any events i can hook into instead?

I've tried setting a onClick and onTouch listener for my root layout but these events are not fired, i suspect SimpleExoPlayerView might be swallowing them?

Upvotes: 5

Views: 7296

Answers (4)

Babar Shamsi
Babar Shamsi

Reputation: 93

There are two classes we have 1. PlayerView 2. StyledPlayerView. I am answering here for StyledPlayerView since PlayerView is deprecated now.

First create a class which extends StyledPlayerView and also your Class do implement this interface class CustomPlayerView extends StyledPlayerView implements StyledPlayerView.ControllerVisibilityListener So you need to override onVisibilityChanged Method:

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

Now you can call this method on some other class where all your playerView methods present binding.playerView.setControllerVisibilityListener(customPlayerView)

So on Visibility change of your controls you will get callbacks.

Upvotes: 0

Kaaveh Mohamedi
Kaaveh Mohamedi

Reputation: 1795

With Exoplayer 2.16.1 you can use setControllerVisibilityListener like this:

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

Upvotes: 0

AndroidDev
AndroidDev

Reputation: 1625

ExoPlayer 2.10.4 has it.

exoplayer PlayerView has a method called

public void setControllerVisibilityListener(PlayerControlView.VisibilityListener listener) {
}

Upvotes: 9

Tamás Szincsák
Tamás Szincsák

Reputation: 1031

As of 2.6.1, SimpleExoPlayerView doesn't seem to have any visibility change listeners for the controls, but PlaybackControlView has. However, it's stored in a private field in SimpleExoPlayerView and there's no builtin way to a access it. To set your own listener, you'll either have to:

  • copy SimpleExoPlayerView.java to your project and make the required changes,
  • use reflection (don't forget to add proguard rules, if needed),
  • override exo_simple_player_view.xml and make sure it contains a PlaybackControlView, then find it using findViewById,
  • find it manually by traversing the view hierarchy.

In my opinion, the first and third options are the nicest, but the last one requires the least amount of changes, and it also works very well. Here is an example:

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;
    }
}

Upvotes: 1

Related Questions