summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Li <pyli@google.com>2019-05-30 18:11:35 -0700
committerPeter Li <pyli@google.com>2019-05-31 14:14:18 -0700
commit5970b3de51391c5786a8e26757f1843bbe265f4a (patch)
treea9097518b9debcd2f641da514497b4e20bbe796e
parentba1dbeb96efe8ecf6be933a30992e868ff248f52 (diff)
downloadCluster-5970b3de51391c5786a8e26757f1843bbe265f4a.tar.gz
Refactor music facet, use MetadataController
Fix: 131720177 Test: Manual Change-Id: Ib11a9592990211a18d23a2873419bfedc78e6eb8
-rw-r--r--res/layout/fragment_music.xml19
-rw-r--r--res/layout/metadata_normal.xml38
-rw-r--r--res/values/dimens.xml5
-rw-r--r--src/android/car/cluster/MusicFragment.java49
-rw-r--r--src/android/car/cluster/MusicFragmentViewModel.java84
5 files changed, 70 insertions, 125 deletions
diff --git a/res/layout/fragment_music.xml b/res/layout/fragment_music.xml
index f9c72f7..8317253 100644
--- a/res/layout/fragment_music.xml
+++ b/res/layout/fragment_music.xml
@@ -23,13 +23,6 @@
app:cardElevation="0dp"
app:cardCornerRadius="6dp">
- <com.android.car.apps.common.CrossfadeImageView
- android:id="@+id/album_background"
- android:foreground="?android:attr/selectableItemBackground"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scaleType="fitStart" />
-
<View
android:id="@+id/playback_scrim"
android:layout_width="match_parent"
@@ -46,7 +39,7 @@
<TextView
android:id="@+id/app_name"
- android:layout_width="0dp"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/playback_fragment_text_margin_top"
android:layout_marginLeft="@dimen/playback_fragment_text_margin_x"
@@ -56,7 +49,15 @@
android:maxLines="1"
android:includeFontPadding="false"
app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintTop_toTopOf="parent"/>
+
+ <ImageView
+ android:id="@+id/app_icon"
+ android:layout_width="@dimen/playback_app_icon_size"
+ android:layout_height="@dimen/playback_app_icon_size"
+ android:layout_marginTop="@dimen/playback_fragment_icon_margin_top"
+ android:layout_marginLeft="@dimen/playback_fragment_icon_margin_x"
+ app:layout_constraintStart_toEndOf="@+id/app_name"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.constraintlayout.widget.Guideline
diff --git a/res/layout/metadata_normal.xml b/res/layout/metadata_normal.xml
index 5cb75a6..ee1de38 100644
--- a/res/layout/metadata_normal.xml
+++ b/res/layout/metadata_normal.xml
@@ -48,18 +48,38 @@
app:layout_constraintEnd_toStartOf="@+id/time"
app:layout_constraintTop_toBottomOf="@+id/title"
tools:text="Body 2"/>
- <TextView
- android:id="@+id/time"
- android:layout_width="wrap_content"
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/metadata_normal_time_margin_top"
- android:ellipsize="end"
- android:maxLines="@integer/playback_subtitle_text_max_lines"
- android:gravity="end"
- android:textAppearance="?android:attr/textAppearanceMedium"
+ android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title"
- tools:text="3:27 / 4:03"/>
+ android:gravity="end"
+ android:layout_marginTop="@dimen/metadata_normal_time_margin_top">
+
+ <TextView
+ android:id="@+id/time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLines="@integer/playback_subtitle_text_max_lines"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ tools:text="3:27"/>
+ <TextView
+ android:id="@+id/time_separator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLines="@integer/playback_subtitle_text_max_lines"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text=" / "
+ tools:text=" / "/>
+ <TextView
+ android:id="@+id/track_length"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLines="@integer/playback_subtitle_text_max_lines"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ tools:text="3:27"/>
+ </LinearLayout>
<SeekBar
android:id="@+id/seek_bar"
android:layout_width="0dp"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 21aec67..4fa9e22 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -70,6 +70,11 @@
<dimen name="metadata_normal_seek_margin_top">@*android:dimen/car_padding_4</dimen>
<dimen name="metadata_normal_subtitle_margin_end">@*android:dimen/car_padding_3</dimen>
+ <!-- Size of the selected app's icon -->
+ <dimen name="playback_app_icon_size">25dp</dimen>
+ <dimen name="playback_fragment_icon_margin_x">15dp</dimen>
+ <dimen name="playback_fragment_icon_margin_top">29dp</dimen>
+
<!-- Size of the album art thumbnail -->
<dimen name="playback_album_art_size_normal">156dp</dimen>
diff --git a/src/android/car/cluster/MusicFragment.java b/src/android/car/cluster/MusicFragment.java
index f5a2303..b4e0039 100644
--- a/src/android/car/cluster/MusicFragment.java
+++ b/src/android/car/cluster/MusicFragment.java
@@ -29,10 +29,12 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModelProviders;
-import com.android.car.apps.common.BackgroundImageView;
+import com.android.car.media.common.MetadataController;
import com.android.car.media.common.playback.PlaybackViewModel;
import com.android.car.media.common.source.MediaSourceViewModel;
+import com.bumptech.glide.request.target.Target;
+
/**
* Displays information on the current media item selected.
*/
@@ -54,42 +56,39 @@ public class MusicFragment extends Fragment {
MusicFragmentViewModel innerViewModel = ViewModelProviders.of(activity).get(
MusicFragmentViewModel.class);
- innerViewModel.init(mMediaSourceViewModel, playbackViewModel);
+ innerViewModel.init(mMediaSourceViewModel);
View view = inflater.inflate(R.layout.fragment_music, container, false);
TextView appName = view.findViewById(R.id.app_name);
innerViewModel.getAppName().observe(getViewLifecycleOwner(), appName::setText);
- TextView title = view.findViewById(R.id.title);
- innerViewModel.getTitle().observe(getViewLifecycleOwner(), title::setText);
+ ImageView appIcon = view.findViewById(R.id.app_icon);
+ innerViewModel.getAppIcon().observe(getViewLifecycleOwner(), appIcon::setImageBitmap);
+ TextView title = view.findViewById(R.id.title);
TextView subtitle = view.findViewById(R.id.subtitle);
- innerViewModel.getSubtitle().observe(getViewLifecycleOwner(), subtitle::setText);
-
SeekBar seekBar = view.findViewById(R.id.seek_bar);
- innerViewModel.getMaxProgress().observe(getViewLifecycleOwner(),
- maxProgress -> seekBar.setMax(maxProgress != null ? maxProgress.intValue() : 0));
- innerViewModel.getProgress().observe(getViewLifecycleOwner(),
- progress -> seekBar.setProgress((int) progress.getProgress()));
- innerViewModel.hasTime().observe(getViewLifecycleOwner(),
- hasTime -> seekBar.setVisibility(hasTime ? View.VISIBLE : View.INVISIBLE));
-
TextView time = view.findViewById(R.id.time);
+ TextView timeSeparator = view.findViewById(R.id.time_separator);
+ TextView trackLength = view.findViewById(R.id.track_length);
- innerViewModel.getTimeText().observe(getViewLifecycleOwner(),
- timeText -> time.setText(timeText));
-
- BackgroundImageView albumBackground = view.findViewById(R.id.album_background);
ImageView albumIcon = view.findViewById(R.id.album_art);
- innerViewModel.getAlbumArt().observe(getViewLifecycleOwner(), albumArt -> {
- albumBackground.setBackgroundImage(albumArt, true);
- if (albumArt == null) {
- albumIcon.setImageDrawable(getContext().getDrawable(R.drawable.ic_person));
- } else {
- albumIcon.setImageBitmap(albumArt);
- }
- });
+
+ new MetadataController(
+ getViewLifecycleOwner(),
+ playbackViewModel,
+ title,
+ subtitle,
+ null,
+ null,
+ time,
+ timeSeparator,
+ trackLength,
+ seekBar,
+ albumIcon,
+ Target.SIZE_ORIGINAL
+ );
return view;
}
diff --git a/src/android/car/cluster/MusicFragmentViewModel.java b/src/android/car/cluster/MusicFragmentViewModel.java
index 6923ec3..6e0faef 100644
--- a/src/android/car/cluster/MusicFragmentViewModel.java
+++ b/src/android/car/cluster/MusicFragmentViewModel.java
@@ -15,30 +15,17 @@
*/
package android.car.cluster;
-import static androidx.lifecycle.Transformations.map;
-
-import static com.android.car.arch.common.LiveDataFunctions.combine;
import static com.android.car.arch.common.LiveDataFunctions.mapNonNull;
-import android.annotation.SuppressLint;
import android.app.Application;
import android.graphics.Bitmap;
-import android.media.session.PlaybackState;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
-import com.android.car.media.common.MediaItemMetadata;
-import com.android.car.media.common.playback.AlbumArtLiveData;
-import com.android.car.media.common.playback.PlaybackProgress;
-import com.android.car.media.common.playback.PlaybackViewModel;
import com.android.car.media.common.source.MediaSource;
import com.android.car.media.common.source.MediaSourceViewModel;
-import com.bumptech.glide.request.target.Target;
-
-import java.util.concurrent.TimeUnit;
-
/**
* View model for {@link MusicFragment}
*/
@@ -47,48 +34,21 @@ public final class MusicFragmentViewModel extends AndroidViewModel {
private LiveData<MediaSource> mMediaSource;
private LiveData<CharSequence> mAppName;
private LiveData<Bitmap> mAppIcon;
- private LiveData<CharSequence> mTitle;
- private LiveData<CharSequence> mSubtitle;
- private LiveData<Bitmap> mAlbumArt;
- private LiveData<PlaybackProgress> mProgress;
- private LiveData<Long> mMaxProgress;
- private LiveData<CharSequence> mTimeText;
- private LiveData<Boolean> mHasTime;
- private PlaybackViewModel mPlaybackViewModel;
private MediaSourceViewModel mMediaSourceViewModel;
public MusicFragmentViewModel(Application application) {
super(application);
}
- void init(MediaSourceViewModel mediaSourceViewModel, PlaybackViewModel playbackViewModel) {
- if (mMediaSourceViewModel == mediaSourceViewModel
- && mPlaybackViewModel == playbackViewModel) {
+ void init(MediaSourceViewModel mediaSourceViewModel) {
+ if (mMediaSourceViewModel == mediaSourceViewModel) {
return;
}
- mPlaybackViewModel = playbackViewModel;
mMediaSourceViewModel = mediaSourceViewModel;
mMediaSource = mMediaSourceViewModel.getPrimaryMediaSource();
mAppName = mapNonNull(mMediaSource, MediaSource::getName);
mAppIcon = mapNonNull(mMediaSource, MediaSource::getRoundPackageIcon);
- mTitle = mapNonNull(playbackViewModel.getMetadata(), MediaItemMetadata::getTitle);
- mSubtitle = mapNonNull(playbackViewModel.getMetadata(), MediaItemMetadata::getSubtitle);
- mAlbumArt = AlbumArtLiveData.getAlbumArt(getApplication(),
- Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL, false,
- playbackViewModel.getMetadata());
- mProgress = playbackViewModel.getProgress();
- mMaxProgress = map(playbackViewModel.getPlaybackStateWrapper(),
- state -> state != null ? state.getMaxProgress() : 0L);
- mTimeText = combine(mProgress, mMaxProgress, (progress, maxProgress) -> {
- boolean showHours = TimeUnit.MILLISECONDS.toHours(maxProgress) > 0;
- return String.format("%s / %s",
- formatTime(progress.getProgress(), showHours),
- formatTime(maxProgress, showHours));
- });
- mHasTime = combine(mProgress, mMaxProgress, (progress, maxProgress) ->
- maxProgress > 0
- && progress.getProgress() != PlaybackState.PLAYBACK_POSITION_UNKNOWN);
}
LiveData<CharSequence> getAppName() {
@@ -98,44 +58,4 @@ public final class MusicFragmentViewModel extends AndroidViewModel {
LiveData<Bitmap> getAppIcon() {
return mAppIcon;
}
-
- LiveData<CharSequence> getTitle() {
- return mTitle;
- }
-
- LiveData<CharSequence> getSubtitle() {
- return mSubtitle;
- }
-
- LiveData<Bitmap> getAlbumArt() {
- return mAlbumArt;
- }
-
- LiveData<PlaybackProgress> getProgress() {
- return mProgress;
- }
-
- LiveData<Long> getMaxProgress() {
- return mMaxProgress;
- }
-
- LiveData<CharSequence> getTimeText() {
- return mTimeText;
- }
-
- LiveData<Boolean> hasTime() {
- return mHasTime;
- }
-
- @SuppressLint("DefaultLocale")
- private static String formatTime(long millis, boolean showHours) {
- long hours = TimeUnit.MILLISECONDS.toHours(millis);
- long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) % TimeUnit.HOURS.toMinutes(1);
- long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) % TimeUnit.MINUTES.toSeconds(1);
- if (showHours) {
- return String.format("%d:%02d:%02d", hours, minutes, seconds);
- } else {
- return String.format("%d:%02d", minutes, seconds);
- }
- }
}