MusicConsumptionExampleFragment.java revision 1dd934eb3d2aa4e685585fa0f26c738feee0db4c
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15package android.support.v17.leanback.supportleanbackshowcase.app.media; 16 17import android.content.Context; 18import android.content.res.Resources; 19import android.graphics.drawable.Drawable; 20import android.net.Uri; 21import android.os.Bundle; 22import android.support.v17.leanback.app.PlaybackOverlayFragment; 23import android.support.v17.leanback.supportleanbackshowcase.utils.Constants; 24import android.support.v17.leanback.supportleanbackshowcase.R; 25import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; 26import android.support.v17.leanback.supportleanbackshowcase.models.Song; 27import android.support.v17.leanback.supportleanbackshowcase.models.SongList; 28import android.support.v17.leanback.widget.*; 29import android.support.v17.leanback.widget.AbstractMediaItemPresenter; 30import android.util.Log; 31 32import com.google.gson.Gson; 33 34import java.util.List; 35 36/** 37 * This example shows how to play music files and build a simple track list. 38 */ 39public class MusicConsumptionExampleFragment extends PlaybackOverlayFragment implements 40 BaseOnItemViewClickedListener, BaseOnItemViewSelectedListener, 41 MediaPlayerGlue.OnMediaFileFinishedPlayingListener { 42 43 private static final String TAG = "MusicConsumptionExampleFragment"; 44 private static final int PLAYLIST_ACTION_ID = 0; 45 private static final int FAVORITE_ACTION_ID = 1; 46 private ArrayObjectAdapter mRowsAdapter; 47 private MediaPlayerGlue mGlue; 48 private int mCurrentSongIndex = 0; 49 private List<Song> mSongList; 50 private boolean mAdapterNotified = false; 51 52 @Override public void onCreate(Bundle savedInstanceState) { 53 super.onCreate(savedInstanceState); 54 if (Constants.LOCAL_LOGD) Log.d(TAG, "onCreate"); 55 56 mGlue = new MediaPlayerGlue(getActivity(), this) { 57 58 @Override protected void onRowChanged(PlaybackControlsRow row) { 59 if (mRowsAdapter == null || mAdapterNotified) return; 60 //mAdapterNotified = true; 61 mRowsAdapter.notifyArrayItemRangeChanged(0, 1); 62 } 63 }; 64 mGlue.setOnMediaFileFinishedPlayingListener(this); 65 66 String json = Utils.inputStreamToString( 67 getResources().openRawResource(R.raw.music_consumption_example)); 68 69 70 mSongList = new Gson().fromJson(json, SongList.class).getSongs(); 71 72 Resources res = getActivity().getResources(); 73 74 // For each song add a playlist and favorite actions. 75 for(Song song : mSongList) { 76 MultiActionsProvider.MultiAction[] mediaRowActions = new 77 MultiActionsProvider.MultiAction[2]; 78 MultiActionsProvider.MultiAction playlistAction = new 79 MultiActionsProvider.MultiAction(PLAYLIST_ACTION_ID); 80 Drawable[] playlistActionDrawables = new Drawable[] { 81 res.getDrawable(R.drawable.ic_playlist_add_white_24dp, 82 getActivity().getTheme()), 83 res.getDrawable(R.drawable.ic_playlist_add_filled_24dp, 84 getActivity().getTheme())}; 85 playlistAction.setDrawables(playlistActionDrawables); 86 mediaRowActions[0] = playlistAction; 87 88 MultiActionsProvider.MultiAction favoriteAction = new 89 MultiActionsProvider.MultiAction(FAVORITE_ACTION_ID); 90 Drawable[] favoriteActionDrawables = new Drawable[] { 91 res.getDrawable(R.drawable.ic_favorite_border_white_24dp, 92 getActivity().getTheme()), 93 res.getDrawable(R.drawable.ic_favorite_filled_24dp, 94 getActivity().getTheme())}; 95 favoriteAction.setDrawables(favoriteActionDrawables); 96 mediaRowActions[1] = favoriteAction; 97 song.setMediaRowActions(mediaRowActions); 98 } 99 100 Song song = mSongList.get(mCurrentSongIndex); 101 MediaPlayerGlue.MetaData metaData = new MediaPlayerGlue.MetaData(); 102 metaData.setArtist(song.getDescription()); 103 metaData.setTitle(song.getTitle()); 104 metaData.setCover(getResources().getDrawable(song.getImageResource(getActivity()), null)); 105 Uri uri = Utils.getResourceUri(getActivity(), song.getFileResource(getActivity())); 106 mGlue.setMetaData(metaData); 107 mGlue.setMediaSource(uri); 108 109 addPlaybackControlsRow(); 110 } 111 112 @Override public void onStart() { 113 super.onStart(); 114 mGlue.enableProgressUpdating(mGlue.hasValidMedia() && mGlue.isMediaPlaying()); 115 } 116 117 @Override public void onStop() { 118 super.onStop(); 119 mGlue.enableProgressUpdating(false); 120 mGlue.reset(); 121 } 122 123 static class SongPresenter extends AbstractMediaItemPresenter { 124 125 SongPresenter() { 126 super(); 127 } 128 129 SongPresenter(Context context, int themeResId) { 130 super(themeResId); 131 setHasMediaRowSeparator(true); 132 } 133 134 @Override 135 protected void onBindMediaDetails(ViewHolder vh, Object item) { 136 137 int favoriteTextColor = vh.view.getContext().getResources().getColor( 138 R.color.song_row_favorite_color); 139 Song song = (Song) item; 140 vh.getMediaItemNumberView().setText("" + song.getNumber()); 141 142 String songTitle = song.getTitle() + " / " + song.getDescription(); 143 vh.getMediaItemNameView().setText(songTitle); 144 145 vh.getMediaItemDurationView().setText("" + song.getDuration()); 146 147 if (song.isFavorite()) { 148 vh.getMediaItemNumberView().setTextColor(favoriteTextColor); 149 vh.getMediaItemNameView().setTextColor(favoriteTextColor); 150 vh.getMediaItemDurationView().setTextColor(favoriteTextColor); 151 } else { 152 vh.getMediaItemNumberView().setTextAppearance( 153 R.style.TextAppearance_Leanback_PlaybackMediaItemNumber); 154 vh.getMediaItemNameView().setTextAppearance( 155 R.style.TextAppearance_Leanback_PlaybackMediaItemName); 156 vh.getMediaItemDurationView().setTextAppearance( 157 R.style.TextAppearance_Leanback_PlaybackMediaItemDuration); 158 } 159 } 160 }; 161 162 static class SongPresenterSelector extends PresenterSelector { 163 Presenter mRegularPresenter; 164 Presenter mFavoritePresenter; 165 166 /** 167 * Adds a presenter to be used for the given class. 168 */ 169 public SongPresenterSelector setSongPresenterRegular(Presenter presenter) { 170 mRegularPresenter = presenter; 171 return this; 172 } 173 174 /** 175 * Adds a presenter to be used for the given class. 176 */ 177 public SongPresenterSelector setSongPresenterFavorite(Presenter presenter) { 178 mFavoritePresenter = presenter; 179 return this; 180 } 181 182 @Override 183 public Presenter[] getPresenters() { 184 return new Presenter[]{mRegularPresenter, mFavoritePresenter}; 185 } 186 187 @Override 188 public Presenter getPresenter(Object item) { 189 return ( (Song) item).isFavorite() ? mFavoritePresenter : mRegularPresenter; 190 } 191 192 } 193 194 static class TrackListHeaderPresenter extends AbstractMediaListHeaderPresenter { 195 196 TrackListHeaderPresenter() { 197 super(); 198 } 199 200 @Override 201 protected void onBindMediaListHeaderViewHolder(ViewHolder vh, Object item) { 202 vh.getHeaderView().setText("Tracklist"); 203 } 204 }; 205 206 private void addPlaybackControlsRow() { 207 mRowsAdapter = new ArrayObjectAdapter(new ClassPresenterSelector() 208 .addClassPresenterSelector(Song.class, new SongPresenterSelector() 209 .setSongPresenterRegular(new SongPresenter(getActivity(), 210 R.style.Theme_Example_LeanbackMusic_RegularSongNumbers)) 211 .setSongPresenterFavorite(new SongPresenter(getActivity(), 212 R.style.Theme_Example_LeanbackMusic_FavoriteSongNumbers))) 213 .addClassPresenter(TrackListHeader.class, new TrackListHeaderPresenter()) 214 .addClassPresenter(PlaybackControlsRow.class, 215 mGlue.createControlsRowAndPresenter())); 216 mRowsAdapter.add(mGlue.getControlsRow()); 217 mRowsAdapter.add(new TrackListHeader()); 218 mRowsAdapter.addAll(2, mSongList); 219 setAdapter(mRowsAdapter); 220 setOnItemViewClickedListener(this); 221 setOnItemViewSelectedListener(this); 222 } 223 224 public MusicConsumptionExampleFragment() { 225 super(); 226 } 227 228 229 230 @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, 231 RowPresenter.ViewHolder rowViewHolder, Object row) { 232 233 if (item instanceof Action) { 234 // if the clicked item is a primary or secondary action in the playback controller 235 mGlue.onActionClicked((Action) item); 236 } else if (row instanceof Song) { 237 // if a media item row is clicked 238 Song clickedSong = (Song) row; 239 AbstractMediaItemPresenter.ViewHolder songRowVh = 240 (AbstractMediaItemPresenter.ViewHolder) rowViewHolder; 241 242 // if an action within a media item row is clicked 243 if (item instanceof MultiActionsProvider.MultiAction) { 244 if ( ((MultiActionsProvider.MultiAction) item).getId() == FAVORITE_ACTION_ID) { 245 MultiActionsProvider.MultiAction favoriteAction = 246 (MultiActionsProvider.MultiAction) item; 247 MultiActionsProvider.MultiAction playlistAction = 248 songRowVh.getMediaItemRowActions()[0]; 249 favoriteAction.incrementIndex(); 250 playlistAction.incrementIndex();; 251 252 clickedSong.setFavorite(!clickedSong.isFavorite()); 253 songRowVh.notifyDetailsChanged(); 254 songRowVh.notifyActionChanged(playlistAction); 255 songRowVh.notifyActionChanged(favoriteAction); 256 } 257 } else if (item == null){ 258 // if a media item details is clicked, start playing that media item 259 onSongDetailsClicked(clickedSong); 260 } 261 262 } 263 264 265 } 266 267 @Override 268 public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, 269 RowPresenter.ViewHolder rowViewHolder, Object row) { 270 } 271 272 273 public void onSongDetailsClicked(Song song) { 274 int nextSongIndex = mSongList.indexOf(song); 275 mCurrentSongIndex = nextSongIndex; 276 startPlayback(); 277 } 278 279 280 @Override public void onMediaFileFinishedPlaying(MediaPlayerGlue.MetaData song) { 281 if (mGlue.repeatOne()) { 282 } else if (mGlue.useShuffle()) { 283 mCurrentSongIndex = (int) (Math.random() * mSongList.size()); 284 } else { 285 mCurrentSongIndex++; 286 if (mCurrentSongIndex >= mSongList.size()) { 287 mCurrentSongIndex = 0; 288 if (!mGlue.repeatAll()) { 289 return; 290 } 291 } 292 } 293 startPlayback(); 294 } 295 296 private void startPlayback() { 297 Song song = mSongList.get(mCurrentSongIndex); 298 MediaPlayerGlue.MetaData metaData = new MediaPlayerGlue.MetaData(); 299 metaData.setArtist(song.getDescription()); 300 metaData.setTitle(song.getTitle()); 301 metaData.setCover(getResources().getDrawable(song.getImageResource(getActivity()), null)); 302 303 Uri uri = Utils.getResourceUri(getActivity(), song.getFileResource(getActivity())); 304 mGlue.setMetaData(metaData); 305 mGlue.setMediaSource(uri); 306 mGlue.startPlayback(); 307 } 308} 309