Android TV: This is not the idiot box you are looking for
Do you wonder what Android TV is and how could you make the most out of it? Take a look at the features it has to offer and how to build a great user experience with Android TV. Talk given at Droidcon Madrid 2015.
“Designers are also nice people*” Sebastiano Poggi Android Developer @Novoda This is not the idiot box you are looking for *allegedly Dave Clements Head of Design @Novoda
There is no touchable screen android:name="android.software.leanback" android:required="false" /> android:name="android.hardware.touchscreen" android:required="false" />
There is no touchable screen android:focusable="true" android:focusableInTouchMode="true" android:nextFocusDown="@+id/view1" android:nextFocusUp="@+id/view2" />
There is no touchable screen android:focusable="true" android:focusableInTouchMode="true" android:nextFocusDown="@+id/view1" android:nextFocusUp="@+id/view2" />
Customising the BrowseFragment public class MainFragment extends BrowseFragment setBadgeDrawable(getDrawable(R.drawable.videos_by_google_banner)); setTitle(getString(R.string.browse_title));
Presenting data mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); CardPresenter cardPresenter = new CardPresenter(); for (Map.Entry> entry : data.entrySet()) { ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter); List list = entry.getValue();
Presenting data mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); CardPresenter cardPresenter = new CardPresenter(); for (Map.Entry> entry : data.entrySet()) { ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter); List list = entry.getValue();
Presenting data mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); CardPresenter cardPresenter = new CardPresenter(); for (Map.Entry> entry : data.entrySet()) { ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter); List list = entry.getValue();
Presenting details /* * LeanbackDetailsFragment extends DetailsFragment, a Wrapper fragment for leanback details screens. * It shows a detailed view of video and its meta plus related videos. */ public class MovieDetailsFragment extends android.support.v17.leanback.app.DetailsFragment {
Playing a video in the background /* * Class for video playback with media control */ public class PlayFragment extends android.support.v17.leanback.app.PlaybackOverlayFragment
Playing a video in the background PlaybackControlsRowPresenter playbackControlsRowPresenter; playbackControlsRowPresenter = new PlaybackControlsRowPresenter( new DescriptionPresenter()); ps.addClassPresenter(PlaybackControlsRow.class, playbackControlsRowPresenter); mRowsAdapter = new ArrayObjectAdapter(ps); setAdapter(mRowsAdapter); static class DescriptionPresenter extends AbstractDetailsDescriptionPresenter { @Override protected void onBindDescription(ViewHolder viewHolder, Object item) { viewHolder.getTitle().setText(((Movie) item).getTitle()); viewHolder.getSubtitle().setText(((Movie) item).getStudio()); } }
Playing a video in the background PlaybackControlsRowPresenter playbackControlsRowPresenter; playbackControlsRowPresenter = new PlaybackControlsRowPresenter( new DescriptionPresenter()); ps.addClassPresenter(PlaybackControlsRow.class, playbackControlsRowPresenter); mRowsAdapter = new ArrayObjectAdapter(ps); setAdapter(mRowsAdapter); static class DescriptionPresenter extends AbstractDetailsDescriptionPresenter { @Override protected void onBindDescription(ViewHolder viewHolder, Object item) { viewHolder.getTitle().setText(((Movie) item).getTitle()); viewHolder.getSubtitle().setText(((Movie) item).getStudio()); } }
Setup the Media Session mSession = new MediaSession (this, "MyApp"); mSession.setCallback(new MediaSessionCallback()); mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); if (!mSession.isActive()) { mSession.setActive(true); }
Use the Media Session private void updatePlaybackState() { long position = PlaybackState.PLAYBACK_POSITION_UNKNOWN; position = mMediaPlayer.getCurrentPosition();
Setup the player and start player = ExoPlayer.Factory.newInstance(RENDERER_COUNT, 1000, 5000); player.addListener(this); player.prepare(videoRenderer, audioRenderer); Surface surface = surfaceView.getHolder().getSurface(); player.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); playerControl = new PlayerControl(player); playerControl.start();
Setup the player and start player = ExoPlayer.Factory.newInstance(RENDERER_COUNT, 1000, 5000); player.addListener(this); player.prepare(videoRenderer, audioRenderer); Surface surface = surfaceView.getHolder().getSurface(); player.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); playerControl = new PlayerControl(player); playerControl.start();
Setup the player and start player = ExoPlayer.Factory.newInstance(RENDERER_COUNT, 1000, 5000); player.addListener(this); player.prepare(videoRenderer, audioRenderer); Surface surface = surfaceView.getHolder().getSurface(); player.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); playerControl = new PlayerControl(player); playerControl.start();