kip2 kip2 - 5 months ago 25
Android Question

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?

Answer

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() { // no AbstractDetailsDescriptionPresenter argument
... 
}

// 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

Comments