Search code examples
androidandroid-tvleanback

Leanback for Android TV : Unsetting Video Title Increases Spacing between Rows


The PlaybackOverlayFragment of the sample app uses the PlaybackControlsGlue to set up playback controls based on the data model. This is the look when using the standard glue: enter image description here

My problem is that I don't want the title/subtitle text to appear above the main player controls bar - we want them at the top left of the player screen instead. Therefore, to disable the showing of title/subtitle, I override createControlsRowAndPresenter() of the glue and use the empty-args constructor of PlaybackControlsRowPresenter instead:

@Override
public PlaybackControlsRowPresenter createControlsRowAndPresenter() {
    PlaybackControlsRow controlsRow = new PlaybackControlsRow(this);
    setControlsRow(controlsRow);
    final View.OnKeyListener onKeyListener = this;
    PlaybackControlsRowPresenter presenter = new PlaybackControlsRowPresenter() { // no AbstractDetailsDescriptionPresenter argument
        @Override
        protected void onBindRowViewHolder(RowPresenter.ViewHolder vh, Object item) {
            super.onBindRowViewHolder(vh, item);
            vh.setOnKeyListener(onKeyListener);
        }
        @Override
        protected void onUnbindRowViewHolder(RowPresenter.ViewHolder vh) {
            super.onUnbindRowViewHolder(vh);
            vh.setOnKeyListener(null);
        }
    };

    // secondaryActionsAdapter setup not shown
    presenter.setOnActionClickedListener(new OnActionClickedListener() {
        @Override
        public void onActionClicked(Action action) {
            dispatchAction(action);
        }
    });

    return presenter;
}

The result? No title/subtitle show as expected but now there's more spacing between the primary controls bar and other rows: almost double spacing when title is not set

What could I be doing wrong, or is it a bug with the leanback library?


Solution

  • Turns out the playback controls need some view above it so they don't occupy the top of their container view (@Nick is right). But I wanted to share my solution in case anyone has a similar need.

    PlaybackControlsRowPresenter can take in any presenter in its constructor, not just AbstractDetailsDescriptionPresenters. So createControlsRowAndPresenter() should look like this:

    EmojiRowPresenter emojiRowPresenter = new EmojiRowPresenter() {
                @Override
                protected void onBindEmojiInfo(EmojiRowView rowView, EmojiInfo emojiInfo) {
                    rowView.setEmojiInfo(emojiInfo);
                }
            };
    PlaybackControlsRowPresenter presenter = new PlaybackControlsRowPresenter(emojiRowPresenter) { // replace the default description presenter with custom presenter
    ... 
    }
    
    // everything else stays as before
    

    and EmojiRowPresenter is a subclass of Presenter that looks like this:

    public abstract class EmojiRowPresenter extends Presenter {
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent) {
            EmojiRowView emojiRowView = new EmojiRowView(parent.getContext());
            emojiRowView.setFocusable(true);
            emojiRowView.setFocusableInTouchMode(true);
            return new ViewHolder(emojiRowView);
        }
    
        @Override
        public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
            EmojiRowView emojiRowView = (EmojiRowView) viewHolder.view;
            PlaybackControlHelper glue = (PlaybackControlHelper) item;
            EmojiInfo emojiInfo = glue.getEmojiInfo();
            if (emojiInfo != null) {
                onBindEmojiInfo(emojiRowView, emojiInfo);
            }
        }
    
        @Override
        public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
            // ...
        }
    
        protected abstract void onBindEmojiInfo(EmojiRowView rowView, EmojiInfo emojiInfo);
    }
    

    Of course, EmojiRowView creates the view from the layout that defines each item. Here's the end result:

    enter image description here