[Android] [PATCH 06/11] Finer audio browsing
Geoffrey Métais
geoffrey.metais at gmail.com
Mon Nov 17 17:53:43 CET 2014
---
.../src/org/videolan/vlc/gui/tv/CardPresenter.java | 39 ++---
.../src/org/videolan/vlc/gui/tv/GridFragment.java | 175 +++++++++++++++++++--
.../org/videolan/vlc/gui/tv/MainTvActivity.java | 52 +++---
.../vlc/gui/video/VideoBrowserInterface.java | 11 +-
4 files changed, 225 insertions(+), 52 deletions(-)
diff --git a/vlc-android/src/org/videolan/vlc/gui/tv/CardPresenter.java b/vlc-android/src/org/videolan/vlc/gui/tv/CardPresenter.java
index b1338ee..a070433 100644
--- a/vlc-android/src/org/videolan/vlc/gui/tv/CardPresenter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/tv/CardPresenter.java
@@ -26,7 +26,6 @@ public class CardPresenter extends Presenter {
private static Drawable sDefaultCardImage;
static class ViewHolder extends Presenter.ViewHolder {
- private Media mMedia;
private ImageCardView mCardView;
public ViewHolder(View view) {
@@ -34,14 +33,6 @@ public class CardPresenter extends Presenter {
mCardView = (ImageCardView) view;
}
- public void setMovie(Media m) {
- mMedia = m;
- }
-
- public Media getMovie() {
- return mMedia;
- }
-
public ImageCardView getCardView() {
return mCardView;
}
@@ -80,16 +71,28 @@ public class CardPresenter extends Presenter {
@Override
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
- Media media = (Media) item;
- ((ViewHolder) viewHolder).setMovie(media);
-
- ((ViewHolder) viewHolder).mCardView.setTitleText(media.getTitle());
- ((ViewHolder) viewHolder).mCardView.setContentText(media.getDescription());
((ViewHolder) viewHolder).mCardView.setMainImageDimensions(CARD_WIDTH, CARD_HEIGHT);
- if (media.isPictureParsed())
- ((ViewHolder) viewHolder).updateCardViewImage(media.getLocation());
- else
- ((ViewHolder) viewHolder).updateCardViewImage(sDefaultCardImage);
+ if (item instanceof Media) {
+ Media media = (Media) item;
+ ((ViewHolder) viewHolder).mCardView.setTitleText(media.getTitle());
+ ((ViewHolder) viewHolder).mCardView.setContentText(media.getDescription());
+ if (media.isPictureParsed())
+ ((ViewHolder) viewHolder).updateCardViewImage(media.getLocation());
+ else
+ ((ViewHolder) viewHolder).updateCardViewImage(sDefaultCardImage);
+ } else if (item instanceof GridFragment.ListItem) {
+ GridFragment.ListItem listItem = (GridFragment.ListItem) item;
+ Media media = listItem.mMediaList.get(0);
+ ((ViewHolder) viewHolder).mCardView.setTitleText(listItem.mTitle);
+ ((ViewHolder) viewHolder).mCardView.setContentText(listItem.mSubTitle);
+ if (media.isPictureParsed())
+ ((ViewHolder) viewHolder).updateCardViewImage(media.getLocation());
+ else
+ ((ViewHolder) viewHolder).updateCardViewImage(sDefaultCardImage);
+ } else if (item instanceof String){
+ ((ViewHolder) viewHolder).mCardView.setTitleText((String) item);
+ ((ViewHolder) viewHolder).updateCardViewImage(sDefaultCardImage);
+ }
}
@Override
diff --git a/vlc-android/src/org/videolan/vlc/gui/tv/GridFragment.java b/vlc-android/src/org/videolan/vlc/gui/tv/GridFragment.java
index 64a64ae..bfc1f14 100644
--- a/vlc-android/src/org/videolan/vlc/gui/tv/GridFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/tv/GridFragment.java
@@ -20,7 +20,10 @@
package org.videolan.vlc.gui.tv;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
@@ -29,10 +32,11 @@ import org.videolan.vlc.MediaDatabase;
import org.videolan.vlc.MediaLibrary;
import org.videolan.vlc.R;
import org.videolan.vlc.Thumbnailer;
-import org.videolan.vlc.VLCApplication;
+import org.videolan.vlc.gui.audio.AudioUtil;
+import org.videolan.vlc.gui.audio.MediaComparators;
+import org.videolan.vlc.gui.tv.audioplayer.AudioPlayerActivity;
import org.videolan.vlc.gui.video.VideoBrowserInterface;
import org.videolan.vlc.gui.video.VideoListHandler;
-import org.videolan.vlc.gui.video.VideoPlayerActivity;
import org.videolan.vlc.util.Util;
import android.content.Context;
@@ -47,31 +51,46 @@ import android.support.v17.leanback.widget.Row;
import android.support.v17.leanback.widget.VerticalGridPresenter;
public class GridFragment extends VerticalGridFragment implements VideoBrowserInterface {
- private static final String TAG = "VerticalGridFragment";
+ private static final String TAG = "VLC/GridFragment";
private static final int NUM_COLUMNS = 5;
protected final CyclicBarrier mBarrier = new CyclicBarrier(2);
protected Media mItemToUpdate;
+ private Map<String, ListItem> mMediaItemMap;
+ private ArrayList<ListItem> mMediaItemList;
private ArrayObjectAdapter mAdapter;
private MediaLibrary mMediaLibrary;
private Thumbnailer mThumbnailer;
HashMap<String, Integer> mMediaIndex;
Context mContext;
- long mType;
+ String mCategory, mFilter;
+ long mType = -1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getActivity();
- mType = getActivity().getIntent().getLongExtra("id", 0);
+ if (savedInstanceState != null){
+ mType = savedInstanceState.getLong(MEDIA_SECTION);
+ mCategory = savedInstanceState.getString(AUDIO_CATEGORY);
+ mFilter = savedInstanceState.getString(AUDIO_FILTER);
+ } else {
+ mType = getActivity().getIntent().getLongExtra(MEDIA_SECTION, -1);
+ mCategory = getActivity().getIntent().getStringExtra(AUDIO_CATEGORY);
+ mFilter = getActivity().getIntent().getStringExtra(AUDIO_FILTER);
+ }
- setTitle(getString(R.string.app_name_full));
mMediaLibrary = MediaLibrary.getInstance();
- if (mType == HEADER_VIDEO)
+ if (mType == HEADER_VIDEO) {
mThumbnailer = new Thumbnailer(mContext, getActivity().getWindowManager().getDefaultDisplay());
- setupFragment();
+ setupFragment();
+ } else if (mType == HEADER_MUSIC) {
+ setupFragment();
+ } else {
+ setupFragmentForAudio();
+ }
}
public void onResume() {
@@ -94,6 +113,12 @@ public class GridFragment extends VerticalGridFragment implements VideoBrowserIn
mThumbnailer.stop();
}
+ public void onSaveInstanceState(Bundle outState){
+ super.onSaveInstanceState(outState);
+ outState.putLong(MEDIA_SECTION, mType);
+ outState.putString(AUDIO_CATEGORY, mCategory);
+ }
+
@Override
public void onDestroy() {
super.onDestroy();
@@ -102,7 +127,96 @@ public class GridFragment extends VerticalGridFragment implements VideoBrowserIn
mBarrier.reset();
}
+ private void setupFragmentForAudio() {
+ Bitmap picture;
+ String title;
+ mMediaItemMap = new HashMap<String, ListItem>();
+ mMediaItemList = new ArrayList<GridFragment.ListItem>();
+ VerticalGridPresenter gridPresenter = new VerticalGridPresenter();
+ mAdapter = new ArrayObjectAdapter(new CardPresenter());
+ gridPresenter.setNumberOfColumns(NUM_COLUMNS);
+ setGridPresenter(gridPresenter);
+
+ List<Media> audioList = MediaLibrary.getInstance().getAudioItems();
+ if (getString(R.string.artists).equals(mCategory)){
+ Collections.sort(audioList, MediaComparators.byArtist);
+ title = getString(R.string.artists);
+ for (Media media : audioList){
+ add(media.getArtist(), null, media);
+ }
+ } else if (getString(R.string.albums).equals(mCategory)){
+ title = getString(R.string.albums);
+ Collections.sort(audioList, MediaComparators.byAlbum);
+ for (Media media : audioList){
+ if (mFilter == null
+ || (mType == FILTER_ARTIST && mFilter.equals(media.getArtist()))
+ || (mType == FILTER_GENRE && mFilter.equals(media.getGenre())))
+ add(media.getAlbum(), media.getArtist(), media);
+ }
+ //Customize title for artist/genre browsing
+ if (mType == FILTER_ARTIST){
+ title = title + " " + mMediaItemList.get(0).mMediaList.get(0).getArtist();
+ } else if (mType == FILTER_GENRE){
+ title = title + " " + mMediaItemList.get(0).mMediaList.get(0).getGenre();
+ }
+ } else if (getString(R.string.genres).equals(mCategory)){
+ title = getString(R.string.genres);
+ Collections.sort(audioList, MediaComparators.byGenre);
+ for (Media media : audioList){
+ add(media.getGenre(), null, media);
+ }
+ } else if (getString(R.string.songs).equals(mCategory)){
+ title = getString(R.string.songs);
+ Collections.sort(audioList, MediaComparators.byName);
+ for (Media media : audioList){
+ add(media.getTitle(), media.getArtist(), media);
+ }
+ } else {
+ title = getString(R.string.app_name_full);
+ }
+ setTitle(title);
+ //check for pictures
+ for (Media media : audioList){
+ picture = AudioUtil.getCover(mContext, media, 320);
+ if (picture != null){
+ MediaDatabase.setPicture(media, picture);
+ picture = null;
+ }
+ }
+ mAdapter.addAll(0, mMediaItemList);
+ setAdapter(mAdapter);
+
+ setOnItemClickedListener(new OnItemClickedListener() {
+ @Override
+ public void onItemClicked(Object item, Row row) {
+ ListItem listItem = (ListItem) item;
+ Intent intent;
+ if (getString(R.string.artists).equals(mCategory)){
+ intent = new Intent(mContext, VerticalGridActivity.class);
+ intent.putExtra(AUDIO_CATEGORY, getString(R.string.albums));
+ intent.putExtra(MEDIA_SECTION, FILTER_ARTIST);
+ intent.putExtra(AUDIO_FILTER, listItem.mMediaList.get(0).getArtist());
+ } else if (getString(R.string.genres).equals(mCategory)){
+ intent = new Intent(mContext, VerticalGridActivity.class);
+ intent.putExtra(AUDIO_CATEGORY, getString(R.string.albums));
+ intent.putExtra(MEDIA_SECTION, FILTER_GENRE);
+ intent.putExtra(AUDIO_FILTER, listItem.mMediaList.get(0).getGenre());
+ } else {
+ ArrayList<String> locations = new ArrayList<String>();
+ for (Media media : listItem.mMediaList){
+ locations.add(media.getLocation());
+ }
+ intent = new Intent(mContext, AudioPlayerActivity.class);
+ intent.putExtra("locations", locations);
+ }
+ startActivity(intent);
+ }
+ });
+ }
+
+ //TODO shrink audio part, I keep it for now just in case...
private void setupFragment() {
+ setTitle(getString(R.string.app_name_full));
int size;
Media media;
Bitmap picture;
@@ -118,7 +232,7 @@ public class GridFragment extends VerticalGridFragment implements VideoBrowserIn
ArrayList<Media> mediaList = null;
if (mType == HEADER_VIDEO)
mediaList = mMediaLibrary.getVideoItems();
- else if (mType == HEADER_MUSIC)
+ else
mediaList = mMediaLibrary.getAudioItems();
size = mediaList == null ? 0 : mediaList.size();
mMediaIndex = new HashMap<String, Integer>(size);
@@ -135,6 +249,12 @@ public class GridFragment extends VerticalGridFragment implements VideoBrowserIn
MediaDatabase.setPicture(media, picture);
picture = null;
}
+ } else {
+ picture = AudioUtil.getCover(mContext, media, 320);
+ if (picture != null){
+ MediaDatabase.setPicture(media, picture);
+ picture = null;
+ }
}
}
@@ -143,16 +263,15 @@ public class GridFragment extends VerticalGridFragment implements VideoBrowserIn
/*setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(Object item, Row row) {
+ setTitle(((Media )item).getTitle());
}
});*/
setOnItemClickedListener(new OnItemClickedListener() {
@Override
public void onItemClicked(Object item, Row row) {
- Media media = (Media)item;
- if (media.getType() == Media.TYPE_VIDEO){
- VideoPlayerActivity.start(getActivity(), media.getLocation(), false);
- }
+ Media media = (Media) item;
+ TvUtil.openMedia(getActivity(), media, null);
}
});
}
@@ -184,4 +303,34 @@ public class GridFragment extends VerticalGridFragment implements VideoBrowserIn
};
private Handler mHandler = new VideoListHandler(this);
+
+ // An item of the list: a media or a separator.
+ public class ListItem {
+ public String mTitle;
+ public String mSubTitle;
+ public ArrayList<Media> mMediaList;
+ public boolean mIsSeparator;
+
+ public ListItem(String title, String subTitle, Media media, boolean isSeparator) {
+ mMediaList = new ArrayList<Media>();
+ if (media != null)
+ mMediaList.add(media);
+ mTitle = title;
+ mSubTitle = subTitle;
+ mIsSeparator = isSeparator;
+ }
+ }
+
+ public void add(String title, String subTitle, Media media) {
+ if(title == null) return;
+ title = title.trim();
+ if(subTitle != null) subTitle = subTitle.trim();
+ if (mMediaItemMap.containsKey(title))
+ mMediaItemMap.get(title).mMediaList.add(media);
+ else {
+ ListItem item = new ListItem(title, subTitle, media, false);
+ mMediaItemMap.put(title, item);
+ mMediaItemList.add(item);
+ }
+ }
}
\ No newline at end of file
diff --git a/vlc-android/src/org/videolan/vlc/gui/tv/MainTvActivity.java b/vlc-android/src/org/videolan/vlc/gui/tv/MainTvActivity.java
index 5f8d137..e3c1558 100644
--- a/vlc-android/src/org/videolan/vlc/gui/tv/MainTvActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/tv/MainTvActivity.java
@@ -30,7 +30,6 @@ import org.videolan.vlc.MediaDatabase;
import org.videolan.vlc.MediaLibrary;
import org.videolan.vlc.R;
import org.videolan.vlc.Thumbnailer;
-import org.videolan.vlc.gui.audio.AudioUtil;
import org.videolan.vlc.gui.tv.audioplayer.AudioPlayerActivity;
import org.videolan.vlc.gui.video.VideoBrowserInterface;
import org.videolan.vlc.gui.video.VideoListHandler;
@@ -52,7 +51,6 @@ import android.support.v17.leanback.widget.ListRow;
import android.support.v17.leanback.widget.ListRowPresenter;
import android.support.v17.leanback.widget.OnItemClickedListener;
import android.support.v17.leanback.widget.Row;
-import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
@@ -60,7 +58,7 @@ public class MainTvActivity extends Activity implements VideoBrowserInterface {
private static final int NUM_ITEMS_PREVIEW = 5;
- public static final String TAG = "BrowseActivity";
+ public static final String TAG = "VLC/MainTvActivity";
protected BrowseFragment mBrowseFragment;
protected final CyclicBarrier mBarrier = new CyclicBarrier(2);
@@ -68,8 +66,9 @@ public class MainTvActivity extends Activity implements VideoBrowserInterface {
private Thumbnailer mThumbnailer;
private Media mItemToUpdate;
ArrayObjectAdapter mRowsAdapter;
- ArrayObjectAdapter videoAdapter;
- ArrayObjectAdapter audioAdapter;
+ ArrayObjectAdapter mVideoAdapter;
+ ArrayObjectAdapter mAudioAdapter;
+ ArrayObjectAdapter mCategoriesAdapter;
HashMap<String, Integer> mVideoIndex;
Drawable mDefaultBackground;
Activity mContext;
@@ -77,7 +76,13 @@ public class MainTvActivity extends Activity implements VideoBrowserInterface {
OnItemClickedListener mItemClickListener = new OnItemClickedListener() {
@Override
public void onItemClicked(Object item, Row row) {
- TvUtil.openMedia(mContext, (Media)item, row);
+ if (row.getId() == HEADER_CATEGORIES){
+ String category = (String)item;
+ Intent intent = new Intent(mContext, VerticalGridActivity.class);
+ intent.putExtra(AUDIO_CATEGORY, category);
+ startActivity(intent);
+ } else
+ TvUtil.openMedia(mContext, (Media)item, row);
}
};
@@ -93,7 +98,7 @@ public class MainTvActivity extends Activity implements VideoBrowserInterface {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*
- * skip browser and show direcly Audio Player if a song is playing
+ * skip browser and show directly Audio Player if a song is playing
*/
if (LibVLC.getExistingInstance() != null){
if (LibVLC.getExistingInstance().isPlaying()){
@@ -183,7 +188,7 @@ public class MainTvActivity extends Activity implements VideoBrowserInterface {
}
public void updateItem() {
- videoAdapter.notifyArrayItemRangeChanged(mVideoIndex.get(mItemToUpdate.getLocation()), 1);
+ mVideoAdapter.notifyArrayItemRangeChanged(mVideoIndex.get(mItemToUpdate.getLocation()), 1);
try {
mBarrier.await();
} catch (InterruptedException e) {
@@ -204,7 +209,7 @@ public class MainTvActivity extends Activity implements VideoBrowserInterface {
protected Void doInBackground(Void... params) {
MediaDatabase mediaDatabase = MediaDatabase.getInstance();
ArrayList<Media> videoList = mMediaLibrary.getVideoItems();
- ArrayList<Media> audioList = mMediaLibrary.getAudioItems();
+// ArrayList<Media> audioList = mMediaLibrary.getAudioItems();
int size;
Media item;
Bitmap picture;
@@ -213,7 +218,7 @@ public class MainTvActivity extends Activity implements VideoBrowserInterface {
if (!videoList.isEmpty()) {
size = videoList.size();
mVideoIndex = new HashMap<String, Integer>(size);
- videoAdapter = new ArrayObjectAdapter(
+ mVideoAdapter = new ArrayObjectAdapter(
new CardPresenter());
if (NUM_ITEMS_PREVIEW < size)
size = NUM_ITEMS_PREVIEW;
@@ -221,7 +226,7 @@ public class MainTvActivity extends Activity implements VideoBrowserInterface {
item = videoList.get(i);
picture = mediaDatabase.getPicture(mContext, item.getLocation());
- videoAdapter.add(item);
+ mVideoAdapter.add(item);
mVideoIndex.put(item.getLocation(), i);
if (mThumbnailer != null){
if (picture== null) {
@@ -233,18 +238,18 @@ public class MainTvActivity extends Activity implements VideoBrowserInterface {
}
}
// Empty item to launch grid activity
- videoAdapter.add(new Media(null, 0, 0, Media.TYPE_GROUP, null, "Browse more", null, null, null, 0, 0, null, 0, 0));
+ mVideoAdapter.add(new Media(null, 0, 0, Media.TYPE_GROUP, null, "Browse more", null, null, null, 0, 0, null, 0, 0));
HeaderItem header = new HeaderItem(HEADER_VIDEO, getString(R.string.video), null);
- mRowsAdapter.add(new ListRow(header, videoAdapter));
+ mRowsAdapter.add(new ListRow(header, mVideoAdapter));
}
- // update audio section
+ /*// update audio section
if (!audioList.isEmpty()) {
size = audioList.size();
if (NUM_ITEMS_PREVIEW < size)
size = NUM_ITEMS_PREVIEW;
- audioAdapter = new ArrayObjectAdapter(new CardPresenter());
+ mAudioAdapter = new ArrayObjectAdapter(new CardPresenter());
for (int i = 0 ; i < size ; ++i) {
item = audioList.get(i);
picture = AudioUtil.getCover(mContext, item, 320);
@@ -252,15 +257,24 @@ public class MainTvActivity extends Activity implements VideoBrowserInterface {
MediaDatabase.setPicture(item, picture);
picture = null;
}
- audioAdapter.add(item);
+ mAudioAdapter.add(item);
}
// Empty item to launch grid activity
- audioAdapter.add(new Media(null, 0, 0, Media.TYPE_GROUP, null, "Browse more", null, null, null, 0, 0, null, 0, 0));
+ mAudioAdapter.add(new Media(null, 0, 0, Media.TYPE_GROUP, null, "Browse more", null, null, null, 0, 0, null, 0, 0));
HeaderItem header = new HeaderItem(HEADER_MUSIC, getString(R.string.audio), null);
- mRowsAdapter.add(new ListRow(header, audioAdapter));
- }
+ mRowsAdapter.add(new ListRow(header, mAudioAdapter));
+ }*/
+
+ mCategoriesAdapter = new ArrayObjectAdapter(new CardPresenter());
+ mCategoriesAdapter.add(getString(R.string.artists));
+ mCategoriesAdapter.add(getString(R.string.albums));
+ mCategoriesAdapter.add(getString(R.string.genres));
+ mCategoriesAdapter.add(getString(R.string.songs));
+ HeaderItem header = new HeaderItem(HEADER_CATEGORIES, getString(R.string.audio), null);
+ mRowsAdapter.add(new ListRow(header, mCategoriesAdapter));
+
return null;
}
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoBrowserInterface.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoBrowserInterface.java
index 84efc01..b06a5e7 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoBrowserInterface.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoBrowserInterface.java
@@ -5,8 +5,15 @@ import java.util.concurrent.BrokenBarrierException;
import org.videolan.libvlc.Media;
public interface VideoBrowserInterface {
- public static final int HEADER_VIDEO = 0;
- public static final int HEADER_MUSIC = 1;
+ public static final long HEADER_VIDEO = 0;
+ public static final long HEADER_MUSIC = 1;
+ public static final long HEADER_CATEGORIES = 2;
+ public static final long FILTER_ARTIST = 3;
+ public static final long FILTER_GENRE = 4;
+
+ public static final String MEDIA_SECTION = "id";
+ public static final String AUDIO_CATEGORY = "category";
+ public static final String AUDIO_FILTER = "filter";
public void resetBarrier();
public void setItemToUpdate(Media item);
--
1.9.1
More information about the Android
mailing list