diff options
33 files changed, 8 insertions, 4854 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index cfc3834..9c888c4 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -132,13 +132,6 @@ </intent-filter> </activity> - <!-- Profile phone Activity --> - <activity - android:name=".ui.activities.ProfileActivity" - android:excludeFromRecents="true" - android:screenOrientation="portrait" - android:theme="@style/Eleven.Theme.ActionBar.Overlay"> - </activity> <!-- Artist Detail Activity --> <activity android:name=".ui.activities.ArtistDetailActivity" @@ -241,23 +234,6 @@ android:name="android.appwidget.provider" android:resource="@xml/app_widget_large_alternate" /> </receiver> - <!-- Resizable recently listened App Widget --> - <receiver - android:name="com.cyngn.eleven.appwidgets.RecentWidgetProvider" - android:exported="false" - android:label="@string/app_widget_recent" > - <intent-filter> - <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> - </intent-filter> - <!-- This specifies the widget provider info --> - <meta-data - android:name="android.appwidget.provider" - android:resource="@xml/app_widget_recents" /> - </receiver> - <!-- The service serving the RemoteViews to the recently listened App Widget --> - <service - android:name="com.cyngn.eleven.appwidgets.RecentWidgetService" - android:permission="android.permission.BIND_REMOTEVIEWS" /> <!-- Media button receiver --> <receiver android:name=".MediaButtonIntentReceiver" > <intent-filter> diff --git a/res/layout/activity_profile_base.xml b/res/layout/activity_profile_base.xml deleted file mode 100644 index 4e99853..0000000 --- a/res/layout/activity_profile_base.xml +++ /dev/null @@ -1,38 +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. ---> -<!-- content --> - -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <android.support.v4.view.ViewPager - android:id="@+id/acivity_profile_base_pager" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_alignParentLeft="true" - android:layout_alignParentTop="true"/> - - <include - android:id="@+id/acivity_profile_base_tab_carousel" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - layout="@layout/profile_tab_carousel"/> -</RelativeLayout> - <!-- end content --> diff --git a/res/layout/app_widget_recents.xml b/res/layout/app_widget_recents.xml deleted file mode 100644 index 44d3e45..0000000 --- a/res/layout/app_widget_recents.xml +++ /dev/null @@ -1,106 +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. ---> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_margin="0dp" - android:background="@color/action_bar_color" > - - <RelativeLayout - android:id="@+id/app_widget_recents_action_bar" - android:layout_width="match_parent" - android:layout_height="@dimen/app_widget_recents_action_bar_height" > - - <ImageView - android:id="@+id/app_widget_recents_icon" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_centerVertical="true" - android:background="?android:selectableItemBackground" - android:contentDescription="@string/app_name" - android:padding="@dimen/app_widget_recents_action_bar_item_padding" - android:scaleType="centerInside" - android:src="@drawable/ic_launcher" /> - - <TextView - android:id="@+id/app_widget_recents_app_name" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_centerVertical="true" - android:layout_toRightOf="@+id/app_widget_recents_icon" - android:text="@string/page_recent" - android:textColor="@color/white" - android:textSize="@dimen/text_size_medium" /> - - <ImageButton - android:id="@+id/app_widget_recents_previous" - android:layout_width="@dimen/app_widget_recents_action_bar_height" - android:layout_height="match_parent" - android:layout_centerVertical="true" - android:layout_toLeftOf="@+id/app_widget_recents_play" - android:background="?android:selectableItemBackground" - android:contentDescription="@null" - android:scaleType="center" - android:src="@drawable/btn_playback_previous" /> - - <ImageButton - android:id="@+id/app_widget_recents_play" - android:layout_width="@dimen/app_widget_recents_action_bar_height" - android:layout_height="match_parent" - android:layout_centerVertical="true" - android:layout_toLeftOf="@+id/app_widget_recents_next" - android:background="?android:selectableItemBackground" - android:contentDescription="@null" - android:scaleType="center" - android:src="@drawable/btn_playback_play" /> - - <ImageButton - android:id="@+id/app_widget_recents_next" - android:layout_width="@dimen/app_widget_recents_action_bar_height" - android:layout_height="match_parent" - android:layout_alignParentRight="true" - android:layout_centerVertical="true" - android:background="?android:selectableItemBackground" - android:contentDescription="@null" - android:scaleType="center" - android:src="@drawable/btn_playback_next" /> - </RelativeLayout> - - <ImageView - android:id="@+id/colorstrip" - android:layout_width="match_parent" - android:layout_height="@dimen/colorstrip_height" - android:layout_below="@+id/app_widget_recents_action_bar" - android:background="@color/holo_blue_light" - android:contentDescription="@null" /> - - <FrameLayout - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_below="@+id/colorstrip" - android:layout_centerVertical="true" - android:background="@drawable/appwidget_bg" > - - <ListView - android:id="@+id/app_widget_recents_list" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@null" - android:cacheColorHint="@color/transparent" /> - </FrameLayout> - -</RelativeLayout>
\ No newline at end of file diff --git a/res/layout/app_widget_recents_items.xml b/res/layout/app_widget_recents_items.xml deleted file mode 100644 index ec531fb..0000000 --- a/res/layout/app_widget_recents_items.xml +++ /dev/null @@ -1,57 +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. ---> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/app_widget_recents_items" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="horizontal" - tools:ignore="ContentDescription" > - - <ImageView - android:id="@+id/app_widget_recents_base_image" - android:layout_width="@dimen/item_normal_height" - android:layout_height="@dimen/item_normal_height" - android:scaleType="fitXY" /> - - <LinearLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1" - android:layout_gravity="center_vertical" - android:paddingLeft="@dimen/list_preferred_item_padding" - android:orientation="vertical" > - - <TextView - android:id="@+id/app_widget_recents_line_one" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:singleLine="true" - android:textSize="@dimen/text_size_medium" - android:textStyle="bold" /> - - <TextView - android:id="@+id/app_widget_recents_line_two" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/list_item_line_two_margin_top" - android:singleLine="true" - android:textSize="@dimen/text_size_small" /> - - </LinearLayout> - -</LinearLayout> diff --git a/res/layout/faux_carousel.xml b/res/layout/faux_carousel.xml deleted file mode 100644 index cbdc6f0..0000000 --- a/res/layout/faux_carousel.xml +++ /dev/null @@ -1,24 +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="wrap_content" > - - <include - layout="@layout/profile_tab_carousel" - android:visibility="invisible" /> - -</FrameLayout>
\ No newline at end of file diff --git a/res/layout/profile_tab.xml b/res/layout/profile_tab.xml deleted file mode 100644 index 6529bae..0000000 --- a/res/layout/profile_tab.xml +++ /dev/null @@ -1,90 +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. ---> -<view xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="0dip" - android:layout_height="match_parent" - android:layout_weight="1" - class="com.cyngn.eleven.widgets.CarouselTab" > - - <RelativeLayout - android:layout_width="match_parent" - android:layout_height="match_parent" > - - <com.cyngn.eleven.widgets.LayoutSuppressingImageView - android:id="@+id/profile_tab_photo" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:contentDescription="@null" - android:scaleType="centerCrop" /> - - <com.cyngn.eleven.widgets.SquareImageView - android:id="@+id/profile_tab_album_art" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:contentDescription="@null" - android:scaleType="fitXY" - android:visibility="gone" /> - - <View - android:id="@+id/profile_tab_photo_overlay" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" /> - - <View - android:id="@+id/profile_tab_label_background" - android:layout_width="match_parent" - android:layout_height="@dimen/profile_carousel_label_height" - android:layout_alignParentBottom="true" - android:layout_alignParentLeft="true" - android:background="@color/transparent_black" /> - - <View - android:id="@+id/profile_tab_colorstrip" - android:layout_width="match_parent" - android:layout_height="@dimen/profile_indicator_height" - android:layout_alignParentBottom="true" - android:layout_alignParentLeft="true" /> - - <View - android:id="@+id/profile_tab_alpha_overlay" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:layout_marginBottom="@dimen/profile_carousel_label_height" /> - - <TextView - android:id="@+id/profile_tab_label" - android:layout_width="match_parent" - android:layout_height="@dimen/profile_carousel_label_height" - android:layout_alignParentBottom="true" - android:layout_alignParentLeft="true" - android:gravity="left|center_vertical" - android:paddingLeft="@dimen/profile_label_padding" - android:paddingRight="@dimen/profile_label_padding" - android:singleLine="true" - android:textColor="@color/white" - android:textSize="@dimen/text_size_large" /> - </RelativeLayout> - -</view>
\ No newline at end of file diff --git a/res/layout/profile_tab_carousel.xml b/res/layout/profile_tab_carousel.xml deleted file mode 100644 index 8971c44..0000000 --- a/res/layout/profile_tab_carousel.xml +++ /dev/null @@ -1,55 +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. ---> -<view xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/profile_tab_carousel" - android:layout_width="match_parent" - android:layout_height="wrap_content" - class="com.cyngn.eleven.widgets.ProfileTabCarousel" - android:fadingEdge="none" - android:scrollbars="none" > - - <LinearLayout - android:id="@+id/profile_tab_carousel_tab_and_shadow_container" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" > - - <LinearLayout - android:id="@+id/profile_tab_carousel_tab_container" - android:layout_width="match_parent" - android:layout_height="0dip" - android:layout_weight="1" - android:baselineAligned="false" - android:orientation="horizontal" > - - <include - android:id="@+id/profile_tab_carousel_tab_one" - layout="@layout/profile_tab" /> - - <include - android:id="@+id/profile_tab_carousel_tab_two" - layout="@layout/profile_tab" /> - </LinearLayout> - - <View - android:id="@+id/profile_tab_carousel_shadow" - android:layout_width="match_parent" - android:layout_height="@dimen/profile_photo_shadow_height" - android:background="?android:attr/windowContentOverlay" /> - </LinearLayout> - -</view>
\ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index ee10540..af6d700 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -138,8 +138,6 @@ <dimen name="app_widget_small_artwork_size">48.0dip</dimen> <dimen name="app_widget_small_button_padding">8.0dip</dimen> <dimen name="app_widget_small_button_height">48.0dip</dimen> - <dimen name="app_widget_recents_action_bar_height">48.0dip</dimen> - <dimen name="app_widget_recents_action_bar_item_padding">8.0dip</dimen> <dimen name="app_widget_tiny_height">70.0dip</dimen> <dimen name="app_widget_tiny_width">70.0dip</dimen> <dimen name="app_widget_padding">0.0dip</dimen> diff --git a/res/xml/app_widget_recents.xml b/res/xml/app_widget_recents.xml deleted file mode 100644 index f3be48f..0000000 --- a/res/xml/app_widget_recents.xml +++ /dev/null @@ -1,26 +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. ---> -<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" - android:initialLayout="@layout/app_widget_recents" - android:minHeight="@dimen/app_widget_scrollable_min_height" - android:minResizeHeight="@dimen/app_widget_scrollable_min_resize_height" - android:minResizeWidth="@dimen/app_widget_large_min_width" - android:minWidth="@dimen/app_widget_large_min_width" - android:previewImage="@drawable/app_widget_recents" - android:resizeMode="vertical|horizontal" - android:updatePeriodMillis="0" - android:widgetCategory="keyguard|home_screen" /> diff --git a/src/com/cyngn/eleven/MusicPlaybackService.java b/src/com/cyngn/eleven/MusicPlaybackService.java index 0931174..1db2d25 100644 --- a/src/com/cyngn/eleven/MusicPlaybackService.java +++ b/src/com/cyngn/eleven/MusicPlaybackService.java @@ -50,7 +50,6 @@ import android.util.Log; import com.cyngn.eleven.appwidgets.AppWidgetLarge; import com.cyngn.eleven.appwidgets.AppWidgetLargeAlternate; import com.cyngn.eleven.appwidgets.AppWidgetSmall; -import com.cyngn.eleven.appwidgets.RecentWidgetProvider; import com.cyngn.eleven.cache.ImageCache; import com.cyngn.eleven.cache.ImageFetcher; import com.cyngn.eleven.provider.RecentStore; @@ -360,11 +359,6 @@ public class MusicPlaybackService extends Service { .getInstance(); /** - * Recently listened widget - */ - private final RecentWidgetProvider mRecentWidgetProvider = RecentWidgetProvider.getInstance(); - - /** * The media player */ private MultiPlayer mPlayer; @@ -1389,7 +1383,6 @@ public class MusicPlaybackService extends Service { mAppWidgetSmall.notifyChange(this, what); mAppWidgetLarge.notifyChange(this, what); mAppWidgetLargeAlternate.notifyChange(this, what); - mRecentWidgetProvider.notifyChange(this, what); } /** @@ -2420,9 +2413,6 @@ public class MusicPlaybackService extends Service { final int[] largeAlt = intent .getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS); mAppWidgetLargeAlternate.performUpdate(MusicPlaybackService.this, largeAlt); - } else if (RecentWidgetProvider.CMDAPPWIDGETUPDATE.equals(command)) { - final int[] recent = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS); - mRecentWidgetProvider.performUpdate(MusicPlaybackService.this, recent); } else { handleCommandIntent(intent); } diff --git a/src/com/cyngn/eleven/adapters/ArtistAlbumAdapter.java b/src/com/cyngn/eleven/adapters/ArtistAlbumAdapter.java deleted file mode 100644 index e2fc49e..0000000 --- a/src/com/cyngn/eleven/adapters/ArtistAlbumAdapter.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.adapters; - -import android.app.Activity; -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ImageView; - -import com.cyngn.eleven.Config; -import com.cyngn.eleven.R; -import com.cyngn.eleven.cache.ImageFetcher; -import com.cyngn.eleven.model.Album; -import com.cyngn.eleven.ui.MusicHolder; -import com.cyngn.eleven.ui.fragments.profile.ArtistAlbumFragment; -import com.cyngn.eleven.utils.ApolloUtils; -import com.cyngn.eleven.utils.Lists; -import com.cyngn.eleven.utils.MusicUtils; - -import java.util.List; - -/** - * This {@link ArrayAdapter} is used to display the albums for a particular - * artist for {@link ArtistAlbumFragment} . - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -public class ArtistAlbumAdapter extends ArrayAdapter<Album> { - - /** - * The header view - */ - private static final int ITEM_VIEW_TYPE_HEADER = 0; - - /** - * * The data in the list. - */ - private static final int ITEM_VIEW_TYPE_MUSIC = 1; - - /** - * Number of views (ImageView, TextView, header) - */ - private static final int VIEW_TYPE_COUNT = 3; - - /** - * LayoutInflater - */ - private final LayoutInflater mInflater; - - /** - * Fake header - */ - private final View mHeader; - - /** - * The resource Id of the layout to inflate - */ - private final int mLayoutId; - - /** - * Image cache and image fetcher - */ - private final ImageFetcher mImageFetcher; - - /** - * Used to set the size of the data in the adapter - */ - private List<Album> mCount = Lists.newArrayList(); - - /** - * Constructor of <code>ArtistAlbumAdapter</code> - * - * @param context The {@link Context} to use - * @param layoutId The resource Id of the view to inflate. - */ - public ArtistAlbumAdapter(final Activity context, final int layoutId) { - super(context, 0); - // Used to create the custom layout - mInflater = LayoutInflater.from(context); - // Cache the header - mHeader = mInflater.inflate(R.layout.faux_carousel, null); - // Get the layout Id - mLayoutId = layoutId; - // Initialize the cache & image fetcher - mImageFetcher = ApolloUtils.getImageFetcher(context); - } - - /** - * {@inheritDoc} - */ - @Override - public View getView(final int position, View convertView, final ViewGroup parent) { - - // Return a faux header at position 0 - if (position == 0) { - return mHeader; - } - - // Recycle MusicHolder's items - MusicHolder holder; - if (convertView == null) { - convertView = LayoutInflater.from(getContext()).inflate(mLayoutId, parent, false); - holder = new MusicHolder(convertView); - // Remove the background layer - holder.mOverlay.get().setBackgroundColor(0); - convertView.setTag(holder); - } else { - holder = (MusicHolder)convertView.getTag(); - } - - // Retrieve the album - final Album album = getItem(position - 1); - final String albumName = album.mAlbumName; - - // Set each album name (line one) - holder.mLineOne.get().setText(albumName); - // Set the number of songs (line two) - holder.mLineTwo.get().setText(MusicUtils.makeLabel(getContext(), - R.plurals.Nsongs, album.mSongNumber)); - // Set the album year (line three) - holder.mLineThree.get().setText(album.mYear); - // Asynchronously load the album images into the adapter - mImageFetcher.loadAlbumImage(album.mArtistName, albumName, album.mAlbumId, - holder.mImage.get()); - // Play the album when the artwork is touched - playAlbum(holder.mImage.get(), position); - return convertView; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean hasStableIds() { - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public int getCount() { - final int size = mCount.size(); - return size == 0 ? 0 : size + 1; - } - - /** - * {@inheritDoc} - */ - @Override - public long getItemId(final int position) { - if (position == 0) { - return -1; - } - return position - 1; - } - - /** - * {@inheritDoc} - */ - @Override - public int getViewTypeCount() { - return VIEW_TYPE_COUNT; - } - - /** - * {@inheritDoc} - */ - @Override - public int getItemViewType(final int position) { - if (position == 0) { - return ITEM_VIEW_TYPE_HEADER; - } - return ITEM_VIEW_TYPE_MUSIC; - } - - /** - * Starts playing an album if the user touches the artwork in the list. - * - * @param album The {@link ImageView} holding the album - * @param position The position of the album to play. - */ - private void playAlbum(final ImageView album, final int position) { - album.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(final View v) { - final long id = getItem(position - 1).mAlbumId; - final long[] list = MusicUtils.getSongListForAlbum(getContext(), id); - MusicUtils.playAll(getContext(), list, 0, false); - } - }); - } - - /** - * Method that unloads and clears the items in the adapter - */ - public void unload() { - clear(); - } - - /** - * @param pause True to temporarily pause the disk cache, false otherwise. - */ - public void setPauseDiskCache(final boolean pause) { - if (mImageFetcher != null) { - mImageFetcher.setPauseDiskCache(pause); - } - } - - /** - * @param album The key used to find the cached album to remove - */ - public void removeFromCache(final Album album) { - if (mImageFetcher != null) { - mImageFetcher.removeFromCache( - ImageFetcher.generateAlbumCacheKey(album.mAlbumName, album.mArtistName)); - } - } - - /** - * @param data The {@link List} used to return the count for the adapter. - */ - public void setCount(final List<Album> data) { - mCount = data; - } - - /** - * Flushes the disk cache. - */ - public void flush() { - mImageFetcher.flush(); - } -} diff --git a/src/com/cyngn/eleven/adapters/GenreAdapter.java b/src/com/cyngn/eleven/adapters/GenreAdapter.java deleted file mode 100644 index 8d33ab8..0000000 --- a/src/com/cyngn/eleven/adapters/GenreAdapter.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.adapters; - -import android.content.Context; -import android.util.TypedValue; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; - -import com.cyngn.eleven.R; -import com.cyngn.eleven.model.Genre; -import com.cyngn.eleven.ui.MusicHolder; -import com.cyngn.eleven.ui.MusicHolder.DataHolder; -import com.cyngn.eleven.ui.fragments.GenreFragment; - -/** - * This {@link ArrayAdapter} is used to display all of the genres on a user's - * device for {@link GenreFragment} . - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -public class GenreAdapter extends ArrayAdapter<Genre> { - - /** - * Number of views (TextView) - */ - private static final int VIEW_TYPE_COUNT = 1; - - /** - * The resource Id of the layout to inflate - */ - private final int mLayoutId; - - /** - * Used to cache the genre info - */ - private DataHolder[] mData; - - /** - * Constructor of <code>GenreAdapter</code> - * - * @param context The {@link Context} to use. - * @param layoutId The resource Id of the view to inflate. - */ - public GenreAdapter(final Context context, final int layoutId) { - super(context, 0); - // Get the layout Id - mLayoutId = layoutId; - } - - /** - * {@inheritDoc} - */ - @Override - public View getView(final int position, View convertView, final ViewGroup parent) { - // Recycle ViewHolder's items - MusicHolder holder; - if (convertView == null) { - convertView = LayoutInflater.from(getContext()).inflate(mLayoutId, parent, false); - holder = new MusicHolder(convertView); - // Hide the second and third lines of text - holder.mLineTwo.get().setVisibility(View.GONE); - holder.mLineThree.get().setVisibility(View.GONE); - // Make line one slightly larger - holder.mLineOne.get().setTextSize(TypedValue.COMPLEX_UNIT_PX, - getContext().getResources().getDimension(R.dimen.text_size_large)); - convertView.setTag(holder); - } else { - holder = (MusicHolder)convertView.getTag(); - } - - // Retrieve the data holder - final DataHolder dataHolder = mData[position]; - - // Set each genre name (line one) - holder.mLineOne.get().setText(dataHolder.mLineOne); - return convertView; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean hasStableIds() { - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public int getViewTypeCount() { - return VIEW_TYPE_COUNT; - } - - /** - * Method used to cache the data used to populate the list or grid. The idea - * is to cache everything before {@code #getView(int, View, ViewGroup)} is - * called. - */ - public void buildCache() { - mData = new DataHolder[getCount()]; - for (int i = 0; i < getCount(); i++) { - // Build the artist - final Genre genre = getItem(i); - - // Build the data holder - mData[i] = new DataHolder(); - // Genre Id - mData[i].mItemId = genre.mGenreId; - // Genre names (line one) - mData[i].mLineOne = genre.mGenreName; - } - } - - /** - * Method that unloads and clears the items in the adapter - */ - public void unload() { - clear(); - mData = null; - } - -} diff --git a/src/com/cyngn/eleven/adapters/PagerAdapter.java b/src/com/cyngn/eleven/adapters/PagerAdapter.java index bfbf30a..3a0746b 100644 --- a/src/com/cyngn/eleven/adapters/PagerAdapter.java +++ b/src/com/cyngn/eleven/adapters/PagerAdapter.java @@ -22,9 +22,7 @@ import android.view.ViewGroup; import com.cyngn.eleven.R; import com.cyngn.eleven.ui.fragments.AlbumFragment; import com.cyngn.eleven.ui.fragments.ArtistFragment; -import com.cyngn.eleven.ui.fragments.GenreFragment; import com.cyngn.eleven.ui.fragments.PlaylistFragment; -import com.cyngn.eleven.ui.fragments.RecentFragment; import com.cyngn.eleven.ui.fragments.SongFragment; import com.cyngn.eleven.utils.Lists; diff --git a/src/com/cyngn/eleven/adapters/ProfileSongAdapter.java b/src/com/cyngn/eleven/adapters/ProfileSongAdapter.java index 682857b..dbde483 100644 --- a/src/com/cyngn/eleven/adapters/ProfileSongAdapter.java +++ b/src/com/cyngn/eleven/adapters/ProfileSongAdapter.java @@ -22,9 +22,6 @@ import com.cyngn.eleven.cache.ImageFetcher; import com.cyngn.eleven.model.Artist; import com.cyngn.eleven.model.Song; import com.cyngn.eleven.ui.MusicHolder; -import com.cyngn.eleven.ui.fragments.profile.AlbumSongFragment; -import com.cyngn.eleven.ui.fragments.profile.ArtistSongFragment; -import com.cyngn.eleven.ui.fragments.profile.GenreSongFragment; import com.cyngn.eleven.ui.fragments.profile.LastAddedFragment; import com.cyngn.eleven.ui.activities.PlaylistDetailActivity; import com.cyngn.eleven.utils.ApolloUtils; @@ -35,9 +32,8 @@ import java.util.List; /** * This {@link ArrayAdapter} is used to display the songs for a particular - * artist, album, playlist, or genre for {@link ArtistSongFragment}, - * {@link AlbumSongFragment},{@link PlaylistDetailActivity}, - * {@link GenreSongFragment},{@link LastAddedFragment}. + * artist, album, playlist, or genre for + * {@link PlaylistDetailActivity},{@link LastAddedFragment}. * * @author Andrew Neal (andrewdneal@gmail.com) */ @@ -125,16 +121,6 @@ public class ProfileSongAdapter extends ArrayAdapter<Song> { } /** - * Constructor of <code>ProfileSongAdapter</code> - * - * @param activity The {@link Activity} to use - * @param layoutId The resource Id of the view to inflate. - */ - public ProfileSongAdapter(final Activity activity, final int layoutId) { - this(activity, layoutId, R.layout.faux_carousel, DISPLAY_DEFAULT_SETTING); - } - - /** * {@inheritDoc} */ @Override diff --git a/src/com/cyngn/eleven/appwidgets/RecentWidgetProvider.java b/src/com/cyngn/eleven/appwidgets/RecentWidgetProvider.java deleted file mode 100644 index c28f89c..0000000 --- a/src/com/cyngn/eleven/appwidgets/RecentWidgetProvider.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.appwidgets; - -import android.annotation.TargetApi; -import android.app.PendingIntent; -import android.appwidget.AppWidgetManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; -import android.provider.MediaStore; -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.HomeActivity; -import com.cyngn.eleven.ui.fragments.AudioPlayerFragment; -import com.cyngn.eleven.ui.activities.ProfileActivity; -import com.cyngn.eleven.ui.activities.ShortcutActivity; -import com.cyngn.eleven.utils.MusicUtils; - -/** - * App-Widget used to display a list of recently listened albums. - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -@TargetApi(11) -public class RecentWidgetProvider extends AppWidgetBase { - - public static final String SET_ACTION = "set_action"; - - public static final String OPEN_PROFILE = "open_profile"; - - public static final String PLAY_ALBUM = "play_album"; - - public static final String CMDAPPWIDGETUPDATE = "app_widget_recents_update"; - - public static final String CLICK_ACTION = "com.cyngn.eleven.recents.appwidget.action.CLICK"; - - public static final String REFRESH_ACTION = "com.cyngn.eleven.recents.appwidget.action.REFRESH"; - - private static Handler sWorkerQueue; - - private static RecentWidgetProvider mInstance; - - private RemoteViews mViews; - - /** - * Constructor of <code>RecentWidgetProvider</code> - */ - public RecentWidgetProvider() { - // Start the worker thread - final HandlerThread workerThread = new HandlerThread("RecentWidgetProviderWorker", - android.os.Process.THREAD_PRIORITY_BACKGROUND); - workerThread.start(); - sWorkerQueue = new Handler(workerThread.getLooper()); - } - - /** - * @return A singelton of {@link RecentWidgetProvider} - */ - public static synchronized RecentWidgetProvider getInstance() { - if (mInstance == null) { - mInstance = new RecentWidgetProvider(); - } - return mInstance; - } - - /** - * {@inheritDoc} - */ - @Override - public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, - final int[] appWidgetIds) { - for (final int appWidgetId : appWidgetIds) { - // Create the remote views - mViews = new RemoteViews(context.getPackageName(), R.layout.app_widget_recents); - - // Link actions buttons to intents - linkButtons(context, mViews, false); - - final Intent intent = new Intent(context, RecentWidgetService.class); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); - intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); - compatSetRemoteAdapter(mViews, appWidgetId, intent); - - final Intent updateIntent = new Intent(MusicPlaybackService.SERVICECMD); - updateIntent.putExtra(MusicPlaybackService.CMDNAME, - RecentWidgetProvider.CMDAPPWIDGETUPDATE); - updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); - updateIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); - context.sendBroadcast(updateIntent); - - final Intent onClickIntent = new Intent(context, RecentWidgetProvider.class); - onClickIntent.setAction(RecentWidgetProvider.CLICK_ACTION); - onClickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); - onClickIntent.setData(Uri.parse(onClickIntent.toUri(Intent.URI_INTENT_SCHEME))); - final PendingIntent onClickPendingIntent = PendingIntent.getBroadcast(context, 0, - onClickIntent, PendingIntent.FLAG_UPDATE_CURRENT); - mViews.setPendingIntentTemplate(R.id.app_widget_recents_list, onClickPendingIntent); - - // Update the widget - appWidgetManager.updateAppWidget(appWidgetId, mViews); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onReceive(final Context context, final Intent intent) { - final String action = intent.getAction(); - - if (CLICK_ACTION.equals(action)) { - final long albumId = intent.getLongExtra(Config.ID, -1); - - if (intent.getStringExtra(SET_ACTION).equals(PLAY_ALBUM)) { - // Play the selected album - if (albumId != -1) { - final Intent shortcutIntent = new Intent(context, ShortcutActivity.class); - shortcutIntent.setAction(Intent.ACTION_VIEW); - shortcutIntent.putExtra(Config.ID, albumId); - shortcutIntent.putExtra(Config.MIME_TYPE, MediaStore.Audio.Albums.CONTENT_TYPE); - shortcutIntent.putExtra(ShortcutActivity.OPEN_AUDIO_PLAYER, false); - shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(shortcutIntent); - } - } else if (intent.getStringExtra(SET_ACTION).equals(OPEN_PROFILE)) { - final String albumName = intent.getStringExtra(Config.NAME); - // Transfer the album name and MIME type - final Bundle bundle = new Bundle(); - bundle.putString(Config.MIME_TYPE, MediaStore.Audio.Albums.CONTENT_TYPE); - bundle.putString(Config.NAME, albumName); - bundle.putString(Config.ARTIST_NAME, intent.getStringExtra(Config.ARTIST_NAME)); - bundle.putString(Config.ALBUM_YEAR, - MusicUtils.getReleaseDateForAlbum(context, albumId)); - bundle.putLong(Config.ID, albumId); - - // Open the album profile - final Intent profileIntent = new Intent(context, ProfileActivity.class); - profileIntent.putExtras(bundle); - profileIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - profileIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - if (albumId != -1) { - context.startActivity(profileIntent); - } - } - - } - super.onReceive(context, intent); - } - - @SuppressWarnings("deprecation") - @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) - private void compatSetRemoteAdapter(final RemoteViews rv, final int appWidgetId, - final Intent intent) { - rv.setRemoteAdapter(R.id.app_widget_recents_list, intent); - } - - /** - * Check against {@link AppWidgetManager} if there are any instances of this - * widget. - */ - private boolean hasInstances(final Context context) { - final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); - final int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, this - .getClass())); - return appWidgetIds.length > 0; - } - - private void pushUpdate(final Context context, final int[] appWidgetIds, final RemoteViews views) { - final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); - if (appWidgetIds != null) { - appWidgetManager.updateAppWidget(appWidgetIds, views); - } else { - appWidgetManager.updateAppWidget(new ComponentName(context, this.getClass()), views); - } - } - - /** - * Handle a change notification coming over from - * {@link MusicPlaybackService} - */ - public void notifyChange(final MusicPlaybackService service, final String what) { - if (hasInstances(service)) { - if (MusicPlaybackService.PLAYSTATE_CHANGED.equals(what)) { - performUpdate(service, null); - } else if (MusicPlaybackService.META_CHANGED.equals(what)) { - synchronized (service) { - sWorkerQueue.post(new Runnable() { - @Override - public void run() { - final AppWidgetManager appWidgetManager = AppWidgetManager - .getInstance(service); - final ComponentName componentName = new ComponentName(service, - RecentWidgetProvider.class); - appWidgetManager.notifyAppWidgetViewDataChanged( - appWidgetManager.getAppWidgetIds(componentName), - R.id.app_widget_recents_list); - } - }); - } - } - } - } - - /** - * Update all active widget instances by pushing changes - */ - public void performUpdate(final MusicPlaybackService service, final int[] appWidgetIds) { - mViews = new RemoteViews(service.getPackageName(), R.layout.app_widget_recents); - - /* Set correct drawable for pause state */ - final boolean isPlaying = service.isPlaying(); - if (isPlaying) { - mViews.setImageViewResource(R.id.app_widget_recents_play, R.drawable.btn_playback_pause); - } else { - mViews.setImageViewResource(R.id.app_widget_recents_play, R.drawable.btn_playback_play); - } - - // Link actions buttons to intents - linkButtons(service, mViews, isPlaying); - - // Update the app-widget - pushUpdate(service, appWidgetIds, mViews); - } - - /** - * Link up various button actions using {@link PendingIntents}. - * - * @param playerActive True if player is active in background, which means - * widget click will launch {@link AudioPlayerFragment}, - * otherwise we launch {@link MusicBrowserActivity}. - */ - private void linkButtons(final Context context, final RemoteViews views, - final boolean playerActive) { - Intent action; - PendingIntent pendingIntent; - - final ComponentName serviceName = new ComponentName(context, MusicPlaybackService.class); - - // Now playing - if (playerActive) { - action = new Intent(context, HomeActivity.class); - action.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - 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.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - action.setAction(HomeActivity.ACTION_VIEW_BROWSE); - pendingIntent = PendingIntent.getActivity(context, 0, action, 0); - views.setOnClickPendingIntent(R.id.app_widget_recents_action_bar, pendingIntent); - } - - // Previous track - pendingIntent = buildPendingIntent(context, MusicPlaybackService.PREVIOUS_ACTION, serviceName); - views.setOnClickPendingIntent(R.id.app_widget_recents_previous, pendingIntent); - - // Play and pause - pendingIntent = buildPendingIntent(context, MusicPlaybackService.TOGGLEPAUSE_ACTION, serviceName); - views.setOnClickPendingIntent(R.id.app_widget_recents_play, pendingIntent); - - // Next track - pendingIntent = buildPendingIntent(context, MusicPlaybackService.NEXT_ACTION, serviceName); - views.setOnClickPendingIntent(R.id.app_widget_recents_next, pendingIntent); - } - -} diff --git a/src/com/cyngn/eleven/appwidgets/RecentWidgetService.java b/src/com/cyngn/eleven/appwidgets/RecentWidgetService.java deleted file mode 100644 index d687358..0000000 --- a/src/com/cyngn/eleven/appwidgets/RecentWidgetService.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.appwidgets; - -import android.annotation.TargetApi; -import android.content.Context; -import android.content.Intent; -import android.database.Cursor; -import android.graphics.Bitmap; -import android.os.Bundle; -import android.widget.RemoteViews; -import android.widget.RemoteViewsService; - -import com.cyngn.eleven.Config; -import com.cyngn.eleven.R; -import com.cyngn.eleven.cache.ImageCache; -import com.cyngn.eleven.cache.ImageFetcher; -import com.cyngn.eleven.provider.RecentStore; -import com.cyngn.eleven.provider.RecentStore.RecentStoreColumns; - -/** - * This class is used to build the recently listened list for the - * {@link RecentWidgetProvicer}. - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -@TargetApi(11) -public class RecentWidgetService extends RemoteViewsService { - - /** - * {@inheritDoc} - */ - @Override - public RemoteViewsFactory onGetViewFactory(final Intent intent) { - return new WidgetRemoteViewsFactory(getApplicationContext()); - } - - /** - * This is the factory that will provide data to the collection widget. - */ - private static final class WidgetRemoteViewsFactory implements - RemoteViewsService.RemoteViewsFactory { - /** - * Number of views (ImageView and TextView) - */ - private static final int VIEW_TYPE_COUNT = 2; - - /** - * The context to use - */ - private final Context mContext; - - /** - * Image cache - */ - private final ImageFetcher mFetcher; - - /** - * Recents db - */ - private final RecentStore mRecentsStore; - - /** - * Cursor to use - */ - private Cursor mCursor; - - /** - * Remove views - */ - private RemoteViews mViews; - - /** - * Constructor of <code>WidgetRemoteViewsFactory</code> - * - * @param context The {@link Context} to use. - */ - public WidgetRemoteViewsFactory(final Context context) { - // Get the context - mContext = context; - // Initialze the image cache - mFetcher = ImageFetcher.getInstance(context); - mFetcher.setImageCache(ImageCache.getInstance(context)); - // Initialze the recents store - mRecentsStore = RecentStore.getInstance(context); - } - - /** - * {@inheritDoc} - */ - @Override - public int getCount() { - // Check for errors - if (mCursor == null || mCursor.isClosed() || mCursor.getCount() <= 0) { - return 0; - } - return mCursor.getCount(); - } - - /** - * {@inheritDoc} - */ - @Override - public long getItemId(final int position) { - return position; - } - - /** - * {@inheritDoc} - */ - @Override - public RemoteViews getViewAt(final int position) { - mCursor.moveToPosition(position); - - // Create the remote views - mViews = new RemoteViews(mContext.getPackageName(), R.layout.app_widget_recents_items); - - // Copy the album id - final long id = mCursor.getLong(mCursor - .getColumnIndexOrThrow(RecentStoreColumns.ID)); - - // Copy the album name - final String albumName = mCursor.getString(mCursor - .getColumnIndexOrThrow(RecentStoreColumns.ALBUMNAME)); - - // Copy the artist name - final String artist = mCursor.getString(mCursor - .getColumnIndexOrThrow(RecentStoreColumns.ARTISTNAME)); - - // Set the album names - mViews.setTextViewText(R.id.app_widget_recents_line_one, albumName); - // Set the artist names - mViews.setTextViewText(R.id.app_widget_recents_line_two, artist); - // Set the album art - Bitmap bitmap = mFetcher.getCachedArtwork(albumName, artist, id); - if (bitmap != null) { - mViews.setImageViewBitmap(R.id.app_widget_recents_base_image, bitmap); - } else { - mViews.setImageViewResource(R.id.app_widget_recents_base_image, - R.drawable.default_artwork); - } - - // Open the profile of the touched album - final Intent profileIntent = new Intent(); - final Bundle profileExtras = new Bundle(); - profileExtras.putLong(Config.ID, id); - profileExtras.putString(Config.NAME, albumName); - profileExtras.putString(Config.ARTIST_NAME, artist); - profileExtras.putString(RecentWidgetProvider.SET_ACTION, - RecentWidgetProvider.OPEN_PROFILE); - profileIntent.putExtras(profileExtras); - mViews.setOnClickFillInIntent(R.id.app_widget_recents_items, profileIntent); - - // Play the album when the artwork is touched - final Intent playAlbum = new Intent(); - final Bundle playAlbumExtras = new Bundle(); - playAlbumExtras.putLong(Config.ID, id); - playAlbumExtras.putString(RecentWidgetProvider.SET_ACTION, - RecentWidgetProvider.PLAY_ALBUM); - playAlbum.putExtras(playAlbumExtras); - mViews.setOnClickFillInIntent(R.id.app_widget_recents_base_image, playAlbum); - return mViews; - } - - /** - * {@inheritDoc} - */ - @Override - public int getViewTypeCount() { - return VIEW_TYPE_COUNT; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean hasStableIds() { - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public void onDataSetChanged() { - if (mCursor != null && !mCursor.isClosed()) { - mCursor.close(); - mCursor = null; - } - mCursor = mRecentsStore.getReadableDatabase().query( - RecentStoreColumns.NAME, - new String[] { - RecentStoreColumns.ID + " as id", RecentStoreColumns.ID, - RecentStoreColumns.ALBUMNAME, RecentStoreColumns.ARTISTNAME, - RecentStoreColumns.ALBUMSONGCOUNT, RecentStoreColumns.ALBUMYEAR, - RecentStoreColumns.TIMEPLAYED - }, null, null, null, null, RecentStoreColumns.TIMEPLAYED + " DESC"); - } - - /** - * {@inheritDoc} - */ - @Override - public void onDestroy() { - closeCursor(); - } - - /** - * {@inheritDoc} - */ - @Override - public RemoteViews getLoadingView() { - // Nothing to do - return null; - } - - /** - * {@inheritDoc} - */ - @Override - public void onCreate() { - // Nothing to do - } - - private void closeCursor() { - if (mCursor != null && !mCursor.isClosed()) { - mCursor.close(); - mCursor = null; - } - } - } -} diff --git a/src/com/cyngn/eleven/loaders/GenreLoader.java b/src/com/cyngn/eleven/loaders/GenreLoader.java deleted file mode 100644 index 7d102dd..0000000 --- a/src/com/cyngn/eleven/loaders/GenreLoader.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.loaders; - -import android.content.Context; -import android.database.Cursor; -import android.provider.BaseColumns; -import android.provider.MediaStore; -import android.provider.MediaStore.Audio.GenresColumns; - -import com.cyngn.eleven.model.Genre; -import com.cyngn.eleven.utils.Lists; - -import java.util.ArrayList; -import java.util.List; - -/** - * Used to query {@link MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI} and return - * the genres on a user's device. - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -public class GenreLoader extends WrappedAsyncTaskLoader<List<Genre>> { - - /** - * The result - */ - private final ArrayList<Genre> mGenreList = Lists.newArrayList(); - - /** - * The {@link Cursor} used to run the query. - */ - private Cursor mCursor; - - /** - * Constructor of <code>GenreLoader</code> - * - * @param context The {@link Context} to use - */ - public GenreLoader(final Context context) { - super(context); - } - - /** - * {@inheritDoc} - */ - @Override - public List<Genre> loadInBackground() { - // Create the Cursor - mCursor = makeGenreCursor(getContext()); - // Gather the data - if (mCursor != null && mCursor.moveToFirst()) { - do { - // Copy the genre id - final long id = mCursor.getLong(0); - - // Copy the genre name - final String name = mCursor.getString(1); - - // Create a new genre - final Genre genre = new Genre(id, name); - - // Add everything up - mGenreList.add(genre); - } while (mCursor.moveToNext()); - } - // Close the cursor - if (mCursor != null) { - mCursor.close(); - mCursor = null; - } - return mGenreList; - } - - /** - * Creates the {@link Cursor} used to run the query. - * - * @param context The {@link Context} to use. - * @return The {@link Cursor} used to run the genre query. - */ - public static final Cursor makeGenreCursor(final Context context) { - final StringBuilder selection = new StringBuilder(); - selection.append(MediaStore.Audio.Genres.NAME + " != ''"); - return context.getContentResolver().query(MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI, - new String[] { - /* 0 */ - BaseColumns._ID, - /* 1 */ - GenresColumns.NAME - }, selection.toString(), null, MediaStore.Audio.Genres.DEFAULT_SORT_ORDER); - } -} diff --git a/src/com/cyngn/eleven/loaders/GenreSongLoader.java b/src/com/cyngn/eleven/loaders/GenreSongLoader.java deleted file mode 100644 index dca0a49..0000000 --- a/src/com/cyngn/eleven/loaders/GenreSongLoader.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.loaders; - -import android.content.Context; -import android.database.Cursor; -import android.provider.MediaStore; - -import com.cyngn.eleven.model.Song; -import com.cyngn.eleven.utils.Lists; - -import java.util.ArrayList; -import java.util.List; - -/** - * Used to query {@link MediaStore.Audio.Genres.Members.EXTERNAL_CONTENT_URI} - * and return the songs for a particular genre. - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -public class GenreSongLoader extends WrappedAsyncTaskLoader<List<Song>> { - - /** - * The result - */ - private final ArrayList<Song> mSongList = Lists.newArrayList(); - - /** - * The {@link Cursor} used to run the query. - */ - private Cursor mCursor; - - /** - * The Id of the genre the songs belong to. - */ - private final Long mGenreID; - - /** - * Constructor of <code>GenreSongHandler</code> - * - * @param context The {@link Context} to use. - * @param genreID The Id of the genre the songs belong to. - */ - public GenreSongLoader(final Context context, final Long genreId) { - super(context); - mGenreID = genreId; - } - - /** - * {@inheritDoc} - */ - @Override - public List<Song> loadInBackground() { - // Create the Cursor - mCursor = makeGenreSongCursor(getContext(), mGenreID); - // Gather the data - if (mCursor != null && mCursor.moveToFirst()) { - do { - // Copy the song Id - final long id = mCursor.getLong(0); - - // Copy the song name - final String songName = mCursor.getString(1); - - // Copy the album name - final String album = mCursor.getString(2); - - // Copy the artist name - final String artist = mCursor.getString(3); - - // Copy the duration - final long duration = mCursor.getLong(4); - - // Convert the duration into seconds - final int durationInSecs = (int) duration / 1000; - - // Grab the Song Year - final int year = mCursor.getInt(5); - - // Create a new song - final Song song = new Song(id, songName, artist, album, -1, durationInSecs, year); - - // Add everything up - mSongList.add(song); - } while (mCursor.moveToNext()); - } - // Close the cursor - if (mCursor != null) { - mCursor.close(); - mCursor = null; - } - return mSongList; - } - - /** - * @param context The {@link Context} to use. - * @param genreId The Id of the genre the songs belong to. - * @return The {@link Cursor} used to run the query. - */ - public static final Cursor makeGenreSongCursor(final Context context, final Long genreId) { - // Match the songs up with the genre - final StringBuilder selection = new StringBuilder(); - selection.append(MediaStore.Audio.Genres.Members.IS_MUSIC + "=1"); - selection.append(" AND " + MediaStore.Audio.Genres.Members.TITLE + "!=''"); //$NON-NLS-2$ - return context.getContentResolver().query( - MediaStore.Audio.Genres.Members.getContentUri("external", genreId), new String[] { - /* 0 */ - MediaStore.Audio.Genres.Members._ID, - /* 1 */ - MediaStore.Audio.Genres.Members.TITLE, - /* 2 */ - MediaStore.Audio.Genres.Members.ALBUM, - /* 3 */ - MediaStore.Audio.Genres.Members.ARTIST, - /* 4 */ - MediaStore.Audio.Genres.Members.DURATION, - /* 5 */ - MediaStore.Audio.Genres.Members.YEAR, - }, selection.toString(), null, MediaStore.Audio.Genres.Members.DEFAULT_SORT_ORDER); - } -} diff --git a/src/com/cyngn/eleven/menu/PhotoSelectionDialog.java b/src/com/cyngn/eleven/menu/PhotoSelectionDialog.java deleted file mode 100644 index 5b9245f..0000000 --- a/src/com/cyngn/eleven/menu/PhotoSelectionDialog.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.menu; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.DialogInterface; -import android.os.Bundle; -import android.support.v4.app.DialogFragment; -import android.widget.ArrayAdapter; -import android.widget.ListAdapter; - -import com.cyngn.eleven.Config; -import com.cyngn.eleven.R; -import com.cyngn.eleven.ui.activities.ProfileActivity; -import com.cyngn.eleven.utils.ApolloUtils; -import com.cyngn.eleven.utils.Lists; - -import java.util.ArrayList; - -/** - * Used when the user touches the image in the header in {@link ProfileActivity} - * . It provides an easy interface for them to choose a new image, use the old - * image, or search Google for one. - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -public class PhotoSelectionDialog extends DialogFragment { - - private static final int NEW_PHOTO = 0; - - private static final int OLD_PHOTO = 1; - - private static final int GOOGLE_SEARCH = 2; - - private static final int FETCH_IMAGE = 3; - - private final ArrayList<String> mChoices = Lists.newArrayList(); - - private static ProfileType mProfileType; - - /** - * Empty constructor as per the {@link Fragment} documentation - */ - public PhotoSelectionDialog() { - } - - /** - * @param title The dialog title. - * @param value The MIME type - * @return A new instance of the dialog. - */ - public static PhotoSelectionDialog newInstance(final String title, final ProfileType type) { - final PhotoSelectionDialog frag = new PhotoSelectionDialog(); - final Bundle args = new Bundle(); - args.putString(Config.NAME, title); - frag.setArguments(args); - mProfileType = type; - return frag; - } - - /** - * {@inheritDoc} - */ - @Override - public Dialog onCreateDialog(final Bundle savedInstanceState) { - final String title = getArguments().getString(Config.NAME); - switch (mProfileType) { - case ARTIST: - setArtistChoices(); - break; - case ALBUM: - setAlbumChoices(); - break; - case OTHER: - setOtherChoices(); - break; - default: - break; - } - // Dialog item Adapter - final ProfileActivity activity = (ProfileActivity) getActivity(); - final ListAdapter adapter = new ArrayAdapter<String>(activity, - android.R.layout.select_dialog_item, mChoices); - return new AlertDialog.Builder(activity).setTitle(title) - .setAdapter(adapter, new DialogInterface.OnClickListener() { - - @Override - public void onClick(final DialogInterface dialog, final int which) { - switch (which) { - case NEW_PHOTO: - activity.selectNewPhoto(); - break; - case OLD_PHOTO: - activity.selectOldPhoto(); - break; - case FETCH_IMAGE: - activity.fetchAlbumArt(); - break; - case GOOGLE_SEARCH: - activity.googleSearch(); - break; - default: - break; - } - } - }).create(); - } - - /** - * Adds the choices for the artist profile image. - */ - private void setArtistChoices() { - // Select a photo from the gallery - mChoices.add(NEW_PHOTO, getString(R.string.new_photo)); - if (ApolloUtils.isOnline(getActivity())) { - // Option to fetch the old artist image - mChoices.add(OLD_PHOTO, getString(R.string.context_menu_fetch_artist_image)); - // Search Google for the artist name - mChoices.add(GOOGLE_SEARCH, getString(R.string.google_search)); - } - } - - /** - * Adds the choices for the album profile image. - */ - private void setAlbumChoices() { - // Select a photo from the gallery - mChoices.add(NEW_PHOTO, getString(R.string.new_photo)); - // Option to fetch the old album image - mChoices.add(OLD_PHOTO, getString(R.string.old_photo)); - if (ApolloUtils.isOnline(getActivity())) { - // Search Google for the album name - mChoices.add(GOOGLE_SEARCH, getString(R.string.google_search)); - // Option to fetch the album image - mChoices.add(FETCH_IMAGE, getString(R.string.context_menu_fetch_album_art)); - } - } - - /** - * Adds the choices for the genre and playlist images. - */ - private void setOtherChoices() { - // Select a photo from the gallery - mChoices.add(NEW_PHOTO, getString(R.string.new_photo)); - // Option to use the default image - mChoices.add(OLD_PHOTO, getString(R.string.use_default)); - } - - /** - * Easily detect the MIME type - */ - public enum ProfileType { - ARTIST, ALBUM, OTHER - } -} diff --git a/src/com/cyngn/eleven/ui/MusicHolder.java b/src/com/cyngn/eleven/ui/MusicHolder.java index ffce576..4cc8bdd 100644 --- a/src/com/cyngn/eleven/ui/MusicHolder.java +++ b/src/com/cyngn/eleven/ui/MusicHolder.java @@ -19,7 +19,6 @@ import android.widget.RelativeLayout; import android.widget.TextView; import com.cyngn.eleven.R; -import com.cyngn.eleven.appwidgets.RecentWidgetService; import com.cyngn.eleven.widgets.PlayPauseProgressButton; import java.lang.ref.WeakReference; @@ -167,11 +166,6 @@ public class MusicHolder { public String mLineThree; /** - * This is the album art bitmap used in {@link RecentWidgetService}. - */ - public Bitmap mImage; - - /** * Constructor of <code>DataHolder</code> */ public DataHolder() { diff --git a/src/com/cyngn/eleven/ui/activities/BaseActivity.java b/src/com/cyngn/eleven/ui/activities/BaseActivity.java index a39e2c7..b6dc98f 100644 --- a/src/com/cyngn/eleven/ui/activities/BaseActivity.java +++ b/src/com/cyngn/eleven/ui/activities/BaseActivity.java @@ -324,9 +324,6 @@ public abstract class BaseActivity extends FragmentActivity implements ServiceCo } else { MusicUtils.shuffleAll(BaseActivity.this); } - if (BaseActivity.this instanceof ProfileActivity) { - finish(); - } } }; diff --git a/src/com/cyngn/eleven/ui/activities/ProfileActivity.java b/src/com/cyngn/eleven/ui/activities/ProfileActivity.java deleted file mode 100644 index 0fb8d4e..0000000 --- a/src/com/cyngn/eleven/ui/activities/ProfileActivity.java +++ /dev/null @@ -1,635 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.ui.activities; - -import android.app.ActionBar; -import android.app.Activity; -import android.app.SearchManager; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.database.Cursor; -import android.graphics.Bitmap; -import android.net.Uri; -import android.os.Bundle; -import android.os.SystemClock; -import android.provider.MediaStore; -import android.support.v4.view.ViewPager; -import android.support.v4.view.ViewPager.OnPageChangeListener; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; - -import com.cyngn.eleven.Config; -import com.cyngn.eleven.R; -import com.cyngn.eleven.adapters.PagerAdapter; -import com.cyngn.eleven.cache.ImageFetcher; -import com.cyngn.eleven.menu.PhotoSelectionDialog; -import com.cyngn.eleven.menu.PhotoSelectionDialog.ProfileType; -import com.cyngn.eleven.ui.fragments.profile.AlbumSongFragment; -import com.cyngn.eleven.ui.fragments.profile.ArtistAlbumFragment; -import com.cyngn.eleven.ui.fragments.profile.ArtistSongFragment; -import com.cyngn.eleven.ui.fragments.profile.GenreSongFragment; -import com.cyngn.eleven.ui.fragments.profile.LastAddedFragment; -import com.cyngn.eleven.utils.ApolloUtils; -import com.cyngn.eleven.utils.ImageUtils; -import com.cyngn.eleven.utils.MusicUtils; -import com.cyngn.eleven.utils.NavUtils; -import com.cyngn.eleven.utils.PreferenceUtils; -import com.cyngn.eleven.utils.SortOrder; -import com.cyngn.eleven.widgets.ProfileTabCarousel; -import com.cyngn.eleven.widgets.ProfileTabCarousel.Listener; - -/** - * The {@link Activity} is used to display the data for specific - * artists, albums, playlists, and genres. This class is only used on phones. - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -public class ProfileActivity extends SlidingPanelActivity implements OnPageChangeListener, Listener { - - private static final int NEW_PHOTO = 1; - - /** - * The Bundle to pass into the Fragments - */ - private Bundle mArguments; - - /** - * View pager - */ - private ViewPager mViewPager; - - /** - * Pager adpater - */ - private PagerAdapter mPagerAdapter; - - /** - * Profile header carousel - */ - private ProfileTabCarousel mTabCarousel; - - /** - * MIME type of the profile - */ - private String mType; - - /** - * Artist name passed into the class - */ - private String mArtistName; - - /** - * The main profile title - */ - private String mProfileName; - - /** - * Image cache - */ - private ImageFetcher mImageFetcher; - - private PreferenceUtils mPreferences; - - /** - * {@inheritDoc} - */ - @Override - public void onCreate(final Bundle savedInstanceState) { - mTargetNavigatePanel = Panel.Browse; - super.onCreate(savedInstanceState); - // Temporay until I can work out a nice landscape layout - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - - // Get the preferences - mPreferences = PreferenceUtils.getInstance(this); - - // Initialze the image fetcher - mImageFetcher = ApolloUtils.getImageFetcher(this); - - // Initialize the Bundle - mArguments = savedInstanceState != null ? savedInstanceState : getIntent().getExtras(); - // Get the MIME type - mType = mArguments.getString(Config.MIME_TYPE); - // Get the profile title - mProfileName = mArguments.getString(Config.NAME); - // Get the artist name - if (isArtist() || isAlbum()) { - mArtistName = mArguments.getString(Config.ARTIST_NAME); - } - - // Initialize the pager adapter - mPagerAdapter = new PagerAdapter(this); - - // Initialze the carousel - mTabCarousel = (ProfileTabCarousel)findViewById(R.id.acivity_profile_base_tab_carousel); - mTabCarousel.reset(); - mTabCarousel.getPhoto().setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(final View v) { - ProfileType profileType; - if (isArtist()) { - profileType = ProfileType.ARTIST; - } else if (isAlbum()) { - profileType = ProfileType.ALBUM; - } else { - profileType = ProfileType.OTHER; - } - PhotoSelectionDialog.newInstance(isArtist() ? mArtistName : mProfileName, - profileType).show(getSupportFragmentManager(), "PhotoSelectionDialog"); - } - }); - // Set up the action bar - final ActionBar actionBar = getActionBar(); - actionBar.setIcon(R.drawable.ic_action_back); - actionBar.setHomeButtonEnabled(true); - - /* Set up the artist profile */ - if (isArtist()) { - // Add the carousel images - mTabCarousel.setArtistProfileHeader(this, mArtistName); - - // Artist profile fragments - mPagerAdapter.add(ArtistSongFragment.class, mArguments); - mPagerAdapter.add(ArtistAlbumFragment.class, mArguments); - - // Action bar title - getActionBar().setTitle(mArtistName); - - } else - // Set up the album profile - if (isAlbum()) { - // Add the carousel images - mTabCarousel.setAlbumProfileHeader(this, mProfileName, mArtistName); - - // Album profile fragments - mPagerAdapter.add(AlbumSongFragment.class, mArguments); - - // Action bar title = album name - getActionBar().setTitle(mProfileName); - // Action bar subtitle = year released - getActionBar().setSubtitle(mArguments.getString(Config.ALBUM_YEAR)); - } else - // Set up the last added profile - if (isLastAdded()) { - // Add the carousel images - mTabCarousel.setPlaylistOrGenreProfileHeader(this, mProfileName); - - // Last added fragment - mPagerAdapter.add(LastAddedFragment.class, null); - - // Action bar title = Last added - getActionBar().setTitle(mProfileName); - } else - // Set up the genre profile - if (isGenre()) { - // Add the carousel images - mTabCarousel.setPlaylistOrGenreProfileHeader(this, mProfileName); - - // Genre profile fragments - mPagerAdapter.add(GenreSongFragment.class, mArguments); - - // Action bar title = playlist name - getActionBar().setTitle(mProfileName); - } - - // Initialize the ViewPager - mViewPager = (ViewPager)findViewById(R.id.acivity_profile_base_pager); - // Attch the adapter - mViewPager.setAdapter(mPagerAdapter); - // Offscreen limit - mViewPager.setOffscreenPageLimit(mPagerAdapter.getCount() - 1); - // Attach the page change listener - mViewPager.setOnPageChangeListener(this); - // Attach the carousel listener - mTabCarousel.setListener(this); - } - - @Override - protected int getLayoutToInflate() { - return R.layout.activity_profile_base; - } - - /** - * {@inheritDoc} - */ - @Override - protected void onPause() { - super.onPause(); - mImageFetcher.flush(); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean onPrepareOptionsMenu(final Menu menu) { - // Set the shuffle all title to "play all" if a playlist. - final MenuItem shuffle = menu.findItem(R.id.menu_shuffle); - String title = null; - if (isLastAdded()) { - title = getString(R.string.menu_play_all); - } else { - title = getString(R.string.menu_shuffle); - } - shuffle.setTitle(title); - return super.onPrepareOptionsMenu(menu); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean onCreateOptionsMenu(final Menu menu) { - // Shuffle - getMenuInflater().inflate(R.menu.shuffle, menu); - // Sort orders - if (isArtistSongPage()) { - getMenuInflater().inflate(R.menu.artist_song_sort_by, menu); - } else if (isArtistAlbumPage()) { - getMenuInflater().inflate(R.menu.artist_album_sort_by, menu); - } else if (isAlbum()) { - getMenuInflater().inflate(R.menu.album_song_sort_by, menu); - } - return super.onCreateOptionsMenu(menu); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean onOptionsItemSelected(final MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - // If an album profile, go up to the artist profile - if (isAlbum()) { - NavUtils.openArtistProfile(this, mArtistName); - finish(); - } else { - // Otherwise just go back - goBack(); - } - return true; - case R.id.menu_shuffle: { - final long id = mArguments.getLong(Config.ID); - long[] list = null; - if (isArtist()) { - list = MusicUtils.getSongListForArtist(this, id); - } else if (isAlbum()) { - list = MusicUtils.getSongListForAlbum(this, id); - } else if (isGenre()) { - list = MusicUtils.getSongListForGenre(this, id); - } - if (isLastAdded()) { - MusicUtils.playLastAdded(this); - } else { - if (list != null && list.length > 0) { - MusicUtils.playAll(this, list, 0, true); - } - } - return true; - } - case R.id.menu_sort_by_az: - if (isArtistSongPage()) { - mPreferences.setArtistSongSortOrder(SortOrder.ArtistSongSortOrder.SONG_A_Z); - getArtistSongFragment().refresh(); - } else if (isArtistAlbumPage()) { - mPreferences.setArtistAlbumSortOrder(SortOrder.ArtistAlbumSortOrder.ALBUM_A_Z); - getArtistAlbumFragment().refresh(); - } else { - mPreferences.setAlbumSongSortOrder(SortOrder.AlbumSongSortOrder.SONG_A_Z); - getAlbumSongFragment().refresh(); - } - return true; - case R.id.menu_sort_by_za: - if (isArtistSongPage()) { - mPreferences.setArtistSongSortOrder(SortOrder.ArtistSongSortOrder.SONG_Z_A); - getArtistSongFragment().refresh(); - } else if (isArtistAlbumPage()) { - mPreferences.setArtistAlbumSortOrder(SortOrder.ArtistAlbumSortOrder.ALBUM_Z_A); - getArtistAlbumFragment().refresh(); - } else { - mPreferences.setAlbumSongSortOrder(SortOrder.AlbumSongSortOrder.SONG_Z_A); - getAlbumSongFragment().refresh(); - } - return true; - case R.id.menu_sort_by_album: - if (isArtistSongPage()) { - mPreferences.setArtistSongSortOrder(SortOrder.ArtistSongSortOrder.SONG_ALBUM); - getArtistSongFragment().refresh(); - } - return true; - case R.id.menu_sort_by_year: - if (isArtistSongPage()) { - mPreferences.setArtistSongSortOrder(SortOrder.ArtistSongSortOrder.SONG_YEAR); - getArtistSongFragment().refresh(); - } else if (isArtistAlbumPage()) { - mPreferences.setArtistAlbumSortOrder(SortOrder.ArtistAlbumSortOrder.ALBUM_YEAR); - getArtistAlbumFragment().refresh(); - } - return true; - case R.id.menu_sort_by_duration: - if (isArtistSongPage()) { - mPreferences - .setArtistSongSortOrder(SortOrder.ArtistSongSortOrder.SONG_DURATION); - getArtistSongFragment().refresh(); - } else { - mPreferences.setAlbumSongSortOrder(SortOrder.AlbumSongSortOrder.SONG_DURATION); - getAlbumSongFragment().refresh(); - } - return true; - case R.id.menu_sort_by_date_added: - if (isArtistSongPage()) { - mPreferences.setArtistSongSortOrder(SortOrder.ArtistSongSortOrder.SONG_DATE); - getArtistSongFragment().refresh(); - } - return true; - case R.id.menu_sort_by_track_list: - mPreferences.setAlbumSongSortOrder(SortOrder.AlbumSongSortOrder.SONG_TRACK_LIST); - getAlbumSongFragment().refresh(); - return true; - case R.id.menu_sort_by_filename: - if(isArtistSongPage()) { - mPreferences.setArtistSortOrder(SortOrder.ArtistSongSortOrder.SONG_FILENAME); - getArtistSongFragment().refresh(); - } - else { - mPreferences.setAlbumSongSortOrder(SortOrder.AlbumSongSortOrder.SONG_FILENAME); - getAlbumSongFragment().refresh(); - } - return true; - default: - break; - } - return super.onOptionsItemSelected(item); - } - - /** - * {@inheritDoc} - */ - @Override - protected void onSaveInstanceState(final Bundle outState) { - super.onSaveInstanceState(outState); - outState.putAll(mArguments); - } - - /** - * {@inheritDoc} - */ - @Override - public void onBackPressed() { - super.onBackPressed(); - } - - /** - * {@inheritDoc} - */ - @Override - public void onPageScrolled(final int position, final float positionOffset, - final int positionOffsetPixels) { - if (mViewPager.isFakeDragging()) { - return; - } - - final int scrollToX = (int)((position + positionOffset) * mTabCarousel - .getAllowedHorizontalScrollLength()); - mTabCarousel.scrollTo(scrollToX, 0); - } - - /** - * {@inheritDoc} - */ - @Override - public void onPageSelected(final int position) { - mTabCarousel.setCurrentTab(position); - } - - /** - * {@inheritDoc} - */ - @Override - public void onPageScrollStateChanged(final int state) { - if (state == ViewPager.SCROLL_STATE_IDLE) { - mTabCarousel.restoreYCoordinate(75, mViewPager.getCurrentItem()); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onTouchDown() { - if (!mViewPager.isFakeDragging()) { - mViewPager.beginFakeDrag(); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onTouchUp() { - if (mViewPager.isFakeDragging()) { - mViewPager.endFakeDrag(); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onScrollChanged(final int l, final int t, final int oldl, final int oldt) { - if (mViewPager.isFakeDragging()) { - mViewPager.fakeDragBy(oldl - l); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onTabSelected(final int position) { - mViewPager.setCurrentItem(position); - } - - /** - * {@inheritDoc} - */ - @Override - protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == NEW_PHOTO) { - if (resultCode == RESULT_OK) { - final Uri selectedImage = data.getData(); - final String[] filePathColumn = { - MediaStore.Images.Media.DATA - }; - - Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, - null, null); - if (cursor != null && cursor.moveToFirst()) { - final int columnIndex = cursor.getColumnIndex(filePathColumn[0]); - final String picturePath = cursor.getString(columnIndex); - cursor.close(); - cursor = null; - - String key = mProfileName; - if (isArtist()) { - key = mArtistName; - } else if (isAlbum()) { - key = ImageFetcher.generateAlbumCacheKey(mProfileName, mArtistName); - } - - final Bitmap bitmap = ImageUtils.decodeSampledBitmapFromFile(picturePath); - mImageFetcher.addBitmapToCache(key, bitmap); - if (isAlbum()) { - mTabCarousel.getAlbumArt().setImageBitmap(bitmap); - } else { - mTabCarousel.getPhoto().setImageBitmap(bitmap); - } - } - } else { - selectOldPhoto(); - } - } - } - - /** - * Starts an activity for result that returns an image from the Gallery. - */ - public void selectNewPhoto() { - // First remove the old image - removeFromCache(); - // Now open the gallery - final Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null); - intent.setType("image/*"); - startActivityForResult(intent, NEW_PHOTO); - } - - /** - * Fetchs for the artist or album art, other wise sets the default header - * image. - */ - public void selectOldPhoto() { - // First remove the old image - removeFromCache(); - // Apply the old photo - if (isArtist()) { - mTabCarousel.setArtistProfileHeader(this, mArtistName); - } else if (isAlbum()) { - mTabCarousel.setAlbumProfileHeader(this, mProfileName, mArtistName); - } else { - mTabCarousel.setPlaylistOrGenreProfileHeader(this, mProfileName); - } - } - - /** - * When the user chooses {@code #selectOldPhoto()} while viewing an album - * profile, the image is, most likely, reverted back to the locally found - * artwork. This is specifically for fetching the image from Last.fm. - */ - public void fetchAlbumArt() { - // First remove the old image - removeFromCache(); - // Fetch for the artwork - mTabCarousel.fetchAlbumPhoto(this, mProfileName, mArtistName); - } - - /** - * Searches Google for the artist or album - */ - public void googleSearch() { - String query = mProfileName; - if (isArtist()) { - query = mArtistName; - } else if (isAlbum()) { - query = mProfileName + " " + mArtistName; - } - final Intent googleSearch = new Intent(Intent.ACTION_WEB_SEARCH); - googleSearch.putExtra(SearchManager.QUERY, query); - startActivity(googleSearch); - } - - /** - * Removes the header image from the cache. - */ - private void removeFromCache() { - String key = mProfileName; - if (isArtist()) { - key = mArtistName; - } else if (isAlbum()) { - key = ImageFetcher.generateAlbumCacheKey(mProfileName, mArtistName); - } - mImageFetcher.removeFromCache(key); - // Give the disk cache a little time before requesting a new image. - SystemClock.sleep(80); - } - - /** - * Finishes the activity and overrides the default animation. - */ - private void goBack() { - finish(); - } - - /** - * @return True if the MIME type is vnd.android.cursor.dir/artists, false - * otherwise. - */ - private final boolean isArtist() { - return mType.equals(MediaStore.Audio.Artists.CONTENT_TYPE); - } - - /** - * @return True if the MIME type is vnd.android.cursor.dir/albums, false - * otherwise. - */ - private final boolean isAlbum() { - return mType.equals(MediaStore.Audio.Albums.CONTENT_TYPE); - } - - /** - * @return True if the MIME type is vnd.android.cursor.dir/gere, false - * otherwise. - */ - private final boolean isGenre() { - return mType.equals(MediaStore.Audio.Genres.CONTENT_TYPE); - } - - /** - * @return True if the MIME type is "LastAdded", false otherwise. - */ - private final boolean isLastAdded() { - return mType.equals(getString(R.string.playlist_last_added)); - } - - private boolean isArtistSongPage() { - return isArtist() && mViewPager.getCurrentItem() == 0; - } - - private boolean isArtistAlbumPage() { - return isArtist() && mViewPager.getCurrentItem() == 1; - } - - private ArtistSongFragment getArtistSongFragment() { - return (ArtistSongFragment)mPagerAdapter.getFragment(0); - } - - private ArtistAlbumFragment getArtistAlbumFragment() { - return (ArtistAlbumFragment)mPagerAdapter.getFragment(1); - } - - private AlbumSongFragment getAlbumSongFragment() { - return (AlbumSongFragment)mPagerAdapter.getFragment(0); - } -} diff --git a/src/com/cyngn/eleven/ui/fragments/GenreFragment.java b/src/com/cyngn/eleven/ui/fragments/GenreFragment.java deleted file mode 100644 index 54a38a9..0000000 --- a/src/com/cyngn/eleven/ui/fragments/GenreFragment.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.ui.fragments; - -import android.content.Intent; -import android.os.Bundle; -import android.provider.MediaStore; -import android.support.v4.app.Fragment; -import android.support.v4.app.LoaderManager.LoaderCallbacks; -import android.support.v4.content.Loader; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListView; -import android.widget.TextView; - -import com.cyngn.eleven.Config; -import com.cyngn.eleven.R; -import com.cyngn.eleven.adapters.GenreAdapter; -import com.cyngn.eleven.loaders.GenreLoader; -import com.cyngn.eleven.menu.FragmentMenuItems; -import com.cyngn.eleven.model.Genre; -import com.cyngn.eleven.recycler.RecycleHolder; -import com.cyngn.eleven.ui.activities.ProfileActivity; -import com.cyngn.eleven.utils.MusicUtils; -import com.cyngn.eleven.widgets.NoResultsContainer; - -import java.util.List; - -/** - * This class is used to display all of the genres on a user's device. - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -public class GenreFragment extends Fragment implements LoaderCallbacks<List<Genre>>, - OnItemClickListener { - - /** - * Used to keep context menu items from bleeding into other fragments - */ - private static final int GROUP_ID = 5; - - /** - * LoaderCallbacks identifier - */ - private static final int LOADER = 0; - - /** - * Fragment UI - */ - private ViewGroup mRootView; - - /** - * The adapter for the list - */ - private GenreAdapter mAdapter; - - /** - * The list view - */ - private ListView mListView; - - /** - * Genre song list - */ - private long[] mGenreList; - - /** - * Represents a genre - */ - private Genre mGenre; - - /** - * Empty constructor as per the {@link Fragment} documentation - */ - public GenreFragment() { - } - - /** - * {@inheritDoc} - */ - @Override - public void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // Create the adpater - mAdapter = new GenreAdapter(getActivity(), R.layout.list_item_simple); - } - - /** - * {@inheritDoc} - */ - @Override - 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.list_base, null); - // Initialize the list - mListView = (ListView)mRootView.findViewById(R.id.list_base); - // Set the data behind the list - mListView.setAdapter(mAdapter); - // Release any references to the recycled Views - mListView.setRecyclerListener(new RecycleHolder()); - // Listen for ContextMenus to be created - mListView.setOnCreateContextMenuListener(this); - // Show the albums and songs from the selected genre - mListView.setOnItemClickListener(this); - return mRootView; - } - - /** - * {@inheritDoc} - */ - @Override - public void onActivityCreated(final Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - // Enable the options menu - setHasOptionsMenu(true); - // Start the loader - getLoaderManager().initLoader(LOADER, null, this); - } - - /** - * {@inheritDoc} - */ - @Override - public void onCreateContextMenu(final ContextMenu menu, final View v, - final ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - // Get the position of the selected item - final AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; - // Create a new genre - mGenre = mAdapter.getItem(info.position); - // Create a list of the genre's songs - mGenreList = MusicUtils.getSongListForGenre(getActivity(), mGenre.mGenreId); - - // Play the genre - menu.add(GROUP_ID, FragmentMenuItems.PLAY_SELECTION, Menu.NONE, - R.string.context_menu_play_selection); - // Add the genre to the queue - menu.add(GROUP_ID, FragmentMenuItems.ADD_TO_QUEUE, Menu.NONE, R.string.add_to_queue); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean onContextItemSelected(final android.view.MenuItem item) { - if (item.getGroupId() == GROUP_ID) { - switch (item.getItemId()) { - case FragmentMenuItems.PLAY_SELECTION: - MusicUtils.playAll(getActivity(), mGenreList, 0, false); - return true; - case FragmentMenuItems.ADD_TO_QUEUE: - MusicUtils.addToQueue(getActivity(), mGenreList); - return true; - default: - break; - } - } - return super.onContextItemSelected(item); - } - - /** - * {@inheritDoc} - */ - @Override - public void onItemClick(final AdapterView<?> parent, final View view, final int position, - final long id) { - mGenre = mAdapter.getItem(position); - // Create a new bundle to transfer the artist info - final Bundle bundle = new Bundle(); - bundle.putLong(Config.ID, mGenre.mGenreId); - bundle.putString(Config.MIME_TYPE, MediaStore.Audio.Genres.CONTENT_TYPE); - bundle.putString(Config.NAME, mGenre.mGenreName); - - // Create the intent to launch the profile activity - final Intent intent = new Intent(getActivity(), ProfileActivity.class); - intent.putExtras(bundle); - startActivity(intent); - } - - /** - * {@inheritDoc} - */ - @Override - public Loader<List<Genre>> onCreateLoader(final int id, final Bundle args) { - return new GenreLoader(getActivity()); - } - - /** - * {@inheritDoc} - */ - @Override - public void onLoadFinished(final Loader<List<Genre>> loader, final List<Genre> data) { - // Check for any errors - if (data.isEmpty()) { - // Set the empty text - final NoResultsContainer empty = (NoResultsContainer)mRootView.findViewById(R.id.no_results_container); - mListView.setEmptyView(empty); - return; - } - - // Start fresh - mAdapter.unload(); - // Add the data to the adpater - for (final Genre genre : data) { - mAdapter.add(genre); - } - // Build the cache - mAdapter.buildCache(); - } - - /** - * {@inheritDoc} - */ - @Override - public void onLoaderReset(final Loader<List<Genre>> loader) { - // Clear the data in the adapter - mAdapter.unload(); - } - -} diff --git a/src/com/cyngn/eleven/ui/fragments/profile/AlbumSongFragment.java b/src/com/cyngn/eleven/ui/fragments/profile/AlbumSongFragment.java deleted file mode 100644 index 46aa066..0000000 --- a/src/com/cyngn/eleven/ui/fragments/profile/AlbumSongFragment.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.ui.fragments.profile; - -import android.app.Activity; -import android.database.Cursor; -import android.os.Bundle; -import android.os.SystemClock; -import android.support.v4.app.Fragment; -import android.support.v4.app.LoaderManager.LoaderCallbacks; -import android.support.v4.content.Loader; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.SubMenu; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListView; - -import com.cyngn.eleven.Config; -import com.cyngn.eleven.R; -import com.cyngn.eleven.adapters.ProfileSongAdapter; -import com.cyngn.eleven.loaders.AlbumSongLoader; -import com.cyngn.eleven.menu.CreateNewPlaylist; -import com.cyngn.eleven.menu.DeleteDialog; -import com.cyngn.eleven.menu.FragmentMenuItems; -import com.cyngn.eleven.model.Song; -import com.cyngn.eleven.recycler.RecycleHolder; -import com.cyngn.eleven.utils.MusicUtils; -import com.cyngn.eleven.widgets.ProfileTabCarousel; -import com.cyngn.eleven.widgets.VerticalScrollListener; - -import java.util.List; - -/** - * This class is used to display all of the songs from a particular album. - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -public class AlbumSongFragment extends Fragment implements LoaderCallbacks<List<Song>>, - OnItemClickListener { - - /** - * Used to keep context menu items from bleeding into other fragments - */ - private static final int GROUP_ID = 11; - - /** - * LoaderCallbacks identifier - */ - private static final int LOADER = 0; - - /** - * The adapter for the list - */ - private ProfileSongAdapter mAdapter; - - /** - * The list view - */ - private ListView mListView; - - /** - * Represents a song - */ - private Song mSong; - - /** - * Position of a context menu item - */ - private int mSelectedPosition; - - /** - * Id of a context menu item - */ - private long mSelectedId; - - /** - * Song, album, and artist name used in the context menu - */ - private String mSongName, mAlbumName, mArtistName; - - /** - * Profile header - */ - private ProfileTabCarousel mProfileTabCarousel; - - /** - * Empty constructor as per the {@link Fragment} documentation - */ - public AlbumSongFragment() { - } - - /** - * {@inheritDoc} - */ - @Override - public void onAttach(final Activity activity) { - super.onAttach(activity); - mProfileTabCarousel = (ProfileTabCarousel)activity - .findViewById(R.id.acivity_profile_base_tab_carousel); - } - - /** - * {@inheritDoc} - */ - @Override - public void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // Create the adpater - mAdapter = new ProfileSongAdapter( - getActivity(), - R.layout.list_item_simple, - R.layout.faux_carousel, - ProfileSongAdapter.DISPLAY_ALBUM_SETTING - ); - } - - /** - * {@inheritDoc} - */ - @Override - public View onCreateView(final LayoutInflater inflater, final ViewGroup container, - final Bundle savedInstanceState) { - // The View for the fragment's UI - final ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.list_base, null); - // Initialize the list - mListView = (ListView)rootView.findViewById(R.id.list_base); - // Set the data behind the list - mListView.setAdapter(mAdapter); - // Release any references to the recycled Views - mListView.setRecyclerListener(new RecycleHolder()); - // Listen for ContextMenus to be created - mListView.setOnCreateContextMenuListener(this); - // Play the selected song - mListView.setOnItemClickListener(this); - // To help make scrolling smooth - mListView.setOnScrollListener(new VerticalScrollListener(null, mProfileTabCarousel, 0)); - // Remove the scrollbars and padding for the fast scroll - mListView.setVerticalScrollBarEnabled(false); - mListView.setFastScrollEnabled(false); - mListView.setPadding(0, 0, 0, 0); - return rootView; - } - - /** - * {@inheritDoc} - */ - @Override - public void onActivityCreated(final Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - // Enable the options menu - setHasOptionsMenu(true); - // Start the loader - final Bundle arguments = getArguments(); - if (arguments != null) { - getLoaderManager().initLoader(LOADER, arguments, this); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onSaveInstanceState(final Bundle outState) { - super.onSaveInstanceState(outState); - outState.putAll(getArguments() != null ? getArguments() : new Bundle()); - } - - /** - * {@inheritDoc} - */ - @Override - public void onCreateContextMenu(final ContextMenu menu, final View v, - final ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - // Get the position of the selected item - final AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; - mSelectedPosition = info.position - 1; - // Creat a new song - mSong = mAdapter.getItem(mSelectedPosition); - mSelectedId = mSong.mSongId; - mSongName = mSong.mSongName; - mAlbumName = mSong.mAlbumName; - mArtistName = mSong.mArtistName; - - // Play the song - menu.add(GROUP_ID, FragmentMenuItems.PLAY_SELECTION, Menu.NONE, - getString(R.string.context_menu_play_selection)); - - // Play the song - menu.add(GROUP_ID, FragmentMenuItems.PLAY_NEXT, Menu.NONE, - getString(R.string.context_menu_play_next)); - - // Add the song to the queue - menu.add(GROUP_ID, FragmentMenuItems.ADD_TO_QUEUE, Menu.NONE, - getString(R.string.add_to_queue)); - - // Add the song to a playlist - final SubMenu subMenu = menu.addSubMenu(GROUP_ID, FragmentMenuItems.ADD_TO_PLAYLIST, - Menu.NONE, R.string.add_to_playlist); - MusicUtils.makePlaylistMenu(getActivity(), GROUP_ID, subMenu); - - // Make the song a ringtone - menu.add(GROUP_ID, FragmentMenuItems.USE_AS_RINGTONE, Menu.NONE, - getString(R.string.context_menu_use_as_ringtone)); - - // Delete the song - menu.add(GROUP_ID, FragmentMenuItems.DELETE, Menu.NONE, - getString(R.string.context_menu_delete)); - } - - @Override - public boolean onContextItemSelected(final android.view.MenuItem item) { - if (item.getGroupId() == GROUP_ID) { - switch (item.getItemId()) { - case FragmentMenuItems.PLAY_SELECTION: - MusicUtils.playAll(getActivity(), new long[] { - mSelectedId - }, 0, false); - return true; - case FragmentMenuItems.PLAY_NEXT: - MusicUtils.playNext(new long[] { - mSelectedId - }); - return true; - case FragmentMenuItems.ADD_TO_QUEUE: - MusicUtils.addToQueue(getActivity(), new long[] { - mSelectedId - }); - return true; - case FragmentMenuItems.NEW_PLAYLIST: - CreateNewPlaylist.getInstance(new long[] { - mSelectedId - }).show(getFragmentManager(), "CreatePlaylist"); - return true; - case FragmentMenuItems.PLAYLIST_SELECTED: - final long mPlaylistId = item.getIntent().getLongExtra("playlist", 0); - MusicUtils.addToPlaylist(getActivity(), new long[] { - mSelectedId - }, mPlaylistId); - return true; - case FragmentMenuItems.USE_AS_RINGTONE: - MusicUtils.setRingtone(getActivity(), mSelectedId); - return true; - case FragmentMenuItems.DELETE: - DeleteDialog.newInstance(mSong.mSongName, new long[] { - mSelectedId - }, null).show(getFragmentManager(), "DeleteDialog"); - refresh(); - return true; - default: - break; - } - } - return super.onContextItemSelected(item); - } - - /** - * {@inheritDoc} - */ - @Override - public void onItemClick(final AdapterView<?> parent, final View view, final int position, - final long id) { - if (position == 0) { - return; - } - Cursor cursor = AlbumSongLoader.makeAlbumSongCursor(getActivity(), getArguments() - .getLong(Config.ID)); - final long[] list = MusicUtils.getSongListForCursor(cursor); - MusicUtils.playAll(getActivity(), list, position - 1, false); - cursor.close(); - cursor = null; - } - - /** - * {@inheritDoc} - */ - @Override - public Loader<List<Song>> onCreateLoader(final int id, final Bundle args) { - return new AlbumSongLoader(getActivity(), args.getLong(Config.ID)); - } - - /** - * {@inheritDoc} - */ - @Override - public void onLoadFinished(final Loader<List<Song>> loader, final List<Song> data) { - // Check for any errors - if (data.isEmpty()) { - return; - } - - // Start fresh - mAdapter.unload(); - // Return the correct count - mAdapter.setCount(data); - // Add the data to the adpater - for (final Song song : data) { - mAdapter.add(song); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onLoaderReset(final Loader<List<Song>> loader) { - // Clear the data in the adapter - mAdapter.unload(); - } - - /** - * Restarts the loader. - */ - public void refresh() { - // Scroll to the stop of the list before restarting the loader. - // Otherwise, if the user has scrolled enough to move the header, it - // becomes misplaced and needs to be reset. - mListView.setSelection(0); - // Wait a moment for the preference to change. - SystemClock.sleep(10); - mAdapter.notifyDataSetChanged(); - getLoaderManager().restartLoader(LOADER, getArguments(), this); - } -} diff --git a/src/com/cyngn/eleven/ui/fragments/profile/ArtistAlbumFragment.java b/src/com/cyngn/eleven/ui/fragments/profile/ArtistAlbumFragment.java deleted file mode 100644 index 37d0d30..0000000 --- a/src/com/cyngn/eleven/ui/fragments/profile/ArtistAlbumFragment.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.ui.fragments.profile; - -import android.app.Activity; -import android.os.Bundle; -import android.os.SystemClock; -import android.support.v4.app.Fragment; -import android.support.v4.app.LoaderManager.LoaderCallbacks; -import android.support.v4.content.Loader; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.SubMenu; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AbsListView; -import android.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListView; - -import com.cyngn.eleven.Config; -import com.cyngn.eleven.R; -import com.cyngn.eleven.adapters.ArtistAlbumAdapter; -import com.cyngn.eleven.loaders.ArtistAlbumLoader; -import com.cyngn.eleven.menu.CreateNewPlaylist; -import com.cyngn.eleven.menu.DeleteDialog; -import com.cyngn.eleven.menu.FragmentMenuItems; -import com.cyngn.eleven.model.Album; -import com.cyngn.eleven.recycler.RecycleHolder; -import com.cyngn.eleven.utils.MusicUtils; -import com.cyngn.eleven.utils.NavUtils; -import com.cyngn.eleven.widgets.ProfileTabCarousel; -import com.cyngn.eleven.widgets.VerticalScrollListener; -import com.cyngn.eleven.widgets.VerticalScrollListener.ScrollableHeader; - -import java.util.List; - -/** - * This class is used to display all of the albums from a particular artist. - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -public class ArtistAlbumFragment extends Fragment implements LoaderCallbacks<List<Album>>, - OnItemClickListener { - - /** - * Used to keep context menu items from bleeding into other fragments - */ - private static final int GROUP_ID = 10; - - /** - * LoaderCallbacks identifier - */ - private static final int LOADER = 0; - - /** - * The adapter for the grid - */ - private ArtistAlbumAdapter mAdapter; - - /** - * The list view - */ - private ListView mListView; - - /** - * Album song list - */ - private long[] mAlbumList; - - /** - * Represents an album - */ - private Album mAlbum; - - /** - * Profile header - */ - private ProfileTabCarousel mProfileTabCarousel; - - /** - * Empty constructor as per the {@link Fragment} documentation - */ - public ArtistAlbumFragment() { - } - - /** - * {@inheritDoc} - */ - @Override - public void onAttach(final Activity activity) { - super.onAttach(activity); - mProfileTabCarousel = (ProfileTabCarousel)activity - .findViewById(R.id.acivity_profile_base_tab_carousel); - } - - /** - * {@inheritDoc} - */ - @Override - public void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // Create the adpater - mAdapter = new ArtistAlbumAdapter(getActivity(), - R.layout.list_item_detailed_no_background); - } - - /** - * {@inheritDoc} - */ - @Override - public View onCreateView(final LayoutInflater inflater, final ViewGroup container, - final Bundle savedInstanceState) { - // The View for the fragment's UI - final ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.list_base, null); - // Initialize the list - mListView = (ListView)rootView.findViewById(R.id.list_base); - // Set the data behind the grid - mListView.setAdapter(mAdapter); - // Release any references to the recycled Views - mListView.setRecyclerListener(new RecycleHolder()); - // Listen for ContextMenus to be created - mListView.setOnCreateContextMenuListener(this); - // Show the songs from the selected album - mListView.setOnItemClickListener(this); - // To help make scrolling smooth - mListView.setOnScrollListener(new VerticalScrollListener(mScrollableHeader, - mProfileTabCarousel, 1)); - // Remove the scrollbars and padding for the fast scroll - mListView.setVerticalScrollBarEnabled(false); - mListView.setFastScrollEnabled(false); - mListView.setPadding(0, 0, 0, 0); - return rootView; - } - - /** - * {@inheritDoc} - */ - @Override - public void onActivityCreated(final Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - // Enable the options menu - setHasOptionsMenu(true); - // Start the loader - final Bundle arguments = getArguments(); - if (arguments != null) { - getLoaderManager().initLoader(LOADER, arguments, this); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onPause() { - super.onPause(); - mAdapter.flush(); - } - - /** - * {@inheritDoc} - */ - @Override - public void onSaveInstanceState(final Bundle outState) { - super.onSaveInstanceState(outState); - outState.putAll(getArguments() != null ? getArguments() : new Bundle()); - } - - /** - * {@inheritDoc} - */ - @Override - public void onCreateContextMenu(final ContextMenu menu, final View v, - final ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - - // Get the position of the selected item - final AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; - // Create a new album - mAlbum = mAdapter.getItem(info.position - 1); - // Create a list of the album's songs - mAlbumList = MusicUtils.getSongListForAlbum(getActivity(), mAlbum.mAlbumId); - - // Play the album - menu.add(GROUP_ID, FragmentMenuItems.PLAY_SELECTION, Menu.NONE, - getString(R.string.context_menu_play_selection)); - - // Add the album to the queue - menu.add(GROUP_ID, FragmentMenuItems.ADD_TO_QUEUE, Menu.NONE, - getString(R.string.add_to_queue)); - - // Add the album to a playlist - final SubMenu subMenu = menu.addSubMenu(GROUP_ID, FragmentMenuItems.ADD_TO_PLAYLIST, - Menu.NONE, R.string.add_to_playlist); - MusicUtils.makePlaylistMenu(getActivity(), GROUP_ID, subMenu); - - // Delete the album - menu.add(GROUP_ID, FragmentMenuItems.DELETE, Menu.NONE, - getString(R.string.context_menu_delete)); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean onContextItemSelected(final MenuItem item) { - // Avoid leaking context menu selections - if (item.getGroupId() == GROUP_ID) { - switch (item.getItemId()) { - case FragmentMenuItems.PLAY_SELECTION: - MusicUtils.playAll(getActivity(), mAlbumList, 0, false); - return true; - case FragmentMenuItems.ADD_TO_QUEUE: - MusicUtils.addToQueue(getActivity(), mAlbumList); - return true; - case FragmentMenuItems.NEW_PLAYLIST: - CreateNewPlaylist.getInstance(mAlbumList).show(getFragmentManager(), - "CreatePlaylist"); - return true; - case FragmentMenuItems.PLAYLIST_SELECTED: - final long id = item.getIntent().getLongExtra("playlist", 0); - MusicUtils.addToPlaylist(getActivity(), mAlbumList, id); - return true; - case FragmentMenuItems.DELETE: - DeleteDialog.newInstance(mAlbum.mAlbumName, mAlbumList, null).show( - getFragmentManager(), "DeleteDialog"); - refresh(); - return true; - default: - break; - } - } - return super.onContextItemSelected(item); - } - - /** - * {@inheritDoc} - */ - @Override - public void onItemClick(final AdapterView<?> parent, final View view, final int position, - final long id) { - if (position == 0) { - return; - } - mAlbum = mAdapter.getItem(position - 1); - NavUtils.openAlbumProfile(getActivity(), mAlbum.mAlbumName, - mAlbum.mArtistName, mAlbum.mAlbumId); - getActivity().finish(); - } - - /** - * {@inheritDoc} - */ - @Override - public Loader<List<Album>> onCreateLoader(final int id, final Bundle args) { - return new ArtistAlbumLoader(getActivity(), args.getLong(Config.ID)); - } - - /** - * {@inheritDoc} - */ - @Override - public void onLoadFinished(final Loader<List<Album>> loader, final List<Album> data) { - // Check for any errors - if (data.isEmpty()) { - return; - } - - // Start fresh - mAdapter.unload(); - // Return the correct count - mAdapter.setCount(data); - // Add the data to the adpater - for (final Album album : data) { - mAdapter.add(album); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onLoaderReset(final Loader<List<Album>> loader) { - // Clear the data in the adapter - mAdapter.unload(); - } - - // Pause disk cache access to ensure smoother scrolling - private final ScrollableHeader mScrollableHeader = new ScrollableHeader() { - - /** - * {@inheritDoc} - */ - @Override - public void onScrollStateChanged(final AbsListView view, final int scrollState) { - if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING - || scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { - mAdapter.setPauseDiskCache(true); - } else { - mAdapter.setPauseDiskCache(false); - mAdapter.notifyDataSetChanged(); - } - } - }; - - /** - * Restarts the loader. - */ - public void refresh() { - // Scroll to the stop of the list before restarting the loader. - // Otherwise, if the user has scrolled enough to move the header, it - // becomes misplaced and needs to be reset. - mListView.setSelection(0); - // Wait a moment for the preference to change. - SystemClock.sleep(10); - mAdapter.notifyDataSetChanged(); - getLoaderManager().restartLoader(LOADER, getArguments(), this); - } -} diff --git a/src/com/cyngn/eleven/ui/fragments/profile/ArtistSongFragment.java b/src/com/cyngn/eleven/ui/fragments/profile/ArtistSongFragment.java deleted file mode 100644 index b161001..0000000 --- a/src/com/cyngn/eleven/ui/fragments/profile/ArtistSongFragment.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.ui.fragments.profile; - -import android.app.Activity; -import android.database.Cursor; -import android.os.Bundle; -import android.os.SystemClock; -import android.support.v4.app.Fragment; -import android.support.v4.app.LoaderManager.LoaderCallbacks; -import android.support.v4.content.Loader; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.SubMenu; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListView; - -import com.cyngn.eleven.Config; -import com.cyngn.eleven.R; -import com.cyngn.eleven.adapters.ProfileSongAdapter; -import com.cyngn.eleven.loaders.ArtistSongLoader; -import com.cyngn.eleven.menu.CreateNewPlaylist; -import com.cyngn.eleven.menu.DeleteDialog; -import com.cyngn.eleven.menu.FragmentMenuItems; -import com.cyngn.eleven.model.Song; -import com.cyngn.eleven.recycler.RecycleHolder; -import com.cyngn.eleven.utils.MusicUtils; -import com.cyngn.eleven.widgets.ProfileTabCarousel; -import com.cyngn.eleven.widgets.VerticalScrollListener; - -import java.util.List; - -/** - * This class is used to display all of the songs from a particular artist. - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -public class ArtistSongFragment extends Fragment implements LoaderCallbacks<List<Song>>, - OnItemClickListener { - - /** - * Used to keep context menu items from bleeding into other fragments - */ - private static final int GROUP_ID = 9; - - /** - * LoaderCallbacks identifier - */ - private static final int LOADER = 0; - - /** - * The adapter for the list - */ - private ProfileSongAdapter mAdapter; - - /** - * The list view - */ - private ListView mListView; - - /** - * Represents a song - */ - private Song mSong; - - /** - * Position of a context menu item - */ - private int mSelectedPosition; - - /** - * Id of a context menu item - */ - private long mSelectedId; - - /** - * Song, album, and artist name used in the context menu - */ - private String mSongName, mAlbumName, mArtistName; - - /** - * Profile header - */ - private ProfileTabCarousel mProfileTabCarousel; - - /** - * Empty constructor as per the {@link Fragment} documentation - */ - public ArtistSongFragment() { - } - - /** - * {@inheritDoc} - */ - @Override - public void onAttach(final Activity activity) { - super.onAttach(activity); - mProfileTabCarousel = (ProfileTabCarousel)activity - .findViewById(R.id.acivity_profile_base_tab_carousel); - } - - /** - * {@inheritDoc} - */ - @Override - public void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // Create the adpater - mAdapter = new ProfileSongAdapter(getActivity(), R.layout.list_item_simple); - } - - /** - * {@inheritDoc} - */ - @Override - public View onCreateView(final LayoutInflater inflater, final ViewGroup container, - final Bundle savedInstanceState) { - // The View for the fragment's UI - final ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.list_base, null); - // Initialize the list - mListView = (ListView)rootView.findViewById(R.id.list_base); - // Set the data behind the list - mListView.setAdapter(mAdapter); - // Release any references to the recycled Views - mListView.setRecyclerListener(new RecycleHolder()); - // Listen for ContextMenus to be created - mListView.setOnCreateContextMenuListener(this); - // Play the selected song - mListView.setOnItemClickListener(this); - // To help make scrolling smooth - mListView.setOnScrollListener(new VerticalScrollListener(null, mProfileTabCarousel, 0)); - // Remove the scrollbars and padding for the fast scroll - mListView.setVerticalScrollBarEnabled(false); - mListView.setFastScrollEnabled(false); - mListView.setPadding(0, 0, 0, 0); - return rootView; - } - - /** - * {@inheritDoc} - */ - @Override - public void onActivityCreated(final Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - // Enable the options menu - setHasOptionsMenu(true); - // Start the loader - final Bundle arguments = getArguments(); - if (arguments != null) { - getLoaderManager().initLoader(LOADER, arguments, this); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onSaveInstanceState(final Bundle outState) { - super.onSaveInstanceState(outState); - outState.putAll(getArguments() != null ? getArguments() : new Bundle()); - } - - /** - * {@inheritDoc} - */ - @Override - public void onCreateContextMenu(final ContextMenu menu, final View v, - final ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - // Get the position of the selected item - final AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; - mSelectedPosition = info.position - 1; - // Creat a new song - mSong = mAdapter.getItem(mSelectedPosition); - mSelectedId = mSong.mSongId; - mSongName = mSong.mSongName; - mAlbumName = mSong.mAlbumName; - mArtistName = mSong.mArtistName; - - // Play the song - menu.add(GROUP_ID, FragmentMenuItems.PLAY_SELECTION, Menu.NONE, - getString(R.string.context_menu_play_selection)); - - // Play next - menu.add(GROUP_ID, FragmentMenuItems.PLAY_NEXT, Menu.NONE, - getString(R.string.context_menu_play_next)); - - // Add the song to the queue - menu.add(GROUP_ID, FragmentMenuItems.ADD_TO_QUEUE, Menu.NONE, - getString(R.string.add_to_queue)); - - // Add the song to a playlist - final SubMenu subMenu = menu.addSubMenu(GROUP_ID, FragmentMenuItems.ADD_TO_PLAYLIST, - Menu.NONE, R.string.add_to_playlist); - MusicUtils.makePlaylistMenu(getActivity(), GROUP_ID, subMenu); - - // Make the song a ringtone - menu.add(GROUP_ID, FragmentMenuItems.USE_AS_RINGTONE, Menu.NONE, - getString(R.string.context_menu_use_as_ringtone)); - - // Delete the song - menu.add(GROUP_ID, FragmentMenuItems.DELETE, Menu.NONE, - getString(R.string.context_menu_delete)); - } - - @Override - public boolean onContextItemSelected(final android.view.MenuItem item) { - if (item.getGroupId() == GROUP_ID) { - switch (item.getItemId()) { - case FragmentMenuItems.PLAY_SELECTION: - MusicUtils.playAll(getActivity(), new long[] { - mSelectedId - }, 0, false); - return true; - case FragmentMenuItems.PLAY_NEXT: - MusicUtils.playNext(new long[] { - mSelectedId - }); - return true; - case FragmentMenuItems.ADD_TO_QUEUE: - MusicUtils.addToQueue(getActivity(), new long[] { - mSelectedId - }); - return true; - case FragmentMenuItems.NEW_PLAYLIST: - CreateNewPlaylist.getInstance(new long[] { - mSelectedId - }).show(getFragmentManager(), "CreatePlaylist"); - return true; - case FragmentMenuItems.PLAYLIST_SELECTED: - final long mPlaylistId = item.getIntent().getLongExtra("playlist", 0); - MusicUtils.addToPlaylist(getActivity(), new long[] { - mSelectedId - }, mPlaylistId); - return true; - case FragmentMenuItems.USE_AS_RINGTONE: - MusicUtils.setRingtone(getActivity(), mSelectedId); - return true; - case FragmentMenuItems.DELETE: - DeleteDialog.newInstance(mSong.mSongName, new long[] { - mSelectedId - }, null).show(getFragmentManager(), "DeleteDialog"); - refresh(); - return true; - default: - break; - } - } - return super.onContextItemSelected(item); - } - - /** - * {@inheritDoc} - */ - @Override - public void onItemClick(final AdapterView<?> parent, final View view, final int position, - final long id) { - if (position == 0) { - return; - } - Cursor cursor = ArtistSongLoader.makeArtistSongCursor(getActivity(), getArguments() - .getLong(Config.ID)); - final long[] list = MusicUtils.getSongListForCursor(cursor); - MusicUtils.playAll(getActivity(), list, position - 1, false); - cursor.close(); - cursor = null; - } - - /** - * {@inheritDoc} - */ - @Override - public Loader<List<Song>> onCreateLoader(final int id, final Bundle args) { - return new ArtistSongLoader(getActivity(), args.getLong(Config.ID)); - } - - /** - * {@inheritDoc} - */ - @Override - public void onLoadFinished(final Loader<List<Song>> loader, final List<Song> data) { - // Check for any errors - if (data.isEmpty()) { - return; - } - - // Start fresh - mAdapter.unload(); - // Return the correct count - mAdapter.setCount(data); - // Add the data to the adpater - for (final Song song : data) { - mAdapter.add(song); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onLoaderReset(final Loader<List<Song>> loader) { - // Clear the data in the adapter - mAdapter.unload(); - } - - /** - * Restarts the loader. - */ - public void refresh() { - // Scroll to the stop of the list before restarting the loader. - // Otherwise, if the user has scrolled enough to move the header, it - // becomes misplaced and needs to be reset. - mListView.setSelection(0); - // Wait a moment for the preference to change. - SystemClock.sleep(10); - mAdapter.notifyDataSetChanged(); - getLoaderManager().restartLoader(LOADER, getArguments(), this); - } -} diff --git a/src/com/cyngn/eleven/ui/fragments/profile/GenreSongFragment.java b/src/com/cyngn/eleven/ui/fragments/profile/GenreSongFragment.java deleted file mode 100644 index 3be54fa..0000000 --- a/src/com/cyngn/eleven/ui/fragments/profile/GenreSongFragment.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.ui.fragments.profile; - -import android.app.Activity; -import android.database.Cursor; -import android.os.Bundle; -import android.os.SystemClock; -import android.support.v4.app.Fragment; -import android.support.v4.app.LoaderManager.LoaderCallbacks; -import android.support.v4.content.Loader; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.SubMenu; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListView; - -import com.cyngn.eleven.Config; -import com.cyngn.eleven.R; -import com.cyngn.eleven.adapters.ProfileSongAdapter; -import com.cyngn.eleven.loaders.GenreSongLoader; -import com.cyngn.eleven.menu.CreateNewPlaylist; -import com.cyngn.eleven.menu.DeleteDialog; -import com.cyngn.eleven.menu.FragmentMenuItems; -import com.cyngn.eleven.model.Song; -import com.cyngn.eleven.recycler.RecycleHolder; -import com.cyngn.eleven.utils.MusicUtils; -import com.cyngn.eleven.utils.NavUtils; -import com.cyngn.eleven.widgets.ProfileTabCarousel; -import com.cyngn.eleven.widgets.VerticalScrollListener; - -import java.util.List; - -/** - * This class is used to display all of the songs from a particular playlist. - * - * @author Andrew Neal (andrewdneal@gmail.com) - */ -public class GenreSongFragment extends Fragment implements LoaderCallbacks<List<Song>>, - OnItemClickListener { - - /** - * Used to keep context menu items from bleeding into other fragments - */ - private static final int GROUP_ID = 12; - - /** - * LoaderCallbacks identifier - */ - private static final int LOADER = 0; - - /** - * The adapter for the list - */ - private ProfileSongAdapter mAdapter; - - /** - * The list view - */ - private ListView mListView; - - /** - * Represents a song - */ - private Song mSong; - - /** - * Position of a context menu item - */ - private int mSelectedPosition; - - /** - * Id of a context menu item - */ - private long mSelectedId; - - /** - * Song, album, and artist name used in the context menu - */ - private String mSongName, mAlbumName, mArtistName; - - /** - * Profile header - */ - private ProfileTabCarousel mProfileTabCarousel; - - /** - * Empty constructor as per the {@link Fragment} documentation - */ - public GenreSongFragment() { - } - - /** - * {@inheritDoc} - */ - @Override - public void onAttach(final Activity activity) { - super.onAttach(activity); - mProfileTabCarousel = (ProfileTabCarousel)activity - .findViewById(R.id.acivity_profile_base_tab_carousel); - } - - /** - * {@inheritDoc} - */ - @Override - public void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // Create the adpater - mAdapter = new ProfileSongAdapter(getActivity(), R.layout.list_item_simple); - } - - /** - * {@inheritDoc} - */ - @Override - public View onCreateView(final LayoutInflater inflater, final ViewGroup container, - final Bundle savedInstanceState) { - // The View for the fragment's UI - final ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.list_base, null); - // Initialize the list - mListView = (ListView)rootView.findViewById(R.id.list_base); - // Set the data behind the list - mListView.setAdapter(mAdapter); - // Release any references to the recycled Views - mListView.setRecyclerListener(new RecycleHolder()); - // Listen for ContextMenus to be created - mListView.setOnCreateContextMenuListener(this); - // Play the selected song - mListView.setOnItemClickListener(this); - // To help make scrolling smooth - mListView.setOnScrollListener(new VerticalScrollListener(null, mProfileTabCarousel, 0)); - // Remove the scrollbars and padding for the fast scroll - mListView.setVerticalScrollBarEnabled(false); - mListView.setFastScrollEnabled(false); - mListView.setPadding(0, 0, 0, 0); - return rootView; - } - - /** - * {@inheritDoc} - */ - @Override - public void onActivityCreated(final Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - // Enable the options menu - setHasOptionsMenu(true); - // Start the loader - final Bundle arguments = getArguments(); - if (arguments != null) { - getLoaderManager().initLoader(LOADER, arguments, this); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onSaveInstanceState(final Bundle outState) { - super.onSaveInstanceState(outState); - outState.putAll(getArguments() != null ? getArguments() : new Bundle()); - } - - /** - * {@inheritDoc} - */ - @Override - public void onCreateContextMenu(final ContextMenu menu, final View v, - final ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - // Get the position of the selected item - final AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; - mSelectedPosition = info.position - 1; - // Creat a new song - mSong = mAdapter.getItem(mSelectedPosition); - mSelectedId = mSong.mSongId; - mSongName = mSong.mSongName; - mAlbumName = mSong.mAlbumName; - mArtistName = mSong.mArtistName; - - // Play the song - menu.add(GROUP_ID, FragmentMenuItems.PLAY_SELECTION, Menu.NONE, - getString(R.string.context_menu_play_selection)); - - // Play the song - menu.add(GROUP_ID, FragmentMenuItems.PLAY_NEXT, Menu.NONE, - getString(R.string.context_menu_play_next)); - - // Add the song to the queue - menu.add(GROUP_ID, FragmentMenuItems.ADD_TO_QUEUE, Menu.NONE, - getString(R.string.add_to_queue)); - - // Add the song to a playlist - final SubMenu subMenu = menu.addSubMenu(GROUP_ID, FragmentMenuItems.ADD_TO_PLAYLIST, - Menu.NONE, R.string.add_to_playlist); - MusicUtils.makePlaylistMenu(getActivity(), GROUP_ID, subMenu); - - // View more content by the song artist - menu.add(GROUP_ID, FragmentMenuItems.MORE_BY_ARTIST, Menu.NONE, - getString(R.string.context_menu_more_by_artist)); - - // Make the song a ringtone - menu.add(GROUP_ID, FragmentMenuItems.USE_AS_RINGTONE, Menu.NONE, - getString(R.string.context_menu_use_as_ringtone)); - - // Delete the song - menu.add(GROUP_ID, FragmentMenuItems.DELETE, Menu.NONE, - getString(R.string.context_menu_delete)); - } - - @Override - public boolean onContextItemSelected(final android.view.MenuItem item) { - if (item.getGroupId() == GROUP_ID) { - switch (item.getItemId()) { - case FragmentMenuItems.PLAY_SELECTION: - MusicUtils.playAll(getActivity(), new long[] { - mSelectedId - }, 0, false); - return true; - case FragmentMenuItems.PLAY_NEXT: - MusicUtils.playNext(new long[] { - mSelectedId - }); - return true; - case FragmentMenuItems.ADD_TO_QUEUE: - MusicUtils.addToQueue(getActivity(), new long[] { - mSelectedId - }); - return true; - case FragmentMenuItems.NEW_PLAYLIST: - CreateNewPlaylist.getInstance(new long[] { - mSelectedId - }).show(getFragmentManager(), "CreatePlaylist"); - return true; - case FragmentMenuItems.PLAYLIST_SELECTED: - final long mPlaylistId = item.getIntent().getLongExtra("playlist", 0); - MusicUtils.addToPlaylist(getActivity(), new long[] { - mSelectedId - }, mPlaylistId); - return true; - case FragmentMenuItems.MORE_BY_ARTIST: - NavUtils.openArtistProfile(getActivity(), mArtistName); - return true; - case FragmentMenuItems.USE_AS_RINGTONE: - MusicUtils.setRingtone(getActivity(), mSelectedId); - return true; - case FragmentMenuItems.DELETE: - DeleteDialog.newInstance(mSong.mSongName, new long[] { - mSelectedId - }, null).show(getFragmentManager(), "DeleteDialog"); - refresh(); - return true; - default: - break; - } - } - return super.onContextItemSelected(item); - } - - /** - * {@inheritDoc} - */ - @Override - public void onItemClick(final AdapterView<?> parent, final View view, final int position, - final long id) { - if (position == 0) { - return; - } - Cursor cursor = GenreSongLoader.makeGenreSongCursor(getActivity(), getArguments() - .getLong(Config.ID)); - final long[] list = MusicUtils.getSongListForCursor(cursor); - MusicUtils.playAll(getActivity(), list, position - 1, false); - cursor.close(); - cursor = null; - } - - /** - * {@inheritDoc} - */ - @Override - public Loader<List<Song>> onCreateLoader(final int id, final Bundle args) { - return new GenreSongLoader(getActivity(), args.getLong(Config.ID)); - } - - /** - * {@inheritDoc} - */ - @Override - public void onLoadFinished(final Loader<List<Song>> loader, final List<Song> data) { - // Check for any errors - if (data.isEmpty()) { - return; - } - - // Start fresh - mAdapter.unload(); - // Return the correct count - mAdapter.setCount(data); - // Add the data to the adpater - for (final Song song : data) { - mAdapter.add(song); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onLoaderReset(final Loader<List<Song>> loader) { - // Clear the data in the adapter - mAdapter.unload(); - } - - /** - * Restarts the loader. - */ - public void refresh() { - // Scroll to the stop of the list before restarting the loader. - // Otherwise, if the user has scrolled enough to move the header, it - // becomes misplaced and needs to be reset. - mListView.setSelection(0); - // Wait a moment for the preference to change. - SystemClock.sleep(10); - getLoaderManager().restartLoader(LOADER, getArguments(), this); - } -} diff --git a/src/com/cyngn/eleven/utils/MusicUtils.java b/src/com/cyngn/eleven/utils/MusicUtils.java index a48afb4..7ee3b8f 100644 --- a/src/com/cyngn/eleven/utils/MusicUtils.java +++ b/src/com/cyngn/eleven/utils/MusicUtils.java @@ -1321,6 +1321,8 @@ public final class MusicUtils { try { return mService.position(); } catch (final RemoteException ignored) { + } catch (final IllegalStateException ex) { + Log.e(MusicUtils.class.getSimpleName(), ex.getMessage()); } } return 0; diff --git a/src/com/cyngn/eleven/utils/PreferenceUtils.java b/src/com/cyngn/eleven/utils/PreferenceUtils.java index e4b230e..1a0ce7c 100644 --- a/src/com/cyngn/eleven/utils/PreferenceUtils.java +++ b/src/com/cyngn/eleven/utils/PreferenceUtils.java @@ -21,9 +21,7 @@ import com.cyngn.eleven.ui.fragments.AlbumFragment; import com.cyngn.eleven.ui.fragments.ArtistFragment; import com.cyngn.eleven.ui.fragments.SongFragment; import com.cyngn.eleven.ui.fragments.phone.MusicBrowserPhoneFragment; -import com.cyngn.eleven.ui.fragments.profile.AlbumSongFragment; -import com.cyngn.eleven.ui.fragments.profile.ArtistAlbumFragment; -import com.cyngn.eleven.ui.fragments.profile.ArtistSongFragment; +import com.cyngn.eleven.ui.activities.ArtistDetailActivity; /** * A collection of helpers designed to get and set various preferences across @@ -220,7 +218,7 @@ public final class PreferenceUtils { /** * @return The sort order used for the artist song list in - * {@link ArtistSongFragment} + * {@link ArtistDetailSongAdapter} */ public final String getArtistSongSortOrder() { return mPreferences.getString(ARTIST_SONG_SORT_ORDER, @@ -238,7 +236,7 @@ public final class PreferenceUtils { /** * @return The sort order used for the artist album list in - * {@link ArtistAlbumFragment} + * {@link ArtistDetailActivity} */ public final String getArtistAlbumSortOrder() { return mPreferences.getString(ARTIST_ALBUM_SORT_ORDER, diff --git a/src/com/cyngn/eleven/widgets/AlphaTouchInterceptorOverlay.java b/src/com/cyngn/eleven/widgets/AlphaTouchInterceptorOverlay.java index b8c564f..d3c0a9e 100644 --- a/src/com/cyngn/eleven/widgets/AlphaTouchInterceptorOverlay.java +++ b/src/com/cyngn/eleven/widgets/AlphaTouchInterceptorOverlay.java @@ -21,8 +21,7 @@ import android.widget.FrameLayout; * clicks are intercepted and passed to a listener. Also supports an alpha layer * to dim the content underneath. By default, the alpha layer is the same View * as the touch-interceptor layer. However, for some use-cases, you want a few - * Views to not be dimmed, but still have touches intercepted (for example, - * {@link CarouselTab}'s label appears above the alpha layer). In this case, you + * Views to not be dimmed, but still have touches intercepted. In this case, you * can specify the View to use as the alpha layer via setAlphaLayer(); in this * case you are responsible for managing the z-order of the alpha-layer with * respect to your other sub-views. Typically, you would not use this class diff --git a/src/com/cyngn/eleven/widgets/CarouselTab.java b/src/com/cyngn/eleven/widgets/CarouselTab.java deleted file mode 100644 index 6d304df..0000000 --- a/src/com/cyngn/eleven/widgets/CarouselTab.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.widgets; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; - -import com.cyngn.eleven.Config; -import com.cyngn.eleven.R; -import com.cyngn.eleven.cache.ImageFetcher; -import com.cyngn.eleven.utils.ApolloUtils; -import com.cyngn.eleven.utils.BitmapUtils; -import com.cyngn.eleven.utils.MusicUtils; - -/** - * @author Andrew Neal (andrewdneal@gmail.com) - */ -@SuppressLint("NewApi") -public class CarouselTab extends FrameLayoutWithOverlay { - - private ImageView mPhoto; - - private ImageView mAlbumArt; - - private TextView mLabelView; - - private View mAlphaLayer; - - private View mColorstrip; - - private final ImageFetcher mFetcher; - - /** - * @param context The {@link Context} to use - * @param attrs The attributes of the XML tag that is inflating the view. - */ - public CarouselTab(final Context context, final AttributeSet attrs) { - super(context, attrs); - mFetcher = ApolloUtils.getImageFetcher((Activity) context); - } - - /** - * {@inheritDoc} - */ - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - mPhoto = (ImageView)findViewById(R.id.profile_tab_photo); - mAlbumArt = (ImageView)findViewById(R.id.profile_tab_album_art); - mLabelView = (TextView)findViewById(R.id.profile_tab_label); - mAlphaLayer = findViewById(R.id.profile_tab_alpha_overlay); - mColorstrip = findViewById(R.id.profile_tab_colorstrip); - // Set the alpha layer - setAlphaLayer(mAlphaLayer); - } - - /** - * {@inheritDoc} - */ - @Override - public void setSelected(final boolean selected) { - super.setSelected(selected); - if (selected) { - mColorstrip.setVisibility(View.VISIBLE); - } else { - mColorstrip.setVisibility(View.GONE); - } - } - - /** - * Used to set the artist image in the artist profile. - * - * @param context The {@link Context} to use. - * @param artist The name of the artist in the profile the user is viewing. - */ - public void setArtistPhoto(final Activity context, final String artist) { - if (!TextUtils.isEmpty(artist)) { - mFetcher.loadArtistImage(artist, mPhoto); - } else { - setDefault(context); - } - } - - /** - * Used to blur the artist image in the album profile. - * - * @param context The {@link Context} to use. - * @param artist The artist nmae used to fetch the cached artist image. - * @param album The album name used to fetch the album art in case the - * artist image is missing. - */ - public void blurPhoto(final Activity context, final String artist, - final String album) { - //FIXME: this should go into an AsyncTask - - // First check for the artist image - Bitmap artistImage = mFetcher.getCachedBitmap(artist); - // Second check for cached artwork - if (artistImage == null) { - artistImage = mFetcher.getCachedArtwork(album, artist); - } - // If all else, use the default image - if (artistImage == null) { - artistImage = BitmapFactory.decodeResource(getResources(), R.drawable.default_artist); - } - final Bitmap blur = BitmapUtils.createBlurredBitmap(artistImage); - mPhoto.setImageBitmap(blur); - } - - /** - * Used to set the album art in the album profile. - * - * @param context The {@link Context} to use. - * @param album The name of the album in the profile the user is viewing. - */ - public void setAlbumPhoto(final Activity context, final String album, final String artist) { - if (!TextUtils.isEmpty(album)) { - mAlbumArt.setVisibility(View.VISIBLE); - mFetcher.loadAlbumImage(artist, album, - MusicUtils.getIdForAlbum(context, album, artist), mAlbumArt); - } else { - setDefault(context); - } - } - - /** - * Used to fetch for the album art via Last.fm. - * - * @param context The {@link Context} to use. - * @param album The name of the album in the profile the user is viewing. - * @param artist The name of the album artist in the profile the user is viewing - */ - public void fetchAlbumPhoto(final Activity context, final String album, final String artist) { - if (!TextUtils.isEmpty(album)) { - mFetcher.removeFromCache(ImageFetcher.generateAlbumCacheKey(album, artist)); - mFetcher.loadAlbumImage(artist, album, -1, mAlbumArt); - } else { - setDefault(context); - } - } - - /** - * Used to set the album art in the artist profile. - * - * @param context The {@link Context} to use. - * @param artist The name of the artist in the profile the user is viewing. - */ - public void setArtistAlbumPhoto(final Activity context, final String artist) { - final String lastAlbum = MusicUtils.getLastAlbumForArtist(context, artist); - if (!TextUtils.isEmpty(lastAlbum)) { - // Set the last album the artist played - mFetcher.loadAlbumImage(artist, lastAlbum, - MusicUtils.getIdForAlbum(context, lastAlbum, artist), mPhoto); - // Play the album - mPhoto.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(final View v) { - final long[] albumList = MusicUtils.getSongListForAlbum(getContext(), - MusicUtils.getIdForAlbum(context, lastAlbum, artist)); - MusicUtils.playAll(getContext(), albumList, 0, false); - } - }); - } else { - setDefault(context); - } - } - - /** - * Used to set the header image for playlists and genres. - * - * @param context The {@link Context} to use. - * @param profileName The key used to fetch the image. - */ - public void setPlaylistOrGenrePhoto(final Activity context, - final String profileName) { - if (!TextUtils.isEmpty(profileName)) { - final Bitmap image = mFetcher.getCachedBitmap(profileName); - if (image != null) { - mPhoto.setImageBitmap(image); - } else { - setDefault(context); - } - } else { - setDefault(context); - } - } - - /** - * @param context The {@link Context} to use. - */ - public void setDefault(final Context context) { - mPhoto.setImageDrawable(context.getResources().getDrawable(R.drawable.default_artwork)); - } - - /** - * @param label The string to set as the labe. - */ - public void setLabel(final String label) { - mLabelView.setText(label); - } - - /** - * Selects the label view. - */ - public void showSelectedState() { - mLabelView.setSelected(true); - } - - /** - * Deselects the label view. - */ - public void showDeselectedState() { - mLabelView.setSelected(false); - } - - /** - * @return The {@link ImageView} used to set the header photo. - */ - public ImageView getPhoto() { - return mPhoto; - } - - /** - * @return The {@link ImageView} used to set the album art . - */ - public ImageView getAlbumArt() { - return mAlbumArt; - } - -} diff --git a/src/com/cyngn/eleven/widgets/ProfileTabCarousel.java b/src/com/cyngn/eleven/widgets/ProfileTabCarousel.java deleted file mode 100644 index 928c22e..0000000 --- a/src/com/cyngn/eleven/widgets/ProfileTabCarousel.java +++ /dev/null @@ -1,534 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.widgets; - -import android.animation.Animator; -import android.animation.Animator.AnimatorListener; -import android.animation.ObjectAnimator; -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.Context; -import android.content.res.Resources; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnTouchListener; -import android.view.animation.AnimationUtils; -import android.widget.HorizontalScrollView; -import android.widget.ImageView; - -import com.cyngn.eleven.R; -import com.cyngn.eleven.utils.ApolloUtils; - -/** - * A custom {@link HorizontalScrollView} that displays up to two "tabs" in the - * {@link ProfileActivity}. If the second tab is visible, a fraction of it will - * overflow slightly onto the screen. - */ -@SuppressLint("NewApi") -public class ProfileTabCarousel extends HorizontalScrollView implements OnTouchListener { - - /** - * Number of tabs - */ - private static final int TAB_COUNT = 2; - - /** - * First tab index - */ - private static final int TAB_INDEX_FIRST = 0; - - /** - * Second tab index - */ - private static final int TAB_INDEX_SECOND = 1; - - /** - * Alpha layer to be set on the lable view - */ - private static final float MAX_ALPHA = 0.6f; - - /** - * Y coordinate of the tab at the given index was selected - */ - private static final float[] mYCoordinateArray = new float[TAB_COUNT]; - - /** - * Tab width as defined as a fraction of the screen width - */ - private final float tabWidthScreenWidthFraction; - - /** - * Tab height as defined as a fraction of the screen width - */ - private final float tabHeightScreenWidthFraction; - - /** - * Height of the tab label - */ - private final int mTabDisplayLabelHeight; - - /** - * Height in pixels of the shadow under the tab carousel - */ - private final int mTabShadowHeight; - - /** - * First tab click listener - */ - private final TabClickListener mTabOneTouchInterceptListener = new TabClickListener( - TAB_INDEX_FIRST); - - /** - * Second tab click listener - */ - private final TabClickListener mTabTwoTouchInterceptListener = new TabClickListener( - TAB_INDEX_SECOND); - - /** - * The last scrolled position - */ - private int mLastScrollPosition = Integer.MIN_VALUE; - - /** - * Allowed horizontal scroll length - */ - private int mAllowedHorizontalScrollLength = Integer.MIN_VALUE; - - /** - * Allowed vertical scroll length - */ - private int mAllowedVerticalScrollLength = Integer.MIN_VALUE; - - /** - * Current tab index - */ - private int mCurrentTab = TAB_INDEX_FIRST; - - /** - * Factor to scale scroll-amount sent to listeners - */ - private float mScrollScaleFactor = 1.0f; - - private boolean mScrollToCurrentTab = false; - - private boolean mTabCarouselIsAnimating; - - private boolean mEnableSwipe; - - private CarouselTab mFirstTab; - - private CarouselTab mSecondTab; - - private Listener mListener; - - /** - * @param context The {@link Context} to use - * @param attrs The attributes of the XML tag that is inflating the view. - */ - public ProfileTabCarousel(final Context context, final AttributeSet attrs) { - super(context, attrs); - setOnTouchListener(this); - final Resources mResources = context.getResources(); - mTabDisplayLabelHeight = mResources - .getDimensionPixelSize(R.dimen.profile_photo_shadow_height); - mTabShadowHeight = mResources.getDimensionPixelSize(R.dimen.profile_carousel_label_height); - tabWidthScreenWidthFraction = mResources.getFraction( - R.fraction.tab_width_screen_percentage, 1, 1); - tabHeightScreenWidthFraction = mResources.getFraction( - R.fraction.tab_height_screen_percentage, 1, 1); - } - - /** - * {@inheritDoc} - */ - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - mFirstTab = (CarouselTab)findViewById(R.id.profile_tab_carousel_tab_one); - mFirstTab.setOverlayOnClickListener(mTabOneTouchInterceptListener); - mSecondTab = (CarouselTab)findViewById(R.id.profile_tab_carousel_tab_two); - mSecondTab.setOverlayOnClickListener(mTabTwoTouchInterceptListener); - } - - /** - * {@inheritDoc} - */ - @Override - protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { - final int screenWidth = MeasureSpec.getSize(widthMeasureSpec); - final int tabWidth = Math.round(tabWidthScreenWidthFraction * screenWidth); - - mAllowedHorizontalScrollLength = tabWidth * TAB_COUNT - screenWidth; - if (mAllowedHorizontalScrollLength == 0) { - mScrollScaleFactor = 1.0f; - } else { - mScrollScaleFactor = screenWidth / mAllowedHorizontalScrollLength; - } - - final int tabHeight = Math.round(screenWidth * tabHeightScreenWidthFraction) - + mTabShadowHeight; - if (getChildCount() > 0) { - final View child = getChildAt(0); - - // Add 1 dip of separation between the tabs - final int seperatorPixels = (int)(TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics()) + 0.5f); - - if (mEnableSwipe) { - child.measure( - MeasureSpec.makeMeasureSpec(TAB_COUNT * tabWidth + (TAB_COUNT - 1) - * seperatorPixels, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(tabHeight, MeasureSpec.EXACTLY)); - } else { - child.measure(MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(tabHeight, MeasureSpec.EXACTLY)); - } - } - mAllowedVerticalScrollLength = tabHeight - mTabDisplayLabelHeight - mTabShadowHeight; - setMeasuredDimension(resolveSize(screenWidth, widthMeasureSpec), - resolveSize(tabHeight, heightMeasureSpec)); - } - - /** - * {@inheritDoc} - */ - @SuppressLint("DrawAllocation") - @Override - protected void onLayout(final boolean changed, final int l, final int t, final int r, - final int b) { - super.onLayout(changed, l, t, r, b); - if (!mScrollToCurrentTab) { - return; - } - mScrollToCurrentTab = false; - ApolloUtils.doAfterLayout(this, new Runnable() { - @Override - public void run() { - scrollTo(mCurrentTab == TAB_INDEX_FIRST ? 0 : mAllowedHorizontalScrollLength, 0); - updateAlphaLayers(); - } - }); - } - - /** - * {@inheritDoc} - */ - @Override - protected void onScrollChanged(final int x, final int y, final int oldX, final int oldY) { - super.onScrollChanged(x, y, oldX, oldY); - if (mLastScrollPosition == x) { - return; - } - final int scaledL = (int)(x * mScrollScaleFactor); - final int oldScaledL = (int)(oldX * mScrollScaleFactor); - mListener.onScrollChanged(scaledL, y, oldScaledL, oldY); - mLastScrollPosition = x; - updateAlphaLayers(); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean onTouch(final View v, final MotionEvent event) { - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - mListener.onTouchDown(); - return true; - case MotionEvent.ACTION_UP: - mListener.onTouchUp(); - return true; - } - return super.onTouchEvent(event); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean onInterceptTouchEvent(final MotionEvent ev) { - final boolean mInterceptTouch = super.onInterceptTouchEvent(ev); - if (mInterceptTouch) { - mListener.onTouchDown(); - } - return mInterceptTouch; - } - - /** - * Reset the carousel to the start position (i.e. because new data will be - * loaded in for a different contact). - */ - public void reset() { - scrollTo(0, 0); - setCurrentTab(TAB_INDEX_FIRST); - moveToYCoordinate(TAB_INDEX_FIRST, 0); - } - - /** - * Set the current tab that should be restored when the view is first laid - * out. - */ - public void restoreCurrentTab(final int position) { - setCurrentTab(position); - mScrollToCurrentTab = true; - } - - /** - * Restore the Y position of this view to the last manually requested value. - * This can be done after the parent has been re-laid out again, where this - * view's position could have been lost if the view laid outside its - * parent's bounds. - */ - public void restoreYCoordinate(final int duration, final int tabIndex) { - final float storedYCoordinate = getStoredYCoordinateForTab(tabIndex); - - final ObjectAnimator tabCarouselAnimator = ObjectAnimator.ofFloat(this, "y", - storedYCoordinate); - tabCarouselAnimator.addListener(mTabCarouselAnimatorListener); - tabCarouselAnimator.setInterpolator(AnimationUtils.loadInterpolator(getContext(), - android.R.anim.accelerate_decelerate_interpolator)); - tabCarouselAnimator.setDuration(duration); - tabCarouselAnimator.start(); - } - - /** - * Request that the view move to the given Y coordinate. Also store the Y - * coordinate as the last requested Y coordinate for the given tabIndex. - */ - public void moveToYCoordinate(final int tabIndex, final float y) { - storeYCoordinate(tabIndex, y); - restoreYCoordinate(0, tabIndex); - } - - /** - * Store this information as the last requested Y coordinate for the given - * tabIndex. - */ - public void storeYCoordinate(final int tabIndex, final float y) { - mYCoordinateArray[tabIndex] = y; - } - - /** - * Returns the stored Y coordinate of this view the last time the user was - * on the selected tab given by tabIndex. - */ - public float getStoredYCoordinateForTab(final int tabIndex) { - return mYCoordinateArray[tabIndex]; - } - - /** - * Returns the number of pixels that this view can be scrolled horizontally. - */ - public int getAllowedHorizontalScrollLength() { - return mAllowedHorizontalScrollLength; - } - - /** - * Returns the number of pixels that this view can be scrolled vertically - * while still allowing the tab labels to still show. - */ - public int getAllowedVerticalScrollLength() { - return mAllowedVerticalScrollLength; - } - - /** - * Sets the correct alpha layers over the tabs. - */ - private void updateAlphaLayers() { - float alpha = mLastScrollPosition * MAX_ALPHA / mAllowedHorizontalScrollLength; - alpha = AlphaTouchInterceptorOverlay.clamp(alpha, 0.0f, 1.0f); - mFirstTab.setAlphaLayerValue(alpha); - mSecondTab.setAlphaLayerValue(MAX_ALPHA - alpha); - } - - /** - * @return The {@link ImageView} in the first index. - */ - public ImageView getPhoto() { - return mFirstTab.getPhoto(); - } - - /** - * @return The {@link ImageView} used to set the album art. - */ - public ImageView getAlbumArt() { - return mFirstTab.getAlbumArt(); - } - - /** - * This listener keeps track of whether the tab carousel animation is - * currently going on or not, in order to prevent other simultaneous changes - * to the Y position of the tab carousel which can cause flicker. - */ - private final AnimatorListener mTabCarouselAnimatorListener = new AnimatorListener() { - - @Override - public void onAnimationCancel(final Animator animation) { - mTabCarouselIsAnimating = false; - } - - @Override - public void onAnimationEnd(final Animator animation) { - mTabCarouselIsAnimating = false; - } - - @Override - public void onAnimationRepeat(final Animator animation) { - mTabCarouselIsAnimating = true; - } - - @Override - public void onAnimationStart(final Animator animation) { - mTabCarouselIsAnimating = true; - } - }; - - /** - * @return True if the carousel is currently animating, false otherwise - */ - public boolean isTabCarouselIsAnimating() { - return mTabCarouselIsAnimating; - } - - /** - * Updates the tab selection. - */ - public void setCurrentTab(final int position) { - final CarouselTab selected, deselected; - - switch (position) { - case TAB_INDEX_FIRST: - selected = mFirstTab; - deselected = mSecondTab; - break; - case TAB_INDEX_SECOND: - selected = mSecondTab; - deselected = mFirstTab; - break; - default: - throw new IllegalStateException("Invalid tab position " + position); - } - selected.setSelected(true); - selected.showSelectedState(); - selected.setOverlayClickable(false); - deselected.setSelected(false); - deselected.showDeselectedState(); - deselected.setOverlayClickable(true); - mCurrentTab = position; - } - - /** - * Set the given {@link Listener} to handle carousel events. - */ - public void setListener(final Listener listener) { - mListener = listener; - } - - /** - * Sets the artist image header - * - * @param context The {@link Activity} to use - * @param artistName The artist name used to find the cached artist image - * and used to find the last album played by the artist - */ - public void setArtistProfileHeader(final Activity context, - final String artistName) { - mFirstTab.setLabel(getResources().getString(R.string.page_songs)); - mSecondTab.setLabel(getResources().getString(R.string.page_albums)); - mFirstTab.setArtistPhoto(context, artistName); - mSecondTab.setArtistAlbumPhoto(context, artistName); - mEnableSwipe = true; - } - - /** - * Sets the album image header - * - * @param context The {@link Activity} to use - * @param albumName The key used to find the cached album art - * @param artistName The artist name used to find the cached artist image - */ - public void setAlbumProfileHeader(final Activity context, - final String albumName, final String artistName) { - mFirstTab.setLabel(getResources().getString(R.string.page_songs)); - mFirstTab.setAlbumPhoto(context, albumName, artistName); - mFirstTab.blurPhoto(context, artistName, albumName); - mSecondTab.setVisibility(View.GONE); - mEnableSwipe = false; - } - - /** - * Sets the playlist or genre image header - * - * @param context The {@link Activity} to use - * @param profileName The key used to find the cached image for a playlist - * or genre - */ - public void setPlaylistOrGenreProfileHeader(final Activity context, - final String profileName) { - mFirstTab.setDefault(context); - mFirstTab.setLabel(getResources().getString(R.string.page_songs)); - mFirstTab.setPlaylistOrGenrePhoto(context, profileName); - mSecondTab.setVisibility(View.GONE); - mEnableSwipe = false; - } - - /** - * Used to fetch for the album art via Last.fm. - * - * @param context The {@link Context} to use. - * @param albumName The name of the album in the profile the user is viewing. - * @param artistName The name of the album artist in the profile the user is viewing. - */ - public void fetchAlbumPhoto(final Activity context, final String albumName, - final String artistName) { - mFirstTab.fetchAlbumPhoto(context, albumName, artistName); - } - - /** - * @return The main {@link ImageView} for the first tab - */ - public ImageView getHeaderPhoto() { - return mFirstTab.getPhoto(); - } - - /** When clicked, selects the corresponding tab. */ - private final class TabClickListener implements OnClickListener { - private final int mTab; - - public TabClickListener(final int tab) { - super(); - mTab = tab; - } - - @Override - public void onClick(final View v) { - mListener.onTabSelected(mTab); - } - } - - /** - * Interface for callbacks invoked when the user interacts with the - * carousel. - */ - public interface Listener { - public void onTouchDown(); - - public void onTouchUp(); - - public void onScrollChanged(int l, int t, int oldl, int oldt); - - public void onTabSelected(int position); - } - -} diff --git a/src/com/cyngn/eleven/widgets/VerticalScrollListener.java b/src/com/cyngn/eleven/widgets/VerticalScrollListener.java deleted file mode 100644 index f126b75..0000000 --- a/src/com/cyngn/eleven/widgets/VerticalScrollListener.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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. - */ - -package com.cyngn.eleven.widgets; - -import android.annotation.SuppressLint; -import android.view.View; -import android.widget.AbsListView; -import android.widget.AbsListView.OnScrollListener; - -import com.cyngn.eleven.utils.ApolloUtils; - -@SuppressLint("NewApi") -public class VerticalScrollListener implements OnScrollListener { - - /* Used to determine the off set to scroll the header */ - private final ScrollableHeader mHeader; - - private final ProfileTabCarousel mTabCarousel; - - private final int mPageIndex; - - public VerticalScrollListener(final ScrollableHeader header, final ProfileTabCarousel carousel, - final int pageIndex) { - mHeader = header; - mTabCarousel = carousel; - mPageIndex = pageIndex; - } - - /** - * {@inheritDoc} - */ - @Override - public void onScroll(final AbsListView view, final int firstVisibleItem, - final int visibleItemCount, final int totalItemCount) { - - if (mTabCarousel == null || mTabCarousel.isTabCarouselIsAnimating()) { - return; - } - - final View top = view.getChildAt(firstVisibleItem); - if (top == null) { - return; - } - - if (firstVisibleItem != 0) { - mTabCarousel.moveToYCoordinate(mPageIndex, - -mTabCarousel.getAllowedVerticalScrollLength()); - return; - } - - float y = view.getChildAt(firstVisibleItem).getY(); - final float amtToScroll = Math.max(y, -mTabCarousel.getAllowedVerticalScrollLength()); - mTabCarousel.moveToYCoordinate(mPageIndex, amtToScroll); - } - - /** - * {@inheritDoc} - */ - @Override - public void onScrollStateChanged(final AbsListView view, final int scrollState) { - if (mHeader != null) { - mHeader.onScrollStateChanged(view, scrollState); - } - } - - /** Defines the header to be scrolled. */ - public interface ScrollableHeader { - - /* Used the pause the disk cache while scrolling */ - public void onScrollStateChanged(AbsListView view, int scrollState); - } - -} |