Refactor the layout of media route controller dialog
- Apply the UX layout size for the media route control frame and volume layout.
- Remove outer ScrollView.
- Split media route control frame into several views for making easy to handle
the group expansion UX.
- Update play and pause control icons with 48*48 size.
- Make the close button always shown.
Bug: 23117610
Change-Id: I5022a45761c99cc0e046b041e1798740c0adaeb4
diff --git a/v7/mediarouter/res/drawable-hdpi/ic_pause_dark.png b/v7/mediarouter/res/drawable-hdpi/ic_pause_dark.png
index 81c32fe..7192ad4 100644
--- a/v7/mediarouter/res/drawable-hdpi/ic_pause_dark.png
+++ b/v7/mediarouter/res/drawable-hdpi/ic_pause_dark.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-hdpi/ic_pause_light.png b/v7/mediarouter/res/drawable-hdpi/ic_pause_light.png
index 864d8d2..aeb13eb 100644
--- a/v7/mediarouter/res/drawable-hdpi/ic_pause_light.png
+++ b/v7/mediarouter/res/drawable-hdpi/ic_pause_light.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-hdpi/ic_play_dark.png b/v7/mediarouter/res/drawable-hdpi/ic_play_dark.png
index 568ae86..547ef30 100644
--- a/v7/mediarouter/res/drawable-hdpi/ic_play_dark.png
+++ b/v7/mediarouter/res/drawable-hdpi/ic_play_dark.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-hdpi/ic_play_light.png b/v7/mediarouter/res/drawable-hdpi/ic_play_light.png
index e278033..0648523 100644
--- a/v7/mediarouter/res/drawable-hdpi/ic_play_light.png
+++ b/v7/mediarouter/res/drawable-hdpi/ic_play_light.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-mdpi/ic_pause_dark.png b/v7/mediarouter/res/drawable-mdpi/ic_pause_dark.png
index c4218a4..f49aed7 100644
--- a/v7/mediarouter/res/drawable-mdpi/ic_pause_dark.png
+++ b/v7/mediarouter/res/drawable-mdpi/ic_pause_dark.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-mdpi/ic_pause_light.png b/v7/mediarouter/res/drawable-mdpi/ic_pause_light.png
index ab26a30..6708b41 100644
--- a/v7/mediarouter/res/drawable-mdpi/ic_pause_light.png
+++ b/v7/mediarouter/res/drawable-mdpi/ic_pause_light.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-mdpi/ic_play_dark.png b/v7/mediarouter/res/drawable-mdpi/ic_play_dark.png
index 4446faa..a3c80e7 100644
--- a/v7/mediarouter/res/drawable-mdpi/ic_play_dark.png
+++ b/v7/mediarouter/res/drawable-mdpi/ic_play_dark.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-mdpi/ic_play_light.png b/v7/mediarouter/res/drawable-mdpi/ic_play_light.png
index 55b8c5e..8f6a725 100644
--- a/v7/mediarouter/res/drawable-mdpi/ic_play_light.png
+++ b/v7/mediarouter/res/drawable-mdpi/ic_play_light.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-xhdpi/ic_pause_dark.png b/v7/mediarouter/res/drawable-xhdpi/ic_pause_dark.png
index bd7ec0f..660ac65 100644
--- a/v7/mediarouter/res/drawable-xhdpi/ic_pause_dark.png
+++ b/v7/mediarouter/res/drawable-xhdpi/ic_pause_dark.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-xhdpi/ic_pause_light.png b/v7/mediarouter/res/drawable-xhdpi/ic_pause_light.png
index e79d7d7..239b5a8 100644
--- a/v7/mediarouter/res/drawable-xhdpi/ic_pause_light.png
+++ b/v7/mediarouter/res/drawable-xhdpi/ic_pause_light.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-xhdpi/ic_play_dark.png b/v7/mediarouter/res/drawable-xhdpi/ic_play_dark.png
index 9a5d45f..be5c062 100644
--- a/v7/mediarouter/res/drawable-xhdpi/ic_play_dark.png
+++ b/v7/mediarouter/res/drawable-xhdpi/ic_play_dark.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-xhdpi/ic_play_light.png b/v7/mediarouter/res/drawable-xhdpi/ic_play_light.png
index acaeca6..4be0ef3 100644
--- a/v7/mediarouter/res/drawable-xhdpi/ic_play_light.png
+++ b/v7/mediarouter/res/drawable-xhdpi/ic_play_light.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-xxhdpi/ic_pause_dark.png b/v7/mediarouter/res/drawable-xxhdpi/ic_pause_dark.png
index 2a96557..3ea7e03 100644
--- a/v7/mediarouter/res/drawable-xxhdpi/ic_pause_dark.png
+++ b/v7/mediarouter/res/drawable-xxhdpi/ic_pause_dark.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-xxhdpi/ic_pause_light.png b/v7/mediarouter/res/drawable-xxhdpi/ic_pause_light.png
index bf2560f..78456c7 100644
--- a/v7/mediarouter/res/drawable-xxhdpi/ic_pause_light.png
+++ b/v7/mediarouter/res/drawable-xxhdpi/ic_pause_light.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-xxhdpi/ic_play_dark.png b/v7/mediarouter/res/drawable-xxhdpi/ic_play_dark.png
index 1ec1995..2745c3a 100644
--- a/v7/mediarouter/res/drawable-xxhdpi/ic_play_dark.png
+++ b/v7/mediarouter/res/drawable-xxhdpi/ic_play_dark.png
Binary files differ
diff --git a/v7/mediarouter/res/drawable-xxhdpi/ic_play_light.png b/v7/mediarouter/res/drawable-xxhdpi/ic_play_light.png
index a5bd8df..27a0dc0 100644
--- a/v7/mediarouter/res/drawable-xxhdpi/ic_play_light.png
+++ b/v7/mediarouter/res/drawable-xxhdpi/ic_play_light.png
Binary files differ
diff --git a/v7/mediarouter/res/layout/mr_controller_material_dialog_b.xml b/v7/mediarouter/res/layout/mr_controller_material_dialog_b.xml
index d01d251..a4d127d 100644
--- a/v7/mediarouter/res/layout/mr_controller_material_dialog_b.xml
+++ b/v7/mediarouter/res/layout/mr_controller_material_dialog_b.xml
@@ -14,117 +14,61 @@
limitations under the License.
-->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <LinearLayout android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- <LinearLayout android:id="@+id/title_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="24dp"
- android:paddingRight="24dp"
- android:orientation="horizontal" >
- <TextView android:id="@+id/route_name"
- android:layout_width="0dp"
- android:layout_height="72dp"
- android:layout_weight="1"
- android:gravity="center_vertical"
- android:singleLine="true"
- android:ellipsize="end"
- android:textAppearance="?attr/mediaRouteControllerTitleTextStyle" />
- <ImageButton android:id="@+id/close"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:layout_marginLeft="12dp"
- android:layout_gravity="center_vertical"
- android:contentDescription="@string/mr_controller_close_description"
- android:src="?attr/mediaRouteCloseDrawable"
- android:background="?attr/selectableItemBackgroundBorderless" />
- </LinearLayout>
- <FrameLayout android:id="@+id/media_route_control_frame"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" >
- <RelativeLayout android:id="@+id/default_control_frame"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="?attr/colorPrimary">
- <ImageView android:id="@+id/art"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:adjustViewBounds="true"
- android:scaleType="fitCenter"/>
- <ImageButton android:id="@+id/play_pause"
- android:layout_width="48dip"
- android:layout_height="48dip"
- android:padding="12dip"
- android:layout_marginTop="8dip"
- android:layout_marginBottom="8dip"
- android:layout_alignParentRight="true"
- android:layout_below="@id/art"
- android:contentDescription="@string/mr_controller_play"
- android:background="?attr/selectableItemBackgroundBorderless"/>
- <LinearLayout android:orientation="vertical"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:minHeight="64dip"
- android:layout_marginLeft="24dip"
- android:gravity="center_vertical"
- android:layout_toLeftOf="@id/play_pause"
- android:layout_below="@id/art"
- android:layout_alignParentLeft="true" >
- <TextView android:id="@+id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?attr/mediaRouteControllerPrimaryTextStyle"
- android:singleLine="true" />
- <TextView android:id="@+id/subtitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?attr/mediaRouteControllerSecondaryTextStyle"
- android:singleLine="true" />
- </LinearLayout>
- </RelativeLayout>
- </FrameLayout>
- <!-- Optional volume slider section. -->
- <LinearLayout android:id="@+id/media_route_volume_layout"
- android:layout_width="fill_parent"
- android:layout_height="64dp"
- android:gravity="center_vertical"
- android:padding="8dp"
- android:visibility="gone"
- android:background="?attr/colorPrimary">
- <ImageView android:layout_width="48dp"
- android:layout_height="48dp"
- android:src="?attr/mediaRouteCastDrawable"
- android:gravity="center"
- android:scaleType="center" />
- <SeekBar android:id="@+id/media_route_volume_slider"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_marginLeft="8dp"
- android:layout_marginRight="8dp" />
- <ImageButton android:id="@+id/media_route_group_expand_collapse"
- android:layout_width="48dip"
- android:layout_height="48dip"
- android:padding="12dip"
- android:contentDescription="@string/mr_controller_expand_group"
- android:src="?attr/mediaRouteExpandGroupDrawable"
- android:background="?attr/selectableItemBackgroundBorderless"
- android:visibility="gone"/>
- </LinearLayout>
- <ListView android:id="@+id/media_route_volume_group_list"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ <LinearLayout android:id="@+id/title_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="24dp"
+ android:paddingRight="24dp"
+ android:orientation="horizontal" >
+ <TextView android:id="@+id/route_name"
+ android:layout_width="0dp"
+ android:layout_height="72dp"
+ android:layout_weight="1"
+ android:gravity="center_vertical"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:textAppearance="?attr/mediaRouteControllerTitleTextStyle" />
+ <ImageButton android:id="@+id/close"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_marginLeft="12dp"
+ android:layout_gravity="center_vertical"
+ android:contentDescription="@string/mr_controller_close_description"
+ android:src="?attr/mediaRouteCloseDrawable"
+ android:background="?attr/selectableItemBackgroundBorderless" />
+ </LinearLayout>
+ <FrameLayout android:id="@+id/custom_control_frame"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone" />
+ <ImageView android:id="@+id/mr_art"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:adjustViewBounds="true"
+ android:scaleType="fitCenter"
+ android:background="?attr/colorPrimary" />
+ <ListView android:id="@+id/mr_control"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp"
+ android:divider="?attr/colorPrimary"
+ android:dividerHeight="8dp"
+ android:background="?attr/colorPrimary" />
+ <ListView android:id="@+id/mr_volume_group_list"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:background="?attr/colorPrimaryDark"
+ android:visibility="gone" />
+ <LinearLayout android:id="@+id/buttons"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:visibility="gone">
- </ListView>
- <LinearLayout android:id="@+id/buttons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal" >
- <Button android:id="@+id/disconnect"
+ android:orientation="horizontal">
+ <Button android:id="@+id/disconnect"
android:layout_width="0dp"
android:layout_height="48dp"
android:gravity="center"
@@ -132,7 +76,7 @@
android:background="?attr/selectableItemBackgroundBorderless"
android:text="@string/mr_controller_disconnect"
android:visibility="gone" />
- <Button android:id="@+id/stop"
+ <Button android:id="@+id/stop"
android:layout_width="0dp"
android:layout_height="48dp"
android:gravity="center"
@@ -140,6 +84,5 @@
android:textColor="?attr/colorAccent"
android:background="?attr/selectableItemBackgroundBorderless"
android:text="@string/mr_controller_stop" />
- </LinearLayout>
</LinearLayout>
-</ScrollView>
+</LinearLayout>
diff --git a/v7/mediarouter/res/layout/mr_controller_volume_item.xml b/v7/mediarouter/res/layout/mr_controller_volume_item.xml
index d07d94b..8202810 100644
--- a/v7/mediarouter/res/layout/mr_controller_volume_item.xml
+++ b/v7/mediarouter/res/layout/mr_controller_volume_item.xml
@@ -18,24 +18,24 @@
android:layout_width="fill_parent"
android:layout_height="64dp"
android:padding="8dp">
- <TextView android:id="@+id/media_route_name"
+ <TextView android:id="@+id/mr_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" />
- <ImageView android:id="@+id/media_route_volume_item_icon"
+ <ImageView android:id="@+id/mr_volume_item_icon"
android:layout_width="48dp"
android:layout_height="48dp"
- android:layout_below="@id/media_route_name"
+ android:layout_below="@id/mr_name"
android:layout_alignParentLeft="true"
android:src="?attr/mediaRouteAudioTrackDrawable"
android:gravity="center"
android:scaleType="center" />
- <SeekBar android:id="@+id/media_route_volume_slider"
+ <SeekBar android:id="@+id/mr_volume_slider"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_below="@id/media_route_name"
- android:layout_toRightOf="@id/media_route_volume_item_icon"
+ android:layout_below="@id/mr_name"
+ android:layout_toRightOf="@id/mr_volume_item_icon"
android:layout_gravity="center_vertical"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
diff --git a/v7/mediarouter/res/layout/mr_playback_control.xml b/v7/mediarouter/res/layout/mr_playback_control.xml
new file mode 100644
index 0000000..28b2333
--- /dev/null
+++ b/v7/mediarouter/res/layout/mr_playback_control.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:background="?attr/colorPrimary">
+ <ImageButton android:id="@+id/mr_control_play_pause"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="12dp"
+ android:layout_marginRight="12dp"
+ android:layout_alignParentRight="true"
+ android:layout_centerInParent="true"
+ android:contentDescription="@string/mr_controller_play"
+ android:background="?attr/selectableItemBackgroundBorderless"/>
+ <LinearLayout android:orientation="vertical"
+ android:layout_height="fill_parent"
+ android:layout_width="wrap_content"
+ android:layout_marginLeft="24dp"
+ android:layout_alignParentLeft="true"
+ android:layout_toLeftOf="@id/mr_control_play_pause"
+ android:layout_centerInParent="true">
+ <TextView android:id="@+id/mr_control_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?attr/mediaRouteControllerPrimaryTextStyle"
+ android:singleLine="true" />
+ <TextView android:id="@+id/mr_control_subtitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?attr/mediaRouteControllerSecondaryTextStyle"
+ android:singleLine="true" />
+ </LinearLayout>
+</RelativeLayout>
diff --git a/v7/mediarouter/res/layout/mr_volume_control.xml b/v7/mediarouter/res/layout/mr_volume_control.xml
new file mode 100644
index 0000000..18fa7fd
--- /dev/null
+++ b/v7/mediarouter/res/layout/mr_volume_control.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="48dp"
+ android:gravity="center_vertical"
+ android:paddingLeft="24dp"
+ android:paddingRight="24dp"
+ android:background="?attr/colorPrimary">
+ <ImageView android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:src="?attr/mediaRouteCastDrawable"
+ android:gravity="center"
+ android:scaleType="center" />
+ <SeekBar android:id="@+id/mr_volume_slider"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1" />
+ <ImageButton android:id="@+id/mr_group_expand_collapse"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:contentDescription="@string/mr_controller_expand_group"
+ android:src="?attr/mediaRouteExpandGroupDrawable"
+ android:background="?attr/selectableItemBackgroundBorderless"
+ android:visibility="gone"/>
+</LinearLayout>
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java b/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java
index 661c3e6..7bdafe3 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java
@@ -16,8 +16,6 @@
package android.support.v7.app;
-import static android.widget.SeekBar.OnSeekBarChangeListener;
-
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Configuration;
@@ -54,13 +52,17 @@
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
+import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import java.io.BufferedInputStream;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
+import static android.widget.SeekBar.OnSeekBarChangeListener;
+
/**
* This class implements the route controller dialog for {@link MediaRouter}.
* <p>
@@ -92,24 +94,20 @@
private int mDialogWidthLandscape;
private int mDialogPaddingVertical;
- private View mControlView;
+ private View mCustomControlView;
private Button mDisconnectButton;
private Button mStopCastingButton;
- private ImageButton mPlayPauseButton;
private ImageButton mCloseButton;
- private ImageButton mGroupExpandCollapseButton;
+ private FrameLayout mCustomControlFrame;
private ImageView mArtView;
- private TextView mTitleView;
- private TextView mSubtitleView;
- private TextView mRouteNameView;
+ private TextView mRouteNameTextView;
private boolean mVolumeControlEnabled = true;
- private LinearLayout mVolumeLayout;
+ private MediaRouteControlAdapter mControlAdapter;
+ private ListView mControlView;
private ListView mVolumeGroupList;
- private SeekBar mVolumeSlider;
- private boolean mVolumeSliderTouched;
private MediaControllerCompat mMediaController;
private MediaControllerCallback mControllerCallback;
@@ -165,7 +163,7 @@
* @return The media control view, or null if none.
*/
public View getMediaControlView() {
- return mControlView;
+ return mCustomControlView;
}
/**
@@ -179,7 +177,7 @@
if (mVolumeControlEnabled != enable) {
mVolumeControlEnabled = enable;
if (mCreated) {
- updateVolume();
+ mControlAdapter.updateVolumeControl();
}
}
}
@@ -256,92 +254,27 @@
mStopCastingButton = (Button) findViewById(R.id.stop);
mStopCastingButton.setOnClickListener(listener);
+ mRouteNameTextView = (TextView) findViewById(R.id.route_name);
mCloseButton = (ImageButton) findViewById(R.id.close);
mCloseButton.setOnClickListener(listener);
- mArtView = (ImageView) findViewById(R.id.art);
- mTitleView = (TextView) findViewById(R.id.title);
- mSubtitleView = (TextView) findViewById(R.id.subtitle);
- mPlayPauseButton = (ImageButton) findViewById(R.id.play_pause);
- mPlayPauseButton.setOnClickListener(listener);
- mRouteNameView = (TextView) findViewById(R.id.route_name);
- mVolumeLayout = (LinearLayout)findViewById(R.id.media_route_volume_layout);
- mVolumeGroupList = (ListView)findViewById(R.id.media_route_volume_group_list);
+ mCustomControlFrame = (FrameLayout) findViewById(R.id.custom_control_frame);
+ mArtView = (ImageView) findViewById(R.id.mr_art);
- TypedArray styledAttributes = getContext().obtainStyledAttributes(new int[] {
- R.attr.mediaRouteExpandGroupDrawable,
- R.attr.mediaRouteCollapseGroupDrawable
- });
- final Drawable expandGroupDrawable = styledAttributes.getDrawable(0);
- final Drawable collapseGroupDrawable = styledAttributes.getDrawable(1);
- styledAttributes.recycle();
-
- mGroupExpandCollapseButton = (ImageButton)findViewById(
- R.id.media_route_group_expand_collapse);
- mGroupExpandCollapseButton.setOnClickListener(new View.OnClickListener() {
- private boolean mIsExpanded;
-
- @Override
- public void onClick(View v) {
- mIsExpanded = !mIsExpanded;
- if (mIsExpanded) {
- mGroupExpandCollapseButton.setImageDrawable(collapseGroupDrawable);
- mVolumeGroupList.setVisibility(View.VISIBLE);
- mVolumeGroupList.setAdapter(
- new VolumeGroupAdapter(getContext(), getGroup().getRoutes()));
- } else {
- mGroupExpandCollapseButton.setImageDrawable(expandGroupDrawable);
- mVolumeGroupList.setVisibility(View.GONE);
- }
- }
- });
- mVolumeSlider = (SeekBar)findViewById(R.id.media_route_volume_slider);
- mVolumeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
- private final Runnable mStopTrackingTouch = new Runnable() {
- @Override
- public void run() {
- if (mVolumeSliderTouched) {
- mVolumeSliderTouched = false;
- updateVolume();
- }
- }
- };
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- if (mVolumeSliderTouched) {
- mVolumeSlider.removeCallbacks(mStopTrackingTouch);
- } else {
- mVolumeSliderTouched = true;
- }
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- // Defer resetting mVolumeSliderTouched to allow the media route provider
- // a little time to settle into its new state and publish the final
- // volume update.
- mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS);
- }
-
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- if (fromUser) {
- mRoute.requestSetVolume(progress);
- }
- }
- });
+ mControlAdapter = new MediaRouteControlAdapter(
+ getContext(), new ArrayList<View>(), listener);
+ mControlView = (ListView) findViewById(R.id.mr_control);
+ mControlView.setAdapter(mControlAdapter);
+ mVolumeGroupList = (ListView)findViewById(R.id.mr_volume_group_list);
mCreated = true;
- if (update()) {
- mControlView = onCreateMediaControlView(savedInstanceState);
- FrameLayout controlFrame =
- (FrameLayout)findViewById(R.id.media_route_control_frame);
- if (mControlView != null) {
- controlFrame.findViewById(R.id.default_control_frame).setVisibility(View.GONE);
- controlFrame.addView(mControlView);
- }
+ mCustomControlView = onCreateMediaControlView(savedInstanceState);
+ if (mCustomControlView != null) {
+ mCustomControlFrame.addView(mCustomControlView);
+ mCustomControlFrame.setVisibility(View.VISIBLE);
+ mArtView.setVisibility(View.GONE);
}
+ update();
}
/**
@@ -402,108 +335,28 @@
return super.onKeyUp(keyCode, event);
}
- private boolean update() {
+ private void update() {
if (!mRoute.isSelected() || mRoute.isDefault()) {
dismiss();
- return false;
+ return;
}
if (!mCreated) {
- return false;
+ return;
}
- updateVolume();
+ mRouteNameTextView.setText(mRoute.getName());
+ mDisconnectButton.setVisibility(mRoute.canDisconnect() ? View.VISIBLE : View.GONE);
- mRouteNameView.setText(mRoute.getName());
-
- if (mRoute.canDisconnect()) {
- mDisconnectButton.setVisibility(View.VISIBLE);
- } else {
- mDisconnectButton.setVisibility(View.GONE);
- }
-
- if (mRoute.getSettingsIntent() != null) {
- mCloseButton.setVisibility(View.VISIBLE);
- } else {
- mCloseButton.setVisibility(View.GONE);
- }
-
- if (mControlView == null) {
+ if (mCustomControlView == null) {
if (mFetchArtTask != null) {
mFetchArtTask.cancel(true);
}
mArtView.setVisibility(View.GONE);
mFetchArtTask = new FetchArtTask();
mFetchArtTask.execute();
-
- CharSequence title = mDescription == null ? null : mDescription.getTitle();
- boolean hasTitle = !TextUtils.isEmpty(title);
-
- CharSequence subtitle = mDescription == null ? null : mDescription.getSubtitle();
- boolean hasSubtitle = !TextUtils.isEmpty(subtitle);
-
- if (!hasTitle && !hasSubtitle) {
- mTitleView.setText(R.string.mr_controller_no_info_available);
- mTitleView.setEnabled(false);
- mTitleView.setVisibility(View.VISIBLE);
- mSubtitleView.setVisibility(View.GONE);
- } else {
- mTitleView.setText(title);
- mTitleView.setEnabled(hasTitle);
- mTitleView.setVisibility(hasTitle ? View.VISIBLE : View.GONE);
- mSubtitleView.setText(subtitle);
- mSubtitleView.setVisibility(hasSubtitle ? View.VISIBLE : View.GONE);
- }
- if (mState != null) {
- boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_BUFFERING
- || mState.getState() == PlaybackStateCompat.STATE_PLAYING;
- boolean supportsPlay = (mState.getActions() & (PlaybackStateCompat.ACTION_PLAY
- | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0;
- boolean supportsPause = (mState.getActions() & (PlaybackStateCompat.ACTION_PAUSE
- | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0;
- if (isPlaying && supportsPause) {
- mPlayPauseButton.setVisibility(View.VISIBLE);
- mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource(
- getContext(), R.attr.mediaRoutePauseDrawable));
- mPlayPauseButton.setContentDescription(getContext().getResources()
- .getText(R.string.mr_controller_pause));
- } else if (!isPlaying && supportsPlay) {
- mPlayPauseButton.setVisibility(View.VISIBLE);
- mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource(
- getContext(), R.attr.mediaRoutePlayDrawable));
- mPlayPauseButton.setContentDescription(getContext().getResources()
- .getText(R.string.mr_controller_play));
- } else {
- mPlayPauseButton.setVisibility(View.GONE);
- }
- } else {
- mPlayPauseButton.setVisibility(View.GONE);
- }
}
- return true;
- }
-
- private void updateVolume() {
- if (!mVolumeSliderTouched) {
- if (isVolumeControlAvailable()) {
- mVolumeLayout.setVisibility(View.VISIBLE);
- mVolumeSlider.setMax(mRoute.getVolumeMax());
- mVolumeSlider.setProgress(mRoute.getVolume());
- if (USE_GROUP) {
- if (getGroup() == null) {
- mGroupExpandCollapseButton.setVisibility(View.GONE);
- } else {
- mGroupExpandCollapseButton.setVisibility(View.VISIBLE);
- VolumeGroupAdapter adapter =
- (VolumeGroupAdapter) mVolumeGroupList.getAdapter();
- if (adapter != null) {
- adapter.notifyDataSetChanged();
- }
- }
- }
- } else {
- mVolumeLayout.setVisibility(View.GONE);
- }
- }
+ mControlAdapter.updateVolumeControl();
+ mControlAdapter.updatePlaybackControl();
}
private boolean isVolumeControlAvailable() {
@@ -568,7 +421,7 @@
@Override
public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo route) {
if (route == mRoute) {
- updateVolume();
+ mControlAdapter.updateVolumeControl();
}
}
}
@@ -606,7 +459,7 @@
MediaRouter.UNSELECT_REASON_DISCONNECTED);
}
dismiss();
- } else if (id == R.id.play_pause) {
+ } else if (id == R.id.mr_control_play_pause) {
if (mMediaController != null && mState != null) {
if (mState.getState() == PlaybackStateCompat.STATE_PLAYING) {
mMediaController.getTransportControls().pause();
@@ -620,6 +473,190 @@
}
}
+ // TODO: Consider to implement the default controls using LinearLayout instead of ListView.
+ private class MediaRouteControlAdapter extends ArrayAdapter<View> {
+ private List<View> mItemViews;
+
+ private RelativeLayout mPlaybackControl;
+ private TextView mTitleView;
+ private TextView mSubtitleView;
+ private ImageButton mPlayPauseButton;
+
+ private LinearLayout mVolumeControl;
+ private SeekBar mVolumeSlider;
+ private ImageButton mGroupExpandCollapseButton;
+ private boolean mVolumeSliderTouched;
+
+
+ public MediaRouteControlAdapter(Context context, List<View> itemViews,
+ ClickListener listener) {
+ super(context, 0, itemViews);
+ mItemViews = itemViews;
+
+ mPlaybackControl = (RelativeLayout) LayoutInflater.from(context).inflate(
+ R.layout.mr_playback_control, mControlView);
+ mTitleView = (TextView) mPlaybackControl.findViewById(R.id.mr_control_title);
+ mSubtitleView = (TextView) mPlaybackControl.findViewById(R.id.mr_control_subtitle);
+ mPlayPauseButton = (ImageButton) mPlaybackControl.findViewById(
+ R.id.mr_control_play_pause);
+ mPlayPauseButton.setOnClickListener(listener);
+
+ mVolumeControl = (LinearLayout) LayoutInflater.from(context).inflate(
+ R.layout.mr_volume_control, mControlView);
+ mVolumeSlider = (SeekBar) mVolumeControl.findViewById(R.id.mr_volume_slider);
+ mVolumeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ private final Runnable mStopTrackingTouch = new Runnable() {
+ @Override
+ public void run() {
+ if (mVolumeSliderTouched) {
+ mVolumeSliderTouched = false;
+ updateVolumeControl();
+ }
+ }
+ };
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ if (mVolumeSliderTouched) {
+ mVolumeSlider.removeCallbacks(mStopTrackingTouch);
+ } else {
+ mVolumeSliderTouched = true;
+ }
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ // Defer resetting mVolumeSliderTouched to allow the media route provider
+ // a little time to settle into its new state and publish the final
+ // volume update.
+ mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS);
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (fromUser) {
+ mRoute.requestSetVolume(progress);
+ }
+ }
+ });
+
+ TypedArray styledAttributes = context.obtainStyledAttributes(new int[] {
+ R.attr.mediaRouteExpandGroupDrawable,
+ R.attr.mediaRouteCollapseGroupDrawable
+ });
+ final Drawable expandGroupDrawable = styledAttributes.getDrawable(0);
+ final Drawable collapseGroupDrawable = styledAttributes.getDrawable(1);
+ styledAttributes.recycle();
+
+ mGroupExpandCollapseButton = (ImageButton) mVolumeControl.findViewById(
+ R.id.mr_group_expand_collapse);
+ mGroupExpandCollapseButton.setOnClickListener(new View.OnClickListener() {
+ private boolean mIsExpanded;
+
+ @Override
+ public void onClick(View v) {
+ mIsExpanded = !mIsExpanded;
+ if (mIsExpanded) {
+ mGroupExpandCollapseButton.setImageDrawable(collapseGroupDrawable);
+ mVolumeGroupList.setVisibility(View.VISIBLE);
+ mVolumeGroupList.setAdapter(
+ new VolumeGroupAdapter(getContext(), getGroup().getRoutes()));
+ } else {
+ mGroupExpandCollapseButton.setImageDrawable(expandGroupDrawable);
+ mVolumeGroupList.setVisibility(View.GONE);
+ }
+ }
+ });
+ }
+
+ @Override
+ public View getView(final int position, View convertView, ViewGroup parent) {
+ return mItemViews.get(position);
+ }
+
+ public void updateVolumeControl() {
+ if (!mVolumeSliderTouched) {
+ if (isVolumeControlAvailable()) {
+ if (!mItemViews.contains(mVolumeControl)) {
+ mItemViews.add(mVolumeControl);
+
+ notifyDataSetChanged();
+ }
+ mVolumeSlider.setMax(mRoute.getVolumeMax());
+ mVolumeSlider.setProgress(mRoute.getVolume());
+ if (USE_GROUP) {
+ if (getGroup() == null) {
+ mGroupExpandCollapseButton.setVisibility(View.GONE);
+ } else {
+ mGroupExpandCollapseButton.setVisibility(View.VISIBLE);
+ VolumeGroupAdapter adapter =
+ (VolumeGroupAdapter) mVolumeGroupList.getAdapter();
+ if (adapter != null) {
+ adapter.notifyDataSetChanged();
+ }
+ }
+ }
+ } else if (mItemViews.contains(mVolumeControl)) {
+ mItemViews.remove(mVolumeControl);
+ notifyDataSetChanged();
+ }
+ }
+ }
+
+ public void updatePlaybackControl() {
+ if (mCustomControlView == null) {
+ if (!mItemViews.contains(mPlaybackControl)) {
+ mItemViews.add(0, mPlaybackControl);
+ notifyDataSetChanged();
+ }
+ CharSequence title = mDescription == null ? null : mDescription.getTitle();
+ boolean hasTitle = !TextUtils.isEmpty(title);
+
+ CharSequence subtitle = mDescription == null ? null : mDescription.getSubtitle();
+ boolean hasSubtitle = !TextUtils.isEmpty(subtitle);
+
+ if (!hasTitle && !hasSubtitle) {
+ mTitleView.setText(R.string.mr_controller_no_info_available);
+ mTitleView.setEnabled(false);
+ mTitleView.setVisibility(View.VISIBLE);
+ mSubtitleView.setVisibility(View.GONE);
+ } else {
+ mTitleView.setText(title);
+ mTitleView.setEnabled(hasTitle);
+ mTitleView.setVisibility(hasTitle ? View.VISIBLE : View.GONE);
+ mSubtitleView.setText(subtitle);
+ mSubtitleView.setVisibility(hasSubtitle ? View.VISIBLE : View.GONE);
+ }
+ if (mState != null) {
+ boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_BUFFERING
+ || mState.getState() == PlaybackStateCompat.STATE_PLAYING;
+ boolean supportsPlay = (mState.getActions() & (PlaybackStateCompat.ACTION_PLAY
+ | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0;
+ boolean supportsPause = (mState.getActions() & (PlaybackStateCompat.ACTION_PAUSE
+ | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0;
+ if (isPlaying && supportsPause) {
+ mPlayPauseButton.setVisibility(View.VISIBLE);
+ mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource(
+ getContext(), R.attr.mediaRoutePauseDrawable));
+ mPlayPauseButton.setContentDescription(getContext().getResources()
+ .getText(R.string.mr_controller_pause));
+ } else if (!isPlaying && supportsPlay) {
+ mPlayPauseButton.setVisibility(View.VISIBLE);
+ mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource(
+ getContext(), R.attr.mediaRoutePlayDrawable));
+ mPlayPauseButton.setContentDescription(getContext().getResources()
+ .getText(R.string.mr_controller_play));
+ } else {
+ mPlayPauseButton.setVisibility(View.GONE);
+ }
+ }
+ } else if (mItemViews.contains(mPlaybackControl)) {
+ mItemViews.remove(mPlaybackControl);
+ notifyDataSetChanged();
+ }
+ }
+ }
+
private class VolumeGroupAdapter extends ArrayAdapter<MediaRouter.RouteInfo> {
final static float DISABLED_ALPHA = .3f;
@@ -658,11 +695,11 @@
if (route != null) {
boolean isEnabled = route.isEnabled();
- TextView routeName = (TextView) v.findViewById(R.id.media_route_name);
+ TextView routeName = (TextView) v.findViewById(R.id.mr_name);
routeName.setEnabled(isEnabled);
routeName.setText(route.getName());
- SeekBar volumeSlider = (SeekBar) v.findViewById(R.id.media_route_volume_slider);
+ SeekBar volumeSlider = (SeekBar) v.findViewById(R.id.mr_volume_slider);
volumeSlider.setEnabled(isEnabled);
volumeSlider.setTag(position);
if (isEnabled) {
@@ -683,7 +720,7 @@
// }
ImageView volumeItemIcon =
- (ImageView) v.findViewById(R.id.media_route_volume_item_icon);
+ (ImageView) v.findViewById(R.id.mr_volume_item_icon);
volumeItemIcon.setAlpha(isEnabled ? 255 : (int)(255 * DISABLED_ALPHA));
}
return v;