diff options
author | linus_lee <llee@cyngn.com> | 2014-08-21 18:52:12 -0700 |
---|---|---|
committer | linus_lee <llee@cyngn.com> | 2014-11-20 11:58:47 -0800 |
commit | 5d1b17921ef3f60e1ce58c6b64664e34ddf9b972 (patch) | |
tree | 9ba6cd147dbeba14bef4ec626ab2cf235fb489b3 | |
parent | b6facc786099a943f8269426355c62462174f61f (diff) | |
download | android_packages_apps_Eleven-5d1b17921ef3f60e1ce58c6b64664e34ddf9b972.tar.gz android_packages_apps_Eleven-5d1b17921ef3f60e1ce58c6b64664e34ddf9b972.tar.bz2 android_packages_apps_Eleven-5d1b17921ef3f60e1ce58c6b64664e34ddf9b972.zip |
Eleven: Add two sliding panels to the player
This does most of the work to change the player activity to a fragment
and integrate the sliding panel logic. Since this is a pretty large change
I'll be checking this piece in first and then continue to hook up the remaining pieces
Change-Id: Ibc8ee392a939a4a965a3164558ccf075b4d35567
22 files changed, 690 insertions, 628 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index f77b0c5..81c2a54 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -61,7 +61,10 @@ <!-- Main activity --> <activity android:name=".ui.activities.HomeActivity" - android:windowSoftInputMode="adjustPan" > + android:windowSoftInputMode="adjustPan" + android:launchMode="singleTask" + android:exported="true" + android:theme="@style/Eleven.Theme.ActionBar.Overlay"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MUSIC_PLAYER" /> @@ -70,14 +73,7 @@ <category android:name="android.intent.category.APP_MUSIC" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> - </activity> - <!-- Now playing --> - <activity - android:name=".ui.activities.AudioPlayerActivity" - android:clearTaskOnLaunch="true" - android:exported="true" - android:launchMode="singleTask" - android:windowSoftInputMode="adjustPan" > + <intent-filter> <action android:name="android.intent.action.VIEW" /> @@ -169,7 +165,7 @@ <activity android:name=".ui.activities.SettingsActivity" android:label="@string/menu_settings" - android:theme="@style/Apollo.Theme.Dark" /> + android:theme="@style/Eleven.Theme" /> <!-- Themes Activity --> <activity android:name=".ui.activities.ThemesActivity" diff --git a/res/drawable-xhdpi/btn_header_collapse.png b/res/drawable-xhdpi/btn_header_collapse.png Binary files differnew file mode 100644 index 0000000..5dfcf1c --- /dev/null +++ b/res/drawable-xhdpi/btn_header_collapse.png diff --git a/res/drawable-xhdpi/drag_indicator.png b/res/drawable-xhdpi/drag_indicator.png Binary files differnew file mode 100644 index 0000000..6f32fdf --- /dev/null +++ b/res/drawable-xhdpi/drag_indicator.png diff --git a/res/layout/activity_base.xml b/res/layout/activity_base.xml index a0529b0..130a8e5 100644 --- a/res/layout/activity_base.xml +++ b/res/layout/activity_base.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2012 Andrew Neal Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,14 +16,91 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical" > + android:orientation="vertical"> - <FrameLayout - android:id="@+id/activity_base_content" + <com.cyngn.eleven.slidinguppanel.SlidingUpPanelLayout + xmlns:sothree="http://schemas.android.com/apk/res-auto" + android:id="@+id/sliding_layout" android:layout_width="match_parent" - android:layout_height="0dip" - android:layout_weight="1" /> + android:layout_height="match_parent" + android:gravity="bottom" + sothree:panelHeight="@dimen/bottom_action_bar_height" + sothree:slidePanelOffset="@dimen/bottom_action_bar_height" + sothree:dragView="@+id/firstPanelDragArea"> - <include layout="@layout/bottom_action_bar"/> + <FrameLayout + android:id="@+id/activity_base_content" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingTop="?android:attr/actionBarSize" /> + <com.cyngn.eleven.slidinguppanel.SlidingUpPanelLayout + xmlns:sothree="http://schemas.android.com/apk/res-auto" + android:id="@+id/sliding_layout2" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="bottom" + sothree:directOffset="true" + sothree:panelHeight="@dimen/sliding_panel_indicator_height" + sothree:dragView="@+id/secondPanelDragArea"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/panel_background_color" + android:orientation="vertical"> + + <LinearLayout + android:id="@+id/firstPanelDragArea" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <include layout="@layout/bottom_action_bar" /> + + <include + android:id="@+id/firstHeaderBar" + layout="@layout/header_bar" /> + + <FrameLayout + android:id="@+id/audioPlayerFragment" + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1" /> + </LinearLayout> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/panel_background_color" + android:orientation="vertical"> + + <LinearLayout + android:id="@+id/secondPanelDragArea" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <ImageView + android:id="@+id/secondPanelDragIndicator" + android:layout_width="wrap_content" + android:layout_height="@dimen/sliding_panel_indicator_height" + android:layout_gravity="center_horizontal" + android:scaleType="centerInside" + android:src="@drawable/drag_indicator" /> + + <include + android:id="@+id/secondHeaderBar" + layout="@layout/header_bar" /> + </LinearLayout> + + <FrameLayout + android:id="@+id/queueFragment" + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1" /> + </LinearLayout> + </com.cyngn.eleven.slidinguppanel.SlidingUpPanelLayout> + </com.cyngn.eleven.slidinguppanel.SlidingUpPanelLayout> </LinearLayout>
\ No newline at end of file diff --git a/res/layout/activity_player_base.xml b/res/layout/activity_player_base.xml deleted file mode 100644 index 66e2e53..0000000 --- a/res/layout/activity_player_base.xml +++ /dev/null @@ -1,201 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2012 Andrew Neal - - 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. ---> -<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" > - - <RelativeLayout - android:layout_width="match_parent" - android:layout_height="match_parent" > - - <View - android:id="@+id/audio_player_footer" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_alignParentBottom="true" - android:layout_alignTop="@android:id/progress" /> - - <LinearLayout - android:id="@+id/audio_player_header" - android:layout_width="match_parent" - android:layout_height="@dimen/audio_player_header_height" - android:layout_alignParentTop="true" - android:baselineAligned="false" - android:orientation="horizontal" > - - <LinearLayout - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_gravity="center_vertical" - android:layout_weight="1" - android:orientation="vertical" - android:paddingLeft="@dimen/audio_player_header_padding_left" - android:paddingRight="@dimen/audio_player_header_padding_right" > - - <TextView - android:id="@+id/audio_player_track_name" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:ellipsize="end" - android:singleLine="true" - android:textSize="@dimen/text_size_medium" - android:textStyle="bold" /> - - <TextView - android:id="@+id/audio_player_artist_name" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:ellipsize="end" - android:singleLine="true" - android:textSize="@dimen/text_size_medium" /> - </LinearLayout> - - <FrameLayout - android:id="@+id/audio_player_switch" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:clickable="true" - android:focusable="true" - android:padding="@dimen/audio_player_switch_padding" > - - <com.cyngn.eleven.widgets.SquareImageView - android:id="@+id/audio_player_switch_queue" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:contentDescription="@null" /> - - <com.cyngn.eleven.widgets.SquareImageView - android:id="@+id/audio_player_switch_album_art" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:visibility="invisible" /> - </FrameLayout> - </LinearLayout> - - <RelativeLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_above="@android:id/progress" - android:layout_alignParentLeft="true" - android:layout_alignParentRight="true" - android:layout_below="@+id/audio_player_header" > - - <com.cyngn.eleven.widgets.SquareImageView - android:id="@+id/audio_player_album_art" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_centerHorizontal="true" - android:scaleType="fitXY" /> - - <View - android:id="@+id/audio_player_footer_two" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_alignParentBottom="true" - android:layout_below="@+id/audio_player_album_art" /> - - <ImageView - android:layout_width="match_parent" - android:layout_height="@dimen/shadow_height" - android:layout_alignTop="@+id/audio_player_album_art" - android:contentDescription="@null" - android:src="@drawable/top_shadow" /> - - <ImageView - android:layout_width="match_parent" - android:layout_height="@dimen/shadow_height" - android:layout_alignBottom="@+id/audio_player_album_art" - android:contentDescription="@null" - android:src="@drawable/bottom_shadow" /> - - <FrameLayout - android:id="@+id/audio_player_pager_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_alignBottom="@+id/audio_player_album_art" - android:visibility="invisible" > - - <android.support.v4.view.ViewPager - android:id="@+id/audio_player_pager" - android:layout_width="match_parent" - android:layout_height="match_parent" /> - - <ImageView - android:layout_width="match_parent" - android:layout_height="@dimen/shadow_height" - android:layout_gravity="top" - android:contentDescription="@null" - android:src="@drawable/top_shadow" /> - - <ImageView - android:layout_width="match_parent" - android:layout_height="@dimen/shadow_height" - android:layout_gravity="bottom" - android:contentDescription="@null" - android:src="@drawable/bottom_shadow" /> - </FrameLayout> - </RelativeLayout> - - <TextView - android:id="@+id/audio_player_current_time" - android:layout_width="@dimen/audio_player_time_width" - android:layout_height="wrap_content" - android:layout_alignBottom="@android:id/progress" - android:layout_alignParentLeft="true" - android:layout_alignTop="@android:id/progress" - android:gravity="center" - android:textSize="@dimen/text_size_micro" /> - - <TextView - android:id="@+id/audio_player_total_time" - android:layout_width="@dimen/audio_player_time_width" - android:layout_height="wrap_content" - android:layout_alignBottom="@android:id/progress" - android:layout_alignParentRight="true" - android:layout_alignTop="@android:id/progress" - android:gravity="center" - android:textSize="@dimen/text_size_micro" /> - - <SeekBar - android:id="@android:id/progress" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_above="@+id/audio_player_controlss" - android:layout_marginBottom="@dimen/audio_player_seek_bar_margin_bottom" - android:layout_toLeftOf="@+id/audio_player_total_time" - android:layout_toRightOf="@+id/audio_player_current_time" - android:max="1000" - android:thumb="@null" /> - - <LinearLayout - android:id="@+id/audio_player_controlss" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_alignParentBottom="true" - android:layout_alignParentLeft="true" - android:layout_alignParentRight="true" - android:baselineAligned="false" - android:gravity="center" > - - <include layout="@layout/audio_player_controls" /> - </LinearLayout> - </RelativeLayout> - - <include layout="@layout/colorstrip" /> - -</FrameLayout>
\ No newline at end of file diff --git a/res/layout/activity_player_fragment.xml b/res/layout/activity_player_fragment.xml new file mode 100644 index 0000000..a273c06 --- /dev/null +++ b/res/layout/activity_player_fragment.xml @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2012 Andrew Neal + + 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. +--> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" > + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <RelativeLayout + android:id="@+id/album_art_section" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_above="@android:id/progress" + android:layout_alignParentLeft="true" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true" > + + <com.cyngn.eleven.widgets.SquareImageView + android:id="@+id/audio_player_album_art" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_centerHorizontal="true" + android:scaleType="fitXY" /> + + <ImageView + android:layout_width="match_parent" + android:layout_height="@dimen/shadow_height" + android:layout_alignTop="@+id/audio_player_album_art" + android:contentDescription="@null" + android:src="@drawable/top_shadow" /> + + <ImageView + android:layout_width="match_parent" + android:layout_height="@dimen/shadow_height" + android:layout_alignBottom="@+id/audio_player_album_art" + android:contentDescription="@null" + android:src="@drawable/bottom_shadow" /> + + </RelativeLayout> + + <LinearLayout + android:id="@+id/audio_player_header" + android:layout_width="match_parent" + android:layout_height="@dimen/audio_player_header_height" + android:baselineAligned="false" + android:orientation="horizontal"> + + <!-- TODO: Add + Icon --> + <LinearLayout + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_weight="1" + android:orientation="vertical"> + + <TextView + android:id="@+id/audio_player_track_name" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + android:ellipsize="end" + android:singleLine="true" + android:textSize="@dimen/text_size_medium" + android:textStyle="bold" /> + + <TextView + android:id="@+id/audio_player_artist_name" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + android:ellipsize="end" + android:singleLine="true" + android:textSize="@dimen/text_size_medium" /> + </LinearLayout> + <!-- TODO: Add ... Icon --> + </LinearLayout> + + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <TextView + android:id="@+id/audio_player_current_time" + android:layout_width="@dimen/audio_player_time_width" + android:layout_height="wrap_content" + android:layout_alignBottom="@android:id/progress" + android:layout_alignParentLeft="true" + android:layout_alignTop="@android:id/progress" + android:gravity="center" + android:textSize="@dimen/text_size_micro" /> + + <TextView + android:id="@+id/audio_player_total_time" + android:layout_width="@dimen/audio_player_time_width" + android:layout_height="wrap_content" + android:layout_alignBottom="@android:id/progress" + android:layout_alignParentRight="true" + android:layout_alignTop="@android:id/progress" + android:gravity="center" + android:textSize="@dimen/text_size_micro" /> + + <SeekBar + android:id="@android:id/progress" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_above="@+id/audio_player_controlss" + android:layout_marginBottom="@dimen/audio_player_seek_bar_margin_bottom" + android:layout_toLeftOf="@+id/audio_player_total_time" + android:layout_toRightOf="@+id/audio_player_current_time" + android:max="1000" + android:thumb="@null" /> + + <LinearLayout + android:id="@+id/audio_player_controlss" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:layout_alignParentLeft="true" + android:layout_alignParentRight="true" + android:baselineAligned="false" + android:gravity="center" > + + <include layout="@layout/audio_player_controls" /> + </LinearLayout> + </RelativeLayout> + </LinearLayout> +</FrameLayout>
\ No newline at end of file diff --git a/res/layout/header_bar.xml b/res/layout/header_bar.xml new file mode 100644 index 0000000..a79b1b6 --- /dev/null +++ b/res/layout/header_bar.xml @@ -0,0 +1,28 @@ +<!-- + Copyright (C) 2014 Cyanogen, Inc. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="?android:attr/actionBarSize" + android:enabled="false" + android:gravity="center_vertical" + android:orientation="horizontal" + android:background="@color/header_action_bar_color"> + + <ImageView + android:id="@+id/header_bar_up" + android:layout_width="@dimen/header_bar_up_width" + android:layout_height="@dimen/header_bar_up_height" + android:padding="@dimen/header_bar_up_padding" + android:src="@drawable/btn_header_collapse"/> + + <TextView + android:id="@+id/header_bar_title" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:ellipsize="end" + android:singleLine="true" + android:textSize="@dimen/text_size_x_large" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 4e27b72..c3802b9 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -16,8 +16,10 @@ <resources> <declare-styleable name="SlidingUpPanelLayout"> <attr name="panelHeight" format="dimension" /> + <attr name="slidePanelOffset" format="dimension" /> <attr name="shadowHeight" format="dimension" /> <attr name="paralaxOffset" format="dimension" /> + <attr name="directOffset" format="boolean" /> <attr name="fadeColor" format="color" /> <attr name="flingVelocity" format="integer" /> <attr name="dragView" format="reference" /> diff --git a/res/values/colors.xml b/res/values/colors.xml index b3dfb81..dc994ce 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -57,4 +57,10 @@ <!-- A dark Holo shade of orange --> <color name="holo_orange_dark">#ffff8800</color> + <!-- Color for the header action bar --> + <color name="header_action_bar_color">#ff444444</color> + + <!-- Color for backgrounds of panels --> + <color name="panel_background_color">#ff000000</color> + </resources> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index d0a2de2..c651913 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -119,4 +119,11 @@ <!-- Color scheme dialog --> <dimen name="color_scheme_dialog_row_padding">8.0dip</dimen> + <!-- Sliding Panel --> + <dimen name="sliding_panel_indicator_height">25.0dip</dimen> + + <!-- Header Bar --> + <dimen name="header_bar_up_width">50.0dip</dimen> + <dimen name="header_bar_up_height">50.0dip</dimen> + <dimen name="header_bar_up_padding">8.0dip</dimen> </resources> diff --git a/res/values/strings.xml b/res/values/strings.xml index 0635eb3..85c1b44 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -26,6 +26,8 @@ <string name="page_songs">Songs</string> <string name="page_playlists">Playlists</string> <string name="page_genres">Genres</string> + <string name="page_now_playing">NOW PLAYING</string> + <string name="page_play_queue">PLAY QUEUE</string> <!-- Option menu items --> <string name="menu_settings">Settings</string> diff --git a/res/values/styles.xml b/res/values/styles.xml index 9b36fbf..7160dee 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -16,13 +16,12 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Main Holo --> - <style name="Apollo.Theme.Dark" parent="@android:style/Theme.Holo"> + <style name="Eleven.Theme" parent="@android:style/Theme.DeviceDefault"> <item name="android:windowContentOverlay">@null</item> </style> - <!-- Main Holo light --> - <style name="Apollo.Theme.Light" parent="@android:style/Theme.Holo.Light"> - <item name="android:windowContentOverlay">@null</item> + <style name="Eleven.Theme.ActionBar.Overlay" parent="@style/Eleven.Theme"> + <item name="android:windowActionBarOverlay">true</item> </style> <!-- Shortcut Activity theme --> diff --git a/src/com/cyngn/eleven/appwidgets/AppWidgetLarge.java b/src/com/cyngn/eleven/appwidgets/AppWidgetLarge.java index 54be883..4cdc851 100644 --- a/src/com/cyngn/eleven/appwidgets/AppWidgetLarge.java +++ b/src/com/cyngn/eleven/appwidgets/AppWidgetLarge.java @@ -22,7 +22,7 @@ import android.widget.RemoteViews; import com.cyngn.eleven.MusicPlaybackService; import com.cyngn.eleven.R; -import com.cyngn.eleven.ui.activities.AudioPlayerActivity; +import com.cyngn.eleven.ui.fragments.AudioPlayerFragment; import com.cyngn.eleven.ui.activities.HomeActivity; import com.cyngn.eleven.utils.ApolloUtils; @@ -150,7 +150,7 @@ public class AppWidgetLarge extends AppWidgetBase { * Link up various button actions using {@link PendingIntents}. * * @param playerActive True if player is active in background, which means - * widget click will launch {@link AudioPlayerActivity}, + * widget click will launch {@link AudioPlayerFragment}, * otherwise we launch {@link MusicBrowserActivity}. */ private void linkButtons(final Context context, final RemoteViews views, @@ -162,13 +162,15 @@ public class AppWidgetLarge extends AppWidgetBase { // Now playing if (playerActive) { - action = new Intent(context, AudioPlayerActivity.class); + action = new Intent(context, HomeActivity.class); + action.setAction(HomeActivity.ACTION_VIEW_MUSIC_PLAYER); pendingIntent = PendingIntent.getActivity(context, 0, action, 0); views.setOnClickPendingIntent(R.id.app_widget_large_info_container, pendingIntent); views.setOnClickPendingIntent(R.id.app_widget_large_image, pendingIntent); } else { // Home action = new Intent(context, HomeActivity.class); + action.setAction(HomeActivity.ACTION_VIEW_BROWSE); pendingIntent = PendingIntent.getActivity(context, 0, action, 0); views.setOnClickPendingIntent(R.id.app_widget_large_info_container, pendingIntent); views.setOnClickPendingIntent(R.id.app_widget_large_image, pendingIntent); diff --git a/src/com/cyngn/eleven/appwidgets/AppWidgetLargeAlternate.java b/src/com/cyngn/eleven/appwidgets/AppWidgetLargeAlternate.java index a6354a5..729f7a0 100644 --- a/src/com/cyngn/eleven/appwidgets/AppWidgetLargeAlternate.java +++ b/src/com/cyngn/eleven/appwidgets/AppWidgetLargeAlternate.java @@ -22,7 +22,7 @@ import android.widget.RemoteViews; import com.cyngn.eleven.MusicPlaybackService; import com.cyngn.eleven.R; -import com.cyngn.eleven.ui.activities.AudioPlayerActivity; +import com.cyngn.eleven.ui.fragments.AudioPlayerFragment; import com.cyngn.eleven.ui.activities.HomeActivity; import com.cyngn.eleven.utils.ApolloUtils; @@ -185,7 +185,7 @@ public class AppWidgetLargeAlternate extends AppWidgetBase { * Link up various button actions using {@link PendingIntents}. * * @param playerActive True if player is active in background, which means - * widget click will launch {@link AudioPlayerActivity}, + * widget click will launch {@link AudioPlayerFragment}, * otherwise we launch {@link MusicBrowserActivity}. */ private void linkButtons(final Context context, final RemoteViews views, @@ -197,7 +197,8 @@ public class AppWidgetLargeAlternate extends AppWidgetBase { // Now playing if (playerActive) { - action = new Intent(context, AudioPlayerActivity.class); + action = new Intent(context, HomeActivity.class); + action.setAction(HomeActivity.ACTION_VIEW_MUSIC_PLAYER); pendingIntent = PendingIntent.getActivity(context, 0, action, 0); views.setOnClickPendingIntent(R.id.app_widget_large_alternate_info_container, pendingIntent); @@ -205,6 +206,7 @@ public class AppWidgetLargeAlternate extends AppWidgetBase { } else { // Home action = new Intent(context, HomeActivity.class); + action.setAction(HomeActivity.ACTION_VIEW_BROWSE); pendingIntent = PendingIntent.getActivity(context, 0, action, 0); views.setOnClickPendingIntent(R.id.app_widget_large_alternate_info_container, pendingIntent); diff --git a/src/com/cyngn/eleven/appwidgets/AppWidgetSmall.java b/src/com/cyngn/eleven/appwidgets/AppWidgetSmall.java index 368f223..4c34542 100644 --- a/src/com/cyngn/eleven/appwidgets/AppWidgetSmall.java +++ b/src/com/cyngn/eleven/appwidgets/AppWidgetSmall.java @@ -24,7 +24,7 @@ import android.widget.RemoteViews; import com.cyngn.eleven.MusicPlaybackService; import com.cyngn.eleven.R; -import com.cyngn.eleven.ui.activities.AudioPlayerActivity; +import com.cyngn.eleven.ui.fragments.AudioPlayerFragment; import com.cyngn.eleven.ui.activities.HomeActivity; import com.cyngn.eleven.utils.ApolloUtils; @@ -156,7 +156,7 @@ public class AppWidgetSmall extends AppWidgetBase { * Link up various button actions using {@link PendingIntents}. * * @param playerActive True if player is active in background, which means - * widget click will launch {@link AudioPlayerActivity}, + * widget click will launch {@link AudioPlayerFragment}, * otherwise we launch {@link MusicBrowserActivity}. */ private void linkButtons(final Context context, final RemoteViews views, @@ -168,13 +168,15 @@ public class AppWidgetSmall extends AppWidgetBase { // Now playing if (playerActive) { - action = new Intent(context, AudioPlayerActivity.class); + action = new Intent(context, HomeActivity.class); + action.setAction(HomeActivity.ACTION_VIEW_MUSIC_PLAYER); pendingIntent = PendingIntent.getActivity(context, 0, action, 0); views.setOnClickPendingIntent(R.id.app_widget_small_info_container, pendingIntent); views.setOnClickPendingIntent(R.id.app_widget_small_image, pendingIntent); } else { // Home action = new Intent(context, HomeActivity.class); + action.setAction(HomeActivity.ACTION_VIEW_BROWSE); pendingIntent = PendingIntent.getActivity(context, 0, action, 0); views.setOnClickPendingIntent(R.id.app_widget_small_info_container, pendingIntent); views.setOnClickPendingIntent(R.id.app_widget_small_image, pendingIntent); diff --git a/src/com/cyngn/eleven/appwidgets/RecentWidgetProvider.java b/src/com/cyngn/eleven/appwidgets/RecentWidgetProvider.java index 9a80489..6d38a4f 100644 --- a/src/com/cyngn/eleven/appwidgets/RecentWidgetProvider.java +++ b/src/com/cyngn/eleven/appwidgets/RecentWidgetProvider.java @@ -28,7 +28,7 @@ import android.widget.RemoteViews; import com.cyngn.eleven.Config; import com.cyngn.eleven.MusicPlaybackService; import com.cyngn.eleven.R; -import com.cyngn.eleven.ui.activities.AudioPlayerActivity; +import com.cyngn.eleven.ui.fragments.AudioPlayerFragment; import com.cyngn.eleven.ui.activities.HomeActivity; import com.cyngn.eleven.ui.activities.ProfileActivity; import com.cyngn.eleven.ui.activities.ShortcutActivity; @@ -245,7 +245,7 @@ public class RecentWidgetProvider extends AppWidgetBase { * Link up various button actions using {@link PendingIntents}. * * @param playerActive True if player is active in background, which means - * widget click will launch {@link AudioPlayerActivity}, + * widget click will launch {@link AudioPlayerFragment}, * otherwise we launch {@link MusicBrowserActivity}. */ private void linkButtons(final Context context, final RemoteViews views, @@ -257,12 +257,14 @@ public class RecentWidgetProvider extends AppWidgetBase { // Now playing if (playerActive) { - action = new Intent(context, AudioPlayerActivity.class); + action = new Intent(context, HomeActivity.class); + action.setAction(HomeActivity.ACTION_VIEW_MUSIC_PLAYER); pendingIntent = PendingIntent.getActivity(context, 0, action, 0); views.setOnClickPendingIntent(R.id.app_widget_recents_action_bar, pendingIntent); } else { // Home action = new Intent(context, HomeActivity.class); + action.setAction(HomeActivity.ACTION_VIEW_BROWSE); pendingIntent = PendingIntent.getActivity(context, 0, action, 0); views.setOnClickPendingIntent(R.id.app_widget_recents_action_bar, pendingIntent); } diff --git a/src/com/cyngn/eleven/slidinguppanel/SlidingUpPanelLayout.java b/src/com/cyngn/eleven/slidinguppanel/SlidingUpPanelLayout.java index 2ebc942..49f7f0b 100644 --- a/src/com/cyngn/eleven/slidinguppanel/SlidingUpPanelLayout.java +++ b/src/com/cyngn/eleven/slidinguppanel/SlidingUpPanelLayout.java @@ -83,6 +83,16 @@ public class SlidingUpPanelLayout extends ViewGroup { private static final int DEFAULT_PARALAX_OFFSET = 0; /** + * Default slide panel offset when collapsed + */ + private static final int DEFAULT_SLIDE_PANEL_OFFSET = 0; + + /** + * Default direct offset flag + */ + private static final boolean DEFAULT_DIRECT_OFFSET_FLAG = false; + + /** * The paint used to dim the main layout when sliding */ private final Paint mCoveredFadePaint = new Paint(); @@ -98,6 +108,11 @@ public class SlidingUpPanelLayout extends ViewGroup { private int mPanelHeight = -1; /** + * Determines how much to slide the panel off when expanded + */ + private int mSlidePanelOffset = 0; + + /** * The size of the shadow in pixels. */ private int mShadowHeight = -1; @@ -108,6 +123,11 @@ public class SlidingUpPanelLayout extends ViewGroup { private int mParallaxOffset = -1; /** + * Clamps the Main view to the slideable view + */ + private boolean mDirectOffset = false; + + /** * True if the collapsed panel should be dragged up. */ private boolean mIsSlidingUp; @@ -289,8 +309,10 @@ public class SlidingUpPanelLayout extends ViewGroup { if (ta != null) { mPanelHeight = ta.getDimensionPixelSize(R.styleable.SlidingUpPanelLayout_panelHeight, -1); + mSlidePanelOffset = ta.getDimensionPixelSize(R.styleable.SlidingUpPanelLayout_slidePanelOffset, DEFAULT_SLIDE_PANEL_OFFSET); mShadowHeight = ta.getDimensionPixelSize(R.styleable.SlidingUpPanelLayout_shadowHeight, -1); mParallaxOffset = ta.getDimensionPixelSize(R.styleable.SlidingUpPanelLayout_paralaxOffset, -1); + mDirectOffset = ta.getBoolean(R.styleable.SlidingUpPanelLayout_directOffset,DEFAULT_DIRECT_OFFSET_FLAG); mMinFlingVelocity = ta.getInt(R.styleable.SlidingUpPanelLayout_flingVelocity, DEFAULT_MIN_FLING_VELOCITY); mCoveredFadeColor = ta.getColor(R.styleable.SlidingUpPanelLayout_fadeColor, DEFAULT_FADE_COLOR); @@ -396,12 +418,32 @@ public class SlidingUpPanelLayout extends ViewGroup { } /** + * Sets the panel offset when collapsed so you can exit + * the boundaries of the top of the screen + * + * @param val Offset in pixels + */ + public void setSlidePanelOffset(int val) { + mSlidePanelOffset = val; + requestLayout(); + } + + /** * @return The current paralax offset */ public int getCurrentParalaxOffset() { - // Clamp slide offset at zero for parallax computation; - int offset = (int)(mParallaxOffset * Math.max(mSlideOffset, 0)); - return mIsSlidingUp ? -offset : offset; + if (mParallaxOffset < 0) { + return 0; + } + + return (int)(mParallaxOffset * getDirectionalSlideOffset()); + } + + /** + * @return The directional slide offset + */ + protected float getDirectionalSlideOffset() { + return mIsSlidingUp ? -mSlideOffset : mSlideOffset; } /** @@ -637,7 +679,8 @@ public class SlidingUpPanelLayout extends ViewGroup { } if (child == mSlideableView) { - mSlideRange = MeasureSpec.getSize(childHeightSpec) - mPanelHeight; + mSlideRange = MeasureSpec.getSize(childHeightSpec) - mPanelHeight + mSlidePanelOffset; + childHeightSpec += mSlidePanelOffset; } child.measure(childWidthSpec, childHeightSpec); @@ -952,14 +995,21 @@ public class SlidingUpPanelLayout extends ViewGroup { // Recompute the slide offset based on the new top position mSlideOffset = computeSlideOffset(newTop); // Update the parallax based on the new slide offset - if (mParallaxOffset > 0 && mSlideOffset >= 0) { - int mainViewOffset = getCurrentParalaxOffset(); + if ((mParallaxOffset > 0 || mDirectOffset) && mSlideOffset >= 0) { + int mainViewOffset = 0; + if (mParallaxOffset > 0) { + mainViewOffset = getCurrentParalaxOffset(); + } else { + mainViewOffset = (int)(getDirectionalSlideOffset() * mSlideRange); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { mMainView.setTranslationY(mainViewOffset); } else { AnimatorProxy.wrap(mMainView).setTranslationY(mainViewOffset); } } + // Dispatch the slide event dispatchOnPanelSlide(mSlideableView); // If the slide offset is negative, and overlay is not on, we need to increase the diff --git a/src/com/cyngn/eleven/ui/activities/HomeActivity.java b/src/com/cyngn/eleven/ui/activities/HomeActivity.java index 0441e5a..a3237b7 100644 --- a/src/com/cyngn/eleven/ui/activities/HomeActivity.java +++ b/src/com/cyngn/eleven/ui/activities/HomeActivity.java @@ -11,12 +11,22 @@ package com.cyngn.eleven.ui.activities; +import android.content.Intent; +import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.view.ViewPager; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.TextView; import com.cyngn.eleven.R; +import com.cyngn.eleven.slidinguppanel.SlidingUpPanelLayout; +import com.cyngn.eleven.ui.fragments.AudioPlayerFragment; +import com.cyngn.eleven.ui.fragments.QueueFragment; import com.cyngn.eleven.ui.fragments.phone.MusicBrowserPhoneFragment; +import com.cyngn.eleven.utils.ApolloUtils; +import com.cyngn.eleven.widgets.theme.BottomActionBar; /** * This class is used to display the {@link ViewPager} used to swipe between the @@ -25,6 +35,19 @@ import com.cyngn.eleven.ui.fragments.phone.MusicBrowserPhoneFragment; * @author Andrew Neal (andrewdneal@gmail.com) */ public class HomeActivity extends BaseActivity { + public static final String ACTION_VIEW_BROWSE = "com.cyngn.eleven.ui.activities.HomeActivity.view.Browse"; + public static final String ACTION_VIEW_MUSIC_PLAYER = "com.cyngn.eleven.ui.activities.HomeActivity.view.MusicPlayer"; + public static final String ACTION_VIEW_QUEUE = "com.cyngn.eleven.ui.activities.HomeActivity.view.Queue"; + + enum Panel { + Browse, + MusicPlayer, + Queue, + } + + private SlidingUpPanelLayout mFirstPanel; + private SlidingUpPanelLayout mSecondPanel; + private int mActionBarColor; /** * {@inheritDoc} @@ -32,10 +55,143 @@ public class HomeActivity extends BaseActivity { @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // Load the music browser fragment - if (savedInstanceState == null) { - getSupportFragmentManager().beginTransaction() - .replace(R.id.activity_base_content, new MusicBrowserPhoneFragment()).commit(); + + getSupportFragmentManager().beginTransaction() + .replace(R.id.activity_base_content, new MusicBrowserPhoneFragment()).commit(); + + getSupportFragmentManager().beginTransaction() + .replace(R.id.audioPlayerFragment, new AudioPlayerFragment()).commit(); + + getSupportFragmentManager().beginTransaction() + .replace(R.id.queueFragment, new QueueFragment()).commit(); + + // set the action bar background color to be the background theme color + mActionBarColor = getResources().getColor(R.color.header_action_bar_color); + getActionBar().setBackgroundDrawable(new ColorDrawable(mActionBarColor)); + + setupFirstPanel(); + setupSecondPanel(); + + // if we've been launched by an intent, parse it + Intent launchIntent = getIntent(); + if (launchIntent != null) { + parseIntent(launchIntent); + } + } + + private void setupFirstPanel() { + mFirstPanel = (SlidingUpPanelLayout)findViewById(R.id.sliding_layout); + setHeaderText(R.id.firstHeaderBar, R.string.page_now_playing); + mFirstPanel.setPanelSlideListener(new SlidingUpPanelLayout.PanelSlideListener() { + @Override + public void onPanelSlide(View panel, float slideOffset) { + if (slideOffset > 0.8f) { + getActionBar().hide(); + } else if (slideOffset < 0.75f) { + getActionBar().show(); + } + } + + @Override + public void onPanelCollapsed(View panel) { + + } + + @Override + public void onPanelExpanded(View panel) { + + } + + @Override + public void onPanelAnchored(View panel) { + + } + + @Override + public void onPanelHidden(View panel) { + + } + }); + } + + private void setupSecondPanel() { + mSecondPanel = (SlidingUpPanelLayout)findViewById(R.id.sliding_layout2); + mSecondPanel.setPanelSlideListener(new SlidingUpPanelLayout.PanelSlideListener() { + private boolean firstRefresh = true; + @Override + public void onPanelSlide(View panel, float slideOffset) { + mFirstPanel.setSlidingEnabled(false); + // TODO: Make the queue fragment selfaware instead of hacking it here + if (firstRefresh) { + firstRefresh = false; + QueueFragment queueFragment = getQueueFragment(); + if (queueFragment != null) { + queueFragment.refreshQueue(); + } + } + } + + @Override + public void onPanelCollapsed(View panel) { + mFirstPanel.setSlidingEnabled(true); + firstRefresh = true; + } + + @Override + public void onPanelExpanded(View panel) { + + } + + @Override + public void onPanelAnchored(View panel) { + + } + + @Override + public void onPanelHidden(View panel) { + + } + }); + + // set the text of the second header + setHeaderText(R.id.secondHeaderBar, R.string.page_play_queue); + + // set the drag view offset to allow the panel to go past the top of the viewport + // since the previous view's is hiding the slide offset, we need to subtract that + // from action bat height + int slideOffset = getResources().getDimensionPixelOffset(R.dimen.sliding_panel_indicator_height); + slideOffset -= ApolloUtils.getActionBarHeight(this); + mSecondPanel.setSlidePanelOffset(slideOffset); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + + parseIntent(intent); + } + + private void parseIntent(Intent intent) { + Panel targetPanel = null; + + if (intent.getAction() != null) { + String action = intent.getAction(); + if (action.equals(ACTION_VIEW_BROWSE)) { + targetPanel = Panel.Browse; + } else if (action.equals(ACTION_VIEW_MUSIC_PLAYER)) { + targetPanel = Panel.MusicPlayer; + } if (action.equals(ACTION_VIEW_QUEUE)) { + targetPanel = Panel.Queue; + } + } else { + AudioPlayerFragment player = getAudioPlayerFragment(); + if (player != null && player.startPlayback()) { + targetPanel = Panel.MusicPlayer; + } + } + + if (targetPanel != null) { + showPanel(targetPanel); } } @@ -46,4 +202,62 @@ public class HomeActivity extends BaseActivity { public int setContentView() { return R.layout.activity_base; } + + @Override + public void onBackPressed() { + Panel panel = getCurrentPanel(); + switch (panel) { + case Browse: + super.onBackPressed(); + break; + case MusicPlayer: + showPanel(Panel.Browse); + break; + case Queue: + showPanel(Panel.MusicPlayer); + break; + } + } + + protected void showPanel(Panel panel) { + // TODO: Add ability to do this instantaneously as opposed to animate + switch (panel) { + case Browse: + mSecondPanel.collapsePanel(); + mFirstPanel.collapsePanel(); + break; + case MusicPlayer: + mSecondPanel.collapsePanel(); + mFirstPanel.expandPanel(); + break; + case Queue: + mSecondPanel.expandPanel(); + mFirstPanel.expandPanel(); + break; + } + } + + protected Panel getCurrentPanel() { + if (mSecondPanel.isPanelExpanded()) { + return Panel.Queue; + } else if (mFirstPanel.isPanelExpanded()) { + return Panel.MusicPlayer; + } else { + return Panel.Browse; + } + } + + protected AudioPlayerFragment getAudioPlayerFragment() { + return (AudioPlayerFragment)getSupportFragmentManager().findFragmentById(R.id.audioPlayerFragment); + } + + protected QueueFragment getQueueFragment() { + return (QueueFragment)getSupportFragmentManager().findFragmentById(R.id.queueFragment); + } + + protected void setHeaderText(int containerId, int textId) { + View container = findViewById(containerId); + TextView textView = (TextView)container.findViewById(R.id.header_bar_title); + textView.setText(textId); + } } diff --git a/src/com/cyngn/eleven/ui/activities/ShortcutActivity.java b/src/com/cyngn/eleven/ui/activities/ShortcutActivity.java index b9a1731..d30da08 100644 --- a/src/com/cyngn/eleven/ui/activities/ShortcutActivity.java +++ b/src/com/cyngn/eleven/ui/activities/ShortcutActivity.java @@ -53,7 +53,7 @@ public class ShortcutActivity extends FragmentActivity implements ServiceConnect /** * If true, this class will begin playback and open - * {@link AudioPlayerActivity}, false will close the class after playback, + * {@link AudioPlayerFragment}, false will close the class after playback, * which is what happens when a user starts playing something from an * app-widget */ @@ -323,7 +323,7 @@ public class ShortcutActivity extends FragmentActivity implements ServiceConnect } /** - * Starts playback, open {@link AudioPlayerActivity} and finishes this one + * Starts playback, open {@link AudioPlayerFragment} and finishes this one */ private void allDone() { final boolean shouldOpenAudioPlayer = mIntent.getBooleanExtra(OPEN_AUDIO_PLAYER, true); @@ -334,8 +334,8 @@ public class ShortcutActivity extends FragmentActivity implements ServiceConnect // Open the now playing screen if (shouldOpenAudioPlayer) { - final Intent intent = new Intent(this, AudioPlayerActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + final Intent intent = new Intent(this, HomeActivity.class); + intent.setAction(HomeActivity.ACTION_VIEW_MUSIC_PLAYER); startActivity(intent); } // All done diff --git a/src/com/cyngn/eleven/ui/activities/AudioPlayerActivity.java b/src/com/cyngn/eleven/ui/fragments/AudioPlayerFragment.java index d28627c..c4a9383 100644 --- a/src/com/cyngn/eleven/ui/activities/AudioPlayerActivity.java +++ b/src/com/cyngn/eleven/ui/fragments/AudioPlayerFragment.java @@ -1,22 +1,9 @@ /* - * Copyright (C) 2012 Andrew Neal 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. + * Copyright (C) 2014 Cyanogen, Inc. */ +package com.cyngn.eleven.ui.fragments; -package com.cyngn.eleven.ui.activities; - -import static com.cyngn.eleven.utils.MusicUtils.mService; - -import android.animation.ObjectAnimator; -import android.app.ActionBar; -import android.app.SearchManager; -import android.app.SearchableInfo; +import android.app.Activity; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -24,42 +11,29 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.media.AudioManager; -import android.media.audiofx.AudioEffect; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.SystemClock; -import android.provider.MediaStore.Audio.Playlists; -import android.provider.MediaStore.Audio.Albums; -import android.provider.MediaStore.Audio.Artists; -import android.support.v4.app.FragmentActivity; -import android.support.v4.view.ViewPager; -import android.view.Menu; -import android.view.MenuItem; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnClickListener; -import android.view.animation.AnimationUtils; -import android.widget.FrameLayout; +import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.SearchView; -import android.widget.SearchView.OnQueryTextListener; import android.widget.SeekBar; -import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; -import com.cyngn.eleven.IElevenService; +import android.provider.MediaStore.Audio.Playlists; +import android.provider.MediaStore.Audio.Albums; +import android.provider.MediaStore.Audio.Artists; import com.cyngn.eleven.MusicPlaybackService; import com.cyngn.eleven.R; -import com.cyngn.eleven.adapters.PagerAdapter; import com.cyngn.eleven.cache.ImageFetcher; -import com.cyngn.eleven.ui.fragments.QueueFragment; -import com.cyngn.eleven.menu.DeleteDialog; import com.cyngn.eleven.utils.ApolloUtils; import com.cyngn.eleven.utils.MusicUtils; -import com.cyngn.eleven.utils.MusicUtils.ServiceToken; import com.cyngn.eleven.utils.NavUtils; import com.cyngn.eleven.widgets.PlayPauseButton; import com.cyngn.eleven.widgets.RepeatButton; @@ -68,19 +42,19 @@ import com.cyngn.eleven.widgets.ShuffleButton; import java.lang.ref.WeakReference; -/** - * Apollo's "now playing" interface. - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -public class AudioPlayerActivity extends FragmentActivity implements ServiceConnection, - OnSeekBarChangeListener, DeleteDialog.DeleteDialogCallback { +import static com.cyngn.eleven.utils.MusicUtils.mService; + +public class AudioPlayerFragment extends Fragment implements ServiceConnection, + SeekBar.OnSeekBarChangeListener { + + // fragment view + private ViewGroup mRootView; // Message to refresh the time private static final int REFRESH_TIME = 1; // The service token - private ServiceToken mToken; + private MusicUtils.ServiceToken mToken; // Play and pause button private PlayPauseButton mPlayPauseButton; @@ -115,9 +89,6 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn // Total time private TextView mTotalTime; - // Queue switch - private ImageView mQueueSwitch; - // Progess private SeekBar mProgress; @@ -127,15 +98,6 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn // Handler used to update the current time private TimeHandler mTimeHandler; - // View pager - private ViewPager mViewPager; - - // Pager adpater - private PagerAdapter mPagerAdapter; - - // ViewPager container - private FrameLayout mPageContainer; - // Header private LinearLayout mAudioPlayerHeader; @@ -154,50 +116,36 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn private boolean mFromTouch = false; - /** - * {@inheritDoc} - */ @Override - protected void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // Fade it in - overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); // Control the media volume - setVolumeControlStream(AudioManager.STREAM_MUSIC); + getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC); // Bind Apollo's service - mToken = MusicUtils.bindToService(this, this); + mToken = MusicUtils.bindToService(getActivity(), this); // Initialize the image fetcher/cache - mImageFetcher = ApolloUtils.getImageFetcher(this); + mImageFetcher = ApolloUtils.getImageFetcher(getActivity()); // Initialize the handler used to update the current time mTimeHandler = new TimeHandler(this); // Initialize the broadcast receiver mPlaybackStatus = new PlaybackStatus(this); - - // Theme the action bar - final ActionBar actionBar = getActionBar(); - actionBar.setTitle(getString(R.string.app_name)); - actionBar.setDisplayHomeAsUpEnabled(true); - - // Set the layout - setContentView(R.layout.activity_player_base); - - // Cache all the items - initPlaybackControls(); } /** * {@inheritDoc} */ @Override - public void onNewIntent(Intent intent) { - setIntent(intent); - startPlayback(); + public View onCreateView(final LayoutInflater inflater, final ViewGroup container, + final Bundle savedInstanceState) { + // The View for the fragment's UI + mRootView = (ViewGroup) inflater.inflate(R.layout.activity_player_fragment, null); + initPlaybackControls(); + return mRootView; } /** @@ -205,7 +153,6 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn */ @Override public void onServiceConnected(final ComponentName name, final IBinder service) { - mService = IElevenService.Stub.asInterface(service); // Check whether we were asked to start any playback startPlayback(); // Set the playback drawables @@ -213,15 +160,12 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn // Current info updateNowPlayingInfo(); // Update the favorites icon - invalidateOptionsMenu(); + // TODO: Revisit + // invalidateOptionsMenu(); } - /** - * {@inheritDoc} - */ @Override - public void onServiceDisconnected(final ComponentName name) { - mService = null; + public void onServiceDisconnected(ComponentName name) { } /** @@ -271,151 +215,27 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn mFromTouch = false; } - /** - * {@inheritDoc} - */ - @Override - public boolean onPrepareOptionsMenu(final Menu menu) { - // Hide the EQ option if it can't be opened - final Intent intent = new Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL); - if (getPackageManager().resolveActivity(intent, 0) == null) { - final MenuItem effects = menu.findItem(R.id.menu_audio_player_equalizer); - effects.setVisible(false); - } -// mResources.setFavoriteIcon(menu); - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean onCreateOptionsMenu(final Menu menu) { - // Search view - getMenuInflater().inflate(R.menu.search, menu); - // Theme the search icon -// mResources.setSearchIcon(menu); - - final SearchView searchView = (SearchView)menu.findItem(R.id.menu_search).getActionView(); - // Add voice search - final SearchManager searchManager = (SearchManager)getSystemService(Context.SEARCH_SERVICE); - final SearchableInfo searchableInfo = searchManager.getSearchableInfo(getComponentName()); - searchView.setSearchableInfo(searchableInfo); - // Perform the search - searchView.setOnQueryTextListener(new OnQueryTextListener() { - - @Override - public boolean onQueryTextSubmit(final String query) { - // Open the search activity - NavUtils.openSearch(AudioPlayerActivity.this, query); - return true; - } - - @Override - public boolean onQueryTextChange(final String newText) { - // Nothing to do - return false; - } - }); - - // Favorite action - getMenuInflater().inflate(R.menu.favorite, menu); - // Shuffle all - getMenuInflater().inflate(R.menu.shuffle, menu); - // Share, ringtone, and equalizer - getMenuInflater().inflate(R.menu.audio_player, menu); - // Settings - getMenuInflater().inflate(R.menu.activity_base, menu); - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean onOptionsItemSelected(final MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - // Go back to the home activity - NavUtils.goHome(this); - return true; - case R.id.menu_shuffle: - // Shuffle all the songs - MusicUtils.shuffleAll(this); - // Refresh the queue - ((QueueFragment)mPagerAdapter.getFragment(0)).refreshQueue(); - return true; - case R.id.menu_favorite: - // Toggle the current track as a favorite and update the menu - // item - MusicUtils.toggleFavorite(); - invalidateOptionsMenu(); - return true; - case R.id.menu_audio_player_ringtone: - // Set the current track as a ringtone - MusicUtils.setRingtone(this, MusicUtils.getCurrentAudioId()); - return true; - case R.id.menu_audio_player_share: - // Share the current meta data - shareCurrentTrack(); - return true; - case R.id.menu_audio_player_equalizer: - // Sound effects - NavUtils.openEffectsPanel(this); - return true; - case R.id.menu_settings: - // Settings - NavUtils.openSettings(this); - return true; - case R.id.menu_audio_player_delete: - // Delete current song - DeleteDialog.newInstance(MusicUtils.getTrackName(), new long[] { - MusicUtils.getCurrentAudioId() - }, null).show(getSupportFragmentManager(), "DeleteDialog"); - return true; - default: - break; - } - return super.onOptionsItemSelected(item); - } - - @Override public void onDelete(long[] ids) { - ((QueueFragment)mPagerAdapter.getFragment(0)).refreshQueue(); if (MusicUtils.getQueue().length == 0) { - NavUtils.goHome(this); + NavUtils.goHome(getActivity()); } } - /** - * {@inheritDoc} - */ - @Override - public void onBackPressed() { - super.onBackPressed(); - NavUtils.goHome(this); - } - - /** - * {@inheritDoc} - */ - @Override - protected void onResume() { - super.onResume(); + public void onVisible() { // Set the playback drawables updatePlaybackControls(); // Current info updateNowPlayingInfo(); - // Refresh the queue - ((QueueFragment)mPagerAdapter.getFragment(0)).refreshQueue(); } - /** - * {@inheritDoc} - */ + public void onHidden() { + + } + @Override - protected void onStart() { + public void onStart() { super.onStart(); + final IntentFilter filter = new IntentFilter(); // Play and pause changes filter.addAction(MusicPlaybackService.PLAYSTATE_CHANGED); @@ -426,29 +246,23 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn filter.addAction(MusicPlaybackService.META_CHANGED); // Update a list, probably the playlist fragment's filter.addAction(MusicPlaybackService.REFRESH); - registerReceiver(mPlaybackStatus, filter); + getActivity().registerReceiver(mPlaybackStatus, filter); // Refresh the current time final long next = refreshCurrentTime(); queueNextRefresh(next); - MusicUtils.notifyForegroundStateChanged(this, true); } - /** - * {@inheritDoc} - */ @Override - protected void onStop() { + public void onStop() { super.onStop(); - MusicUtils.notifyForegroundStateChanged(this, false); + mImageFetcher.flush(); } - /** - * {@inheritDoc} - */ @Override - protected void onDestroy() { + public void onDestroy() { super.onDestroy(); + mIsPaused = false; mTimeHandler.removeMessages(REFRESH_TIME); // Unbind from the service @@ -459,7 +273,7 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn // Unregister the receiver try { - unregisterReceiver(mPlaybackStatus); + getActivity().unregisterReceiver(mPlaybackStatus); } catch (final Throwable e) { //$FALL-THROUGH$ } @@ -470,60 +284,35 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn */ @SuppressWarnings("deprecation") private void initPlaybackControls() { - // ViewPager container - mPageContainer = (FrameLayout)findViewById(R.id.audio_player_pager_container); - // Theme the pager container background - mPageContainer - .setBackgroundDrawable(getResources().getDrawable(R.drawable.audio_player_pager_container)); - // Now playing header - mAudioPlayerHeader = (LinearLayout)findViewById(R.id.audio_player_header); + mAudioPlayerHeader = (LinearLayout)mRootView.findViewById(R.id.audio_player_header); // Opens the currently playing album profile mAudioPlayerHeader.setOnClickListener(mOpenAlbumProfile); - // Used to hide the artwork and show the queue - final FrameLayout mSwitch = (FrameLayout)findViewById(R.id.audio_player_switch); - mSwitch.setOnClickListener(mToggleHiddenPanel); - - // Initialize the pager adapter - mPagerAdapter = new PagerAdapter(this); - // Queue - mPagerAdapter.add(QueueFragment.class, null); - - // Initialize the ViewPager - mViewPager = (ViewPager)findViewById(R.id.audio_player_pager); - // Attch the adapter - mViewPager.setAdapter(mPagerAdapter); - // Offscreen pager loading limit - mViewPager.setOffscreenPageLimit(mPagerAdapter.getCount() - 1); // Play and pause button - mPlayPauseButton = (PlayPauseButton)findViewById(R.id.action_button_play); + mPlayPauseButton = (PlayPauseButton)mRootView.findViewById(R.id.action_button_play); // Shuffle button - mShuffleButton = (ShuffleButton)findViewById(R.id.action_button_shuffle); + mShuffleButton = (ShuffleButton)mRootView.findViewById(R.id.action_button_shuffle); // Repeat button - mRepeatButton = (RepeatButton)findViewById(R.id.action_button_repeat); + mRepeatButton = (RepeatButton)mRootView.findViewById(R.id.action_button_repeat); // Previous button - mPreviousButton = (RepeatingImageButton)findViewById(R.id.action_button_previous); + mPreviousButton = (RepeatingImageButton)mRootView.findViewById(R.id.action_button_previous); // Next button - mNextButton = (RepeatingImageButton)findViewById(R.id.action_button_next); + mNextButton = (RepeatingImageButton)mRootView.findViewById(R.id.action_button_next); // Track name - mTrackName = (TextView)findViewById(R.id.audio_player_track_name); + mTrackName = (TextView)mRootView.findViewById(R.id.audio_player_track_name); // Artist name - mArtistName = (TextView)findViewById(R.id.audio_player_artist_name); + mArtistName = (TextView)mRootView.findViewById(R.id.audio_player_artist_name); // Album art - mAlbumArt = (ImageView)findViewById(R.id.audio_player_album_art); + mAlbumArt = (ImageView)mRootView.findViewById(R.id.audio_player_album_art); // Small album art - mAlbumArtSmall = (ImageView)findViewById(R.id.audio_player_switch_album_art); + mAlbumArtSmall = (ImageView)mRootView.findViewById(R.id.audio_player_switch_album_art); // Current time - mCurrentTime = (TextView)findViewById(R.id.audio_player_current_time); + mCurrentTime = (TextView)mRootView.findViewById(R.id.audio_player_current_time); // Total time - mTotalTime = (TextView)findViewById(R.id.audio_player_total_time); - // Used to show and hide the queue fragment - mQueueSwitch = (ImageView)findViewById(R.id.audio_player_switch_queue); - // Theme the queue switch icon - mQueueSwitch.setImageDrawable(getResources().getDrawable(R.drawable.btn_switch_queue)); + mTotalTime = (TextView)mRootView.findViewById(R.id.audio_player_total_time); // Progress - mProgress = (SeekBar)findViewById(android.R.id.progress); + mProgress = (SeekBar)mRootView.findViewById(android.R.id.progress); // Set the repeat listner for the previous button mPreviousButton.setRepeatListener(mRewindListener); @@ -542,7 +331,7 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn // Set the artist name mArtistName.setText(MusicUtils.getArtistName()); // Set the total time - mTotalTime.setText(MusicUtils.makeTimeString(this, MusicUtils.duration() / 1000)); + mTotalTime.setText(MusicUtils.makeTimeString(getActivity(), MusicUtils.duration() / 1000)); // Set the album art mImageFetcher.loadCurrentArtwork(mAlbumArt); // Set the small artwork @@ -553,7 +342,7 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn } private long parseIdFromIntent(Intent intent, String longKey, - String stringKey, long defaultId) { + String stringKey, long defaultId) { long id = intent.getLongExtra(longKey, -1); if (id < 0) { String idString = intent.getStringExtra(stringKey); @@ -571,12 +360,13 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn /** * Checks whether the passed intent contains a playback request, * and starts playback if that's the case + * @return true if the intent was consumed */ - private void startPlayback() { - Intent intent = getIntent(); + public boolean startPlayback() { + Intent intent = getActivity().getIntent(); - if (intent == null || mService == null) { - return; + if (intent == null || mService == null || getActivity() == null) { + return false; } Uri uri = intent.getData(); @@ -584,36 +374,39 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn boolean handled = false; if (uri != null && uri.toString().length() > 0) { - MusicUtils.playFile(this, uri); + MusicUtils.playFile(getActivity(), uri); handled = true; } else if (Playlists.CONTENT_TYPE.equals(mimeType)) { long id = parseIdFromIntent(intent, "playlistId", "playlist", -1); if (id >= 0) { - MusicUtils.playPlaylist(this, id); + MusicUtils.playPlaylist(getActivity(), id); handled = true; } } else if (Albums.CONTENT_TYPE.equals(mimeType)) { long id = parseIdFromIntent(intent, "albumId", "album", -1); if (id >= 0) { int position = intent.getIntExtra("position", 0); - MusicUtils.playAlbum(this, id, position); + MusicUtils.playAlbum(getActivity(), id, position); handled = true; } } else if (Artists.CONTENT_TYPE.equals(mimeType)) { long id = parseIdFromIntent(intent, "artistId", "artist", -1); if (id >= 0) { int position = intent.getIntExtra("position", 0); - MusicUtils.playArtist(this, id, position); + MusicUtils.playArtist(getActivity(), id, position); handled = true; } } if (handled) { // Make sure to process intent only once - setIntent(new Intent()); + getActivity().setIntent(new Intent()); // Refresh the queue - ((QueueFragment)mPagerAdapter.getFragment(0)).refreshQueue(); + // TODO: Refresh queue or have it self-aware + return true; } + + return false; } /** @@ -641,7 +434,7 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn /** * Used to scan backwards in time through the curren track - * + * * @param repcnt The repeat count * @param delta The long press duration */ @@ -663,7 +456,7 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn long newpos = mStartSeekPos - delta; if (newpos < 0) { // move to previous track - MusicUtils.previous(this); + MusicUtils.previous(getActivity()); final long duration = MusicUtils.duration(); mStartSeekPos += duration; newpos += duration; @@ -683,7 +476,7 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn /** * Used to scan forwards in time through the curren track - * + * * @param repcnt The repeat count * @param delta The long press duration */ @@ -724,7 +517,7 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn } private void refreshCurrentTimeText(final long pos) { - mCurrentTime.setText(MusicUtils.makeTimeString(this, pos / 1000)); + mCurrentTime.setText(MusicUtils.makeTimeString(getActivity(), pos / 1000)); } /* Used to update the current time string */ @@ -779,44 +572,6 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn } /** - * @param v The view to animate - * @param alpha The alpha to apply - */ - private void fade(final View v, final float alpha) { - final ObjectAnimator fade = ObjectAnimator.ofFloat(v, "alpha", alpha); - fade.setInterpolator(AnimationUtils.loadInterpolator(this, - android.R.anim.accelerate_decelerate_interpolator)); - fade.setDuration(400); - fade.start(); - } - - /** - * Called to show the album art and hide the queue - */ - private void showAlbumArt() { - mPageContainer.setVisibility(View.INVISIBLE); - mAlbumArtSmall.setVisibility(View.GONE); - mQueueSwitch.setVisibility(View.VISIBLE); - // Fade out the pager container - fade(mPageContainer, 0f); - // Fade in the album art - fade(mAlbumArt, 1f); - } - - /** - * Called to hide the album art and show the queue - */ - public void hideAlbumArt() { - mPageContainer.setVisibility(View.VISIBLE); - mQueueSwitch.setVisibility(View.GONE); - mAlbumArtSmall.setVisibility(View.VISIBLE); - // Fade out the artwork - fade(mAlbumArt, 0f); - // Fade in the pager container - fade(mPageContainer, 1f); - } - - /** * /** Used to shared what the user is currently listening to */ private void shareCurrentTrack() { @@ -860,65 +615,29 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn }; /** - * Switches from the large album art screen to show the queue and lyric - * fragments, then back again - */ - private final OnClickListener mToggleHiddenPanel = new OnClickListener() { - - /** - * {@inheritDoc} - */ - @Override - public void onClick(final View v) { - if (mPageContainer.getVisibility() == View.VISIBLE) { - // Open the current album profile - mAudioPlayerHeader.setOnClickListener(mOpenAlbumProfile); - // Show the artwork, hide the queue - showAlbumArt(); - } else { - // Scroll to the current track - mAudioPlayerHeader.setOnClickListener(mScrollToCurrentSong); - // Show the queue, hide the artwork - hideAlbumArt(); - } - } - }; - - /** * Opens to the current album profile */ - private final OnClickListener mOpenAlbumProfile = new OnClickListener() { + private final View.OnClickListener mOpenAlbumProfile = new View.OnClickListener() { @Override public void onClick(final View v) { - NavUtils.openAlbumProfile(AudioPlayerActivity.this, MusicUtils.getAlbumName(), + NavUtils.openAlbumProfile(getActivity(), MusicUtils.getAlbumName(), MusicUtils.getArtistName(), MusicUtils.getCurrentAlbumId()); } }; /** - * Scrolls the queue to the currently playing song - */ - private final OnClickListener mScrollToCurrentSong = new OnClickListener() { - - @Override - public void onClick(final View v) { - ((QueueFragment)mPagerAdapter.getFragment(0)).scrollToCurrentSong(); - } - }; - - /** * Used to update the current time string */ private static final class TimeHandler extends Handler { - private final WeakReference<AudioPlayerActivity> mAudioPlayer; + private final WeakReference<AudioPlayerFragment> mAudioPlayer; /** * Constructor of <code>TimeHandler</code> */ - public TimeHandler(final AudioPlayerActivity player) { - mAudioPlayer = new WeakReference<AudioPlayerActivity>(player); + public TimeHandler(final AudioPlayerFragment player) { + mAudioPlayer = new WeakReference<AudioPlayerFragment>(player); } @Override @@ -939,13 +658,13 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn */ private static final class PlaybackStatus extends BroadcastReceiver { - private final WeakReference<AudioPlayerActivity> mReference; + private final WeakReference<AudioPlayerFragment> mReference; /** * Constructor of <code>PlaybackStatus</code> */ - public PlaybackStatus(final AudioPlayerActivity activity) { - mReference = new WeakReference<AudioPlayerActivity>(activity); + public PlaybackStatus(final AudioPlayerFragment fragment) { + mReference = new WeakReference<AudioPlayerFragment>(fragment); } /** @@ -958,7 +677,8 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn // Current info mReference.get().updateNowPlayingInfo(); // Update the favorites icon - mReference.get().invalidateOptionsMenu(); + // TODO: Revist + // mReference.get().invalidateOptionsMenu(); } else if (action.equals(MusicPlaybackService.PLAYSTATE_CHANGED)) { // Set the play and pause image mReference.get().mPlayPauseButton.updateState(); @@ -971,5 +691,4 @@ public class AudioPlayerActivity extends FragmentActivity implements ServiceConn } } } - } diff --git a/src/com/cyngn/eleven/utils/ApolloUtils.java b/src/com/cyngn/eleven/utils/ApolloUtils.java index 1010bad..ba6d8c1 100644 --- a/src/com/cyngn/eleven/utils/ApolloUtils.java +++ b/src/com/cyngn/eleven/utils/ApolloUtils.java @@ -29,10 +29,13 @@ import android.os.AsyncTask; import android.os.Build; import android.provider.MediaStore; import android.util.Log; +import android.util.TypedValue; import android.view.Gravity; import android.view.View; +import android.view.ViewGroup; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.webkit.WebView; +import android.widget.LinearLayout; import android.widget.Toast; import com.cyngn.eleven.Config; @@ -370,4 +373,19 @@ public final class ApolloUtils { v.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } } + + /** + * Gets the action bar height in pixels + * @param context + * @return action bar height in pixels + */ + public static int getActionBarHeight(Context context) { + TypedValue tv = new TypedValue(); + View view = new View(context); + if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) { + return TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics()); + } + + return 0; + } } diff --git a/src/com/cyngn/eleven/utils/NavUtils.java b/src/com/cyngn/eleven/utils/NavUtils.java index 852ce09..80c6f29 100644 --- a/src/com/cyngn/eleven/utils/NavUtils.java +++ b/src/com/cyngn/eleven/utils/NavUtils.java @@ -22,7 +22,7 @@ import android.provider.MediaStore; import com.cyngn.eleven.Config; import com.cyngn.eleven.R; import com.cyngn.eleven.model.Album; -import com.cyngn.eleven.ui.activities.AudioPlayerActivity; +import com.cyngn.eleven.ui.fragments.AudioPlayerFragment; import com.cyngn.eleven.ui.activities.HomeActivity; import com.cyngn.eleven.ui.activities.ProfileActivity; import com.cyngn.eleven.ui.activities.SearchActivity; @@ -109,17 +109,14 @@ public final class NavUtils { } /** - * Opens to {@link AudioPlayerActivity}. + * Opens to {@link AudioPlayerFragment}. * * @param activity The {@link Activity} to use. */ public static void openAudioPlayer(final Activity activity) { - final Intent intent = new Intent(activity, AudioPlayerActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + final Intent intent = new Intent(activity, HomeActivity.class); + intent.setAction(HomeActivity.ACTION_VIEW_MUSIC_PLAYER); activity.startActivity(intent); - activity.finish(); } /** @@ -143,9 +140,7 @@ public final class NavUtils { */ public static void goHome(final Activity activity) { final Intent intent = new Intent(activity, HomeActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setAction(HomeActivity.ACTION_VIEW_BROWSE); activity.startActivity(intent); activity.finish(); } |