summaryrefslogtreecommitdiffstats
path: root/src/com/cyanogenmod/eleven
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/cyanogenmod/eleven')
-rw-r--r--src/com/cyanogenmod/eleven/ui/HeaderBar.java6
-rw-r--r--src/com/cyanogenmod/eleven/ui/activities/BaseActivity.java20
-rw-r--r--src/com/cyanogenmod/eleven/ui/activities/HomeActivity.java76
-rw-r--r--src/com/cyanogenmod/eleven/ui/activities/SearchActivity.java3
-rw-r--r--src/com/cyanogenmod/eleven/ui/activities/SettingsActivity.java3
-rw-r--r--src/com/cyanogenmod/eleven/ui/activities/SlidingPanelActivity.java12
-rw-r--r--src/com/cyanogenmod/eleven/ui/fragments/AlbumFragment.java1
-rw-r--r--src/com/cyanogenmod/eleven/ui/fragments/ArtistFragment.java1
-rw-r--r--src/com/cyanogenmod/eleven/ui/fragments/AudioPlayerFragment.java17
-rw-r--r--src/com/cyanogenmod/eleven/ui/fragments/BaseFragment.java7
-rw-r--r--src/com/cyanogenmod/eleven/ui/fragments/SongFragment.java1
-rw-r--r--src/com/cyanogenmod/eleven/ui/fragments/phone/MusicBrowserPhoneFragment.java17
-rw-r--r--src/com/cyanogenmod/eleven/widgets/AudioButton.java7
-rw-r--r--src/com/cyanogenmod/eleven/widgets/PlayPauseButton.java6
-rw-r--r--src/com/cyanogenmod/eleven/widgets/PopupMenuButton.java3
-rw-r--r--src/com/cyanogenmod/eleven/widgets/RepeatingImageButton.java4
-rw-r--r--src/com/cyanogenmod/eleven/widgets/ViewPagerTabStrip.java101
-rw-r--r--src/com/cyanogenmod/eleven/widgets/ViewPagerTabs.java224
-rw-r--r--src/com/cyanogenmod/eleven/widgets/theme/HoloSelector.java76
19 files changed, 451 insertions, 134 deletions
diff --git a/src/com/cyanogenmod/eleven/ui/HeaderBar.java b/src/com/cyanogenmod/eleven/ui/HeaderBar.java
index 3d4abbb..afbf13e 100644
--- a/src/com/cyanogenmod/eleven/ui/HeaderBar.java
+++ b/src/com/cyanogenmod/eleven/ui/HeaderBar.java
@@ -33,7 +33,6 @@ import com.cyanogenmod.eleven.loaders.QueueLoader;
import com.cyanogenmod.eleven.menu.CreateNewPlaylist;
import com.cyanogenmod.eleven.utils.MusicUtils;
import com.cyanogenmod.eleven.utils.NavUtils;
-import com.cyanogenmod.eleven.widgets.theme.HoloSelector;
/**
* Simple Header bar wrapper class that also has its own menu bar button.
@@ -62,7 +61,6 @@ public class HeaderBar extends LinearLayout {
super.onFinishInflate();
mMenuButton = (ImageView)findViewById(R.id.header_bar_menu_button);
- mMenuButton.setBackground(new HoloSelector(getContext()));
mMenuButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -71,7 +69,6 @@ public class HeaderBar extends LinearLayout {
});
mSearchButton = (ImageView)findViewById(R.id.header_bar_search_button);
- mSearchButton.setBackground(new HoloSelector(getContext()));
mSearchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -81,7 +78,6 @@ public class HeaderBar extends LinearLayout {
mBackButton = (ImageView)findViewById(R.id.header_bar_up);
- mBackButton.setBackground(new HoloSelector(getContext()));
mTitleText = (TextView)findViewById(R.id.header_bar_title);
}
@@ -173,4 +169,4 @@ public class HeaderBar extends LinearLayout {
return false;
}
-} \ No newline at end of file
+}
diff --git a/src/com/cyanogenmod/eleven/ui/activities/BaseActivity.java b/src/com/cyanogenmod/eleven/ui/activities/BaseActivity.java
index bfaa343..910fb1b 100644
--- a/src/com/cyanogenmod/eleven/ui/activities/BaseActivity.java
+++ b/src/com/cyanogenmod/eleven/ui/activities/BaseActivity.java
@@ -34,6 +34,7 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
+import android.widget.Toolbar;
import com.cyanogenmod.eleven.IElevenService;
import com.cyanogenmod.eleven.MusicPlaybackService;
@@ -57,7 +58,7 @@ import java.util.ArrayList;
* bind to Apollo's service.
* <p>
* {@link SlidingPanelActivity} extends from this skeleton.
- *
+ *
* @author Andrew Neal (andrewdneal@gmail.com)
*/
public abstract class BaseActivity extends FragmentActivity implements ServiceConnection,
@@ -68,6 +69,8 @@ public abstract class BaseActivity extends FragmentActivity implements ServiceCo
*/
private final ArrayList<MusicStateListener> mMusicStateListener = Lists.newArrayList();
+ private Toolbar mToolBar;
+
private int mActionBarHeight;
/**
@@ -121,8 +124,6 @@ public abstract class BaseActivity extends FragmentActivity implements ServiceCo
// Initialize the broadcast receiver
mPlaybackStatus = new PlaybackStatus(this);
- getActionBar().setTitle(getString(R.string.app_name).toUpperCase());
-
// Calculate ActionBar height
TypedValue value = new TypedValue();
if (getTheme().resolveAttribute(android.R.attr.actionBarSize, value, true))
@@ -134,6 +135,11 @@ public abstract class BaseActivity extends FragmentActivity implements ServiceCo
// Set the layout
setContentView(setContentView());
+ mToolBar = (Toolbar) findViewById(R.id.toolbar);
+ setActionBar(mToolBar);
+
+ getActionBar().setTitle(getString(R.string.app_name).toUpperCase());
+
// set the background on the root view
getWindow().getDecorView().getRootView().setBackgroundColor(
getResources().getColor(R.color.background_color));
@@ -280,7 +286,7 @@ public abstract class BaseActivity extends FragmentActivity implements ServiceCo
if (mActionBarBackground == null) {
final int actionBarColor = getResources().getColor(R.color.header_action_bar_color);
mActionBarBackground = new ColorDrawable(actionBarColor);
- getActionBar().setBackgroundDrawable(mActionBarBackground);
+ mToolBar.setBackgroundDrawable(mActionBarBackground);
}
}
@@ -293,6 +299,12 @@ public abstract class BaseActivity extends FragmentActivity implements ServiceCo
mActionBarBackground.setAlpha(alpha);
}
+ public void setActionBarElevation(boolean isElevated) {
+ float targetElevation = isElevated
+ ? getResources().getDimension(R.dimen.action_bar_elevation) : 0;
+ mToolBar.setElevation(targetElevation);
+ }
+
public void setFragmentPadding(boolean enablePadding) {
final int height = enablePadding ? mActionBarHeight : 0;
findViewById(R.id.activity_base_content).setPadding(0, height, 0, 0);
diff --git a/src/com/cyanogenmod/eleven/ui/activities/HomeActivity.java b/src/com/cyanogenmod/eleven/ui/activities/HomeActivity.java
index eacc2fd..6db3675 100644
--- a/src/com/cyanogenmod/eleven/ui/activities/HomeActivity.java
+++ b/src/com/cyanogenmod/eleven/ui/activities/HomeActivity.java
@@ -15,9 +15,13 @@
*/
package com.cyanogenmod.eleven.ui.activities;
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.graphics.Color;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
@@ -27,6 +31,7 @@ import android.support.v4.app.FragmentTransaction;
import android.text.TextUtils;
import android.util.Log;
import android.view.MenuItem;
+import android.view.Window;
import com.cyanogenmod.eleven.Config;
import com.cyanogenmod.eleven.R;
@@ -41,6 +46,7 @@ import com.cyanogenmod.eleven.ui.fragments.phone.MusicBrowserPhoneFragment;
import com.cyanogenmod.eleven.ui.fragments.profile.LastAddedFragment;
import com.cyanogenmod.eleven.ui.fragments.profile.TopTracksFragment;
import com.cyanogenmod.eleven.utils.ApolloUtils;
+import com.cyanogenmod.eleven.utils.BitmapWithColors;
import com.cyanogenmod.eleven.utils.MusicUtils;
import com.cyanogenmod.eleven.utils.NavUtils;
@@ -60,6 +66,7 @@ public class HomeActivity extends SlidingPanelActivity {
private boolean mLoadedBaseFragment = false;
private boolean mHasPendingPlaybackRequest = false;
private Handler mHandler = new Handler();
+ private boolean mBrowsePanelActive = true;
/**
* Used by the up action to determine how to handle this
@@ -91,7 +98,8 @@ public class HomeActivity extends SlidingPanelActivity {
mTopLevelActivity = true;
}
- getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
+ getSupportFragmentManager().addOnBackStackChangedListener(
+ new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
Fragment topFragment = getTopFragment();
@@ -102,19 +110,14 @@ public class HomeActivity extends SlidingPanelActivity {
ISetupActionBar setupActionBar = (ISetupActionBar) topFragment;
setupActionBar.setupActionBar();
- if (topFragment instanceof MusicBrowserPhoneFragment) {
- getActionBar().setIcon(R.drawable.ic_launcher);
- getActionBar().setHomeButtonEnabled(false);
- } else {
- getActionBar().setIcon(R.drawable.ic_action_back_padded);
- getActionBar().setHomeButtonEnabled(true);
- }
+ getActionBar().setDisplayHomeAsUpEnabled(
+ !(topFragment instanceof MusicBrowserPhoneFragment));
}
}
});
// if intent wasn't UI related, process it as a audio playback request
- if ( !intentHandled ) {
+ if (!intentHandled) {
handlePlaybackIntent(launchIntent);
}
@@ -153,6 +156,54 @@ public class HomeActivity extends SlidingPanelActivity {
}
}
+ @Override
+ public void onMetaChanged() {
+ super.onMetaChanged();
+ updateStatusBarColor();
+ }
+
+ @Override
+ protected void onSlide(float slideOffset) {
+ boolean isInBrowser = getCurrentPanel() == Panel.Browse && slideOffset < 0.7f;
+ if (isInBrowser != mBrowsePanelActive) {
+ mBrowsePanelActive = isInBrowser;
+ updateStatusBarColor();
+ }
+ }
+
+ private void updateStatusBarColor() {
+ if (mBrowsePanelActive || MusicUtils.getCurrentAlbumId() < 0) {
+ updateStatusBarColor(getResources().getColor(R.color.primary_dark));
+ } else {
+ new AsyncTask<Void, Void, Integer>() {
+ @Override
+ protected Integer doInBackground(Void... params) {
+ ImageFetcher imageFetcher = ImageFetcher.getInstance(HomeActivity.this);
+ final BitmapWithColors bitmap = imageFetcher.getArtwork(
+ MusicUtils.getAlbumName(), MusicUtils.getCurrentAlbumId(),
+ MusicUtils.getArtistName(), true);
+ return bitmap != null ? bitmap.getVibrantDarkColor() : Color.TRANSPARENT;
+ }
+ @Override
+ protected void onPostExecute(Integer color) {
+ if (color == Color.TRANSPARENT) {
+ color = getResources().getColor(R.color.primary_dark);
+ }
+ updateStatusBarColor(color);
+ }
+ }.execute();
+ }
+ }
+
+ private void updateStatusBarColor(int color) {
+ final Window window = getWindow();
+ ObjectAnimator animator = ObjectAnimator.ofInt(window,
+ "statusBarColor", window.getStatusBarColor(), color);
+ animator.setEvaluator(new ArgbEvaluator());
+ animator.setDuration(300);
+ animator.start();
+ }
+
private boolean parseIntentForFragment(Intent intent) {
boolean handled = false;
if (intent.getAction() != null) {
@@ -199,13 +250,14 @@ public class HomeActivity extends SlidingPanelActivity {
// this happens when they launch search which is its own activity and then
// browse through that back to home activity
mLoadedBaseFragment = true;
- getActionBar().setIcon(R.drawable.ic_action_back_padded);
- getActionBar().setHomeButtonEnabled(true);
+ getActionBar().setDisplayHomeAsUpEnabled(true);
}
// the current top fragment is about to be hidden by what we are replacing
// it with -- so tell that fragment not to make its action bar menu items visible
Fragment oldTop = getTopFragment();
- if(oldTop != null) { oldTop.setMenuVisibility(false); }
+ if (oldTop != null) {
+ oldTop.setMenuVisibility(false);
+ }
transaction.commit();
handled = true;
diff --git a/src/com/cyanogenmod/eleven/ui/activities/SearchActivity.java b/src/com/cyanogenmod/eleven/ui/activities/SearchActivity.java
index a538416..27ef14f 100644
--- a/src/com/cyanogenmod/eleven/ui/activities/SearchActivity.java
+++ b/src/com/cyanogenmod/eleven/ui/activities/SearchActivity.java
@@ -301,8 +301,7 @@ public class SearchActivity extends FragmentActivity implements
// Theme the action bar
final ActionBar actionBar = getActionBar();
- actionBar.setHomeButtonEnabled(true);
- actionBar.setIcon(R.drawable.ic_action_search);
+ actionBar.setDisplayHomeAsUpEnabled(true);
// Get the query String
mFilterString = getIntent().getStringExtra(SearchManager.QUERY);
diff --git a/src/com/cyanogenmod/eleven/ui/activities/SettingsActivity.java b/src/com/cyanogenmod/eleven/ui/activities/SettingsActivity.java
index e2ba8ee..c4f8139 100644
--- a/src/com/cyanogenmod/eleven/ui/activities/SettingsActivity.java
+++ b/src/com/cyanogenmod/eleven/ui/activities/SettingsActivity.java
@@ -43,8 +43,7 @@ public class SettingsActivity extends PreferenceActivity {
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
// UP
- getActionBar().setIcon(R.drawable.ic_action_back_padded);
- getActionBar().setHomeButtonEnabled(true);
+ getActionBar().setDisplayHomeAsUpEnabled(true);
// Add the preferences
addPreferencesFromResource(R.xml.settings);
diff --git a/src/com/cyanogenmod/eleven/ui/activities/SlidingPanelActivity.java b/src/com/cyanogenmod/eleven/ui/activities/SlidingPanelActivity.java
index 35b67f9..5da768f 100644
--- a/src/com/cyanogenmod/eleven/ui/activities/SlidingPanelActivity.java
+++ b/src/com/cyanogenmod/eleven/ui/activities/SlidingPanelActivity.java
@@ -113,13 +113,7 @@ public abstract class SlidingPanelActivity extends BaseActivity {
mFirstPanel.setPanelSlideListener(new SimplePanelSlideListener() {
@Override
public void onPanelSlide(View panel, float slideOffset) {
- if (slideOffset > 0.8f) {
- getActionBar().hide();
- } else if (slideOffset < 0.75f) {
- getActionBar().show();
- }
-
- onSlide();
+ onSlide(slideOffset);
}
@Override
@@ -145,7 +139,7 @@ public abstract class SlidingPanelActivity extends BaseActivity {
mFirstPanel.setSlidingEnabled(false);
}
- onSlide();
+ onSlide(slideOffset);
}
@Override
@@ -256,7 +250,7 @@ public abstract class SlidingPanelActivity extends BaseActivity {
}
}
- protected void onSlide() {
+ protected void onSlide(float slideOffset) {
for (ISlidingPanelListener listener : mSlidingPanelListeners) {
listener.onBeginSlide();
}
diff --git a/src/com/cyanogenmod/eleven/ui/fragments/AlbumFragment.java b/src/com/cyanogenmod/eleven/ui/fragments/AlbumFragment.java
index cc8e6cf..cf459a9 100644
--- a/src/com/cyanogenmod/eleven/ui/fragments/AlbumFragment.java
+++ b/src/com/cyanogenmod/eleven/ui/fragments/AlbumFragment.java
@@ -44,7 +44,6 @@ import com.cyanogenmod.eleven.utils.NavUtils;
import com.cyanogenmod.eleven.utils.PopupMenuHelper;
import com.cyanogenmod.eleven.widgets.IPopupMenuCallback;
import com.cyanogenmod.eleven.widgets.LoadingEmptyContainer;
-import com.viewpagerindicator.TitlePageIndicator;
/**
* This class is used to display all of the albums on a user's device.
diff --git a/src/com/cyanogenmod/eleven/ui/fragments/ArtistFragment.java b/src/com/cyanogenmod/eleven/ui/fragments/ArtistFragment.java
index a759576..a7219d5 100644
--- a/src/com/cyanogenmod/eleven/ui/fragments/ArtistFragment.java
+++ b/src/com/cyanogenmod/eleven/ui/fragments/ArtistFragment.java
@@ -48,7 +48,6 @@ import com.cyanogenmod.eleven.utils.SectionCreatorUtils;
import com.cyanogenmod.eleven.utils.SectionCreatorUtils.IItemCompare;
import com.cyanogenmod.eleven.widgets.IPopupMenuCallback;
import com.cyanogenmod.eleven.widgets.LoadingEmptyContainer;
-import com.viewpagerindicator.TitlePageIndicator;
/**
* This class is used to display all of the artists on a user's device.
diff --git a/src/com/cyanogenmod/eleven/ui/fragments/AudioPlayerFragment.java b/src/com/cyanogenmod/eleven/ui/fragments/AudioPlayerFragment.java
index d081e58..877cda4 100644
--- a/src/com/cyanogenmod/eleven/ui/fragments/AudioPlayerFragment.java
+++ b/src/com/cyanogenmod/eleven/ui/fragments/AudioPlayerFragment.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
+import android.graphics.Outline;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
@@ -39,6 +40,7 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.TextView;
@@ -67,7 +69,6 @@ import com.cyanogenmod.eleven.widgets.QueueButton;
import com.cyanogenmod.eleven.widgets.RepeatButton;
import com.cyanogenmod.eleven.widgets.RepeatingImageButton;
import com.cyanogenmod.eleven.widgets.ShuffleButton;
-import com.cyanogenmod.eleven.widgets.theme.HoloSelector;
import java.lang.ref.WeakReference;
@@ -289,6 +290,17 @@ public class AudioPlayerFragment extends Fragment implements ServiceConnection,
* Initializes the header bar
*/
private void initHeaderBar() {
+ View headerBar = mRootView.findViewById(R.id.audio_player_header);
+ final int bottomActionBarHeight =
+ getResources().getDimensionPixelSize(R.dimen.bottom_action_bar_height);
+
+ headerBar.setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRect(0, -bottomActionBarHeight, view.getWidth(), view.getHeight());
+ }
+ });
+
// Title text
mSongTitle = (TextView) mRootView.findViewById(R.id.header_bar_song_title);
mArtistName = (TextView) mRootView.findViewById(R.id.header_bar_artist_title);
@@ -296,7 +308,6 @@ public class AudioPlayerFragment extends Fragment implements ServiceConnection,
// Buttons
// Search Button
View v = mRootView.findViewById(R.id.header_bar_search_button);
- v.setBackground(new HoloSelector(getActivity()));
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -307,7 +318,6 @@ public class AudioPlayerFragment extends Fragment implements ServiceConnection,
// Add to Playlist Button
// Setup the playlist button - add a click listener to show the context
mAddToPlaylistButton = (ImageView) mRootView.findViewById(R.id.header_bar_add_button);
- mAddToPlaylistButton.setBackground(new HoloSelector(getActivity()));
// Create the context menu when requested
mAddToPlaylistButton.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
@@ -331,7 +341,6 @@ public class AudioPlayerFragment extends Fragment implements ServiceConnection,
// Add the menu button
// menu button
mMenuButton = (ImageView) mRootView.findViewById(R.id.header_bar_menu_button);
- mMenuButton.setBackground(new HoloSelector(getActivity()));
mMenuButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
diff --git a/src/com/cyanogenmod/eleven/ui/fragments/BaseFragment.java b/src/com/cyanogenmod/eleven/ui/fragments/BaseFragment.java
index bdbd454..7bbaf14 100644
--- a/src/com/cyanogenmod/eleven/ui/fragments/BaseFragment.java
+++ b/src/com/cyanogenmod/eleven/ui/fragments/BaseFragment.java
@@ -34,11 +34,16 @@ public abstract class BaseFragment extends Fragment implements MusicStateListene
protected abstract String getTitle();
protected abstract int getLayoutToInflate();
+ protected boolean needsElevatedActionBar() {
+ return true;
+ }
+
@Override
public void setupActionBar() {
getContainingActivity().setupActionBar(getTitle());
getContainingActivity().setActionBarAlpha(255);
getContainingActivity().setFragmentPadding(true);
+ getContainingActivity().setActionBarElevation(needsElevatedActionBar());
}
protected HomeActivity getContainingActivity() {
@@ -84,4 +89,4 @@ public abstract class BaseFragment extends Fragment implements MusicStateListene
public void onPlaylistChanged() {
}
-} \ No newline at end of file
+}
diff --git a/src/com/cyanogenmod/eleven/ui/fragments/SongFragment.java b/src/com/cyanogenmod/eleven/ui/fragments/SongFragment.java
index 597ee3e..1e57580 100644
--- a/src/com/cyanogenmod/eleven/ui/fragments/SongFragment.java
+++ b/src/com/cyanogenmod/eleven/ui/fragments/SongFragment.java
@@ -27,7 +27,6 @@ import com.cyanogenmod.eleven.sectionadapter.SectionListContainer;
import com.cyanogenmod.eleven.ui.fragments.profile.BasicSongFragment;
import com.cyanogenmod.eleven.utils.MusicUtils;
import com.cyanogenmod.eleven.utils.SectionCreatorUtils;
-import com.viewpagerindicator.TitlePageIndicator;
/**
* This class is used to display all of the songs on a user's device.
diff --git a/src/com/cyanogenmod/eleven/ui/fragments/phone/MusicBrowserPhoneFragment.java b/src/com/cyanogenmod/eleven/ui/fragments/phone/MusicBrowserPhoneFragment.java
index b5751ad..1317c4b 100644
--- a/src/com/cyanogenmod/eleven/ui/fragments/phone/MusicBrowserPhoneFragment.java
+++ b/src/com/cyanogenmod/eleven/ui/fragments/phone/MusicBrowserPhoneFragment.java
@@ -31,7 +31,7 @@ import com.cyanogenmod.eleven.ui.fragments.SongFragment;
import com.cyanogenmod.eleven.utils.MusicUtils;
import com.cyanogenmod.eleven.utils.PreferenceUtils;
import com.cyanogenmod.eleven.utils.SortOrder;
-import com.viewpagerindicator.TabPageIndicator;
+import com.cyanogenmod.eleven.widgets.ViewPagerTabs;
/**
* This class is used to hold the {@link ViewPager} used for swiping between the
@@ -111,11 +111,12 @@ public class MusicBrowserPhoneFragment extends BaseFragment {
// Offscreen pager loading limit
mViewPager.setOffscreenPageLimit(mPagerAdapter.getCount() - 1);
- // Initialze the TPI
- final TabPageIndicator pageIndicator = (TabPageIndicator)mRootView
- .findViewById(R.id.fragment_home_phone_pager_titles);
+ // Initialize the tab strip
+ final ViewPagerTabs tabs = (ViewPagerTabs)
+ mRootView.findViewById(R.id.fragment_home_phone_pager_titles);
// Attach the ViewPager
- pageIndicator.setViewPager(mViewPager);
+ tabs.setViewPager(mViewPager);
+ mViewPager.setOnPageChangeListener(tabs);
if (mDefaultPageIdx != INVALID_PAGE_INDEX) {
navigateToPage(mDefaultPageIdx);
@@ -282,6 +283,12 @@ public class MusicBrowserPhoneFragment extends BaseFragment {
return super.onOptionsItemSelected(item);
}
+ @Override
+ protected boolean needsElevatedActionBar() {
+ // our view pager already has elevation
+ return false;
+ }
+
private boolean isArtistPage() {
return mViewPager.getCurrentItem() == MusicFragments.ARTIST.ordinal();
}
diff --git a/src/com/cyanogenmod/eleven/widgets/AudioButton.java b/src/com/cyanogenmod/eleven/widgets/AudioButton.java
index 1f5f70f..1e05e81 100644
--- a/src/com/cyanogenmod/eleven/widgets/AudioButton.java
+++ b/src/com/cyanogenmod/eleven/widgets/AudioButton.java
@@ -8,8 +8,8 @@ import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.ImageButton;
+import com.cyanogenmod.eleven.R;
import com.cyanogenmod.eleven.utils.ApolloUtils;
-import com.cyanogenmod.eleven.widgets.theme.HoloSelector;
public abstract class AudioButton extends ImageButton implements OnClickListener, OnLongClickListener {
public static float ACTIVE_ALPHA = 1.0f;
@@ -18,9 +18,8 @@ public abstract class AudioButton extends ImageButton implements OnClickListener
@SuppressWarnings("deprecation")
public AudioButton(final Context context, final AttributeSet attrs) {
super(context, attrs);
- // Theme the selector
setPadding(0, 0, 0, 0);
- setBackgroundDrawable(new HoloSelector(context));
+ setBackground(getResources().getDrawable(R.drawable.selectable_background));
// Control playback (cycle shuffle)
setOnClickListener(this);
// Show the cheat sheet
@@ -36,4 +35,4 @@ public abstract class AudioButton extends ImageButton implements OnClickListener
return true;
}
}
-} \ No newline at end of file
+}
diff --git a/src/com/cyanogenmod/eleven/widgets/PlayPauseButton.java b/src/com/cyanogenmod/eleven/widgets/PlayPauseButton.java
index 1b8e988..2b68d02 100644
--- a/src/com/cyanogenmod/eleven/widgets/PlayPauseButton.java
+++ b/src/com/cyanogenmod/eleven/widgets/PlayPauseButton.java
@@ -24,11 +24,10 @@ import android.widget.ImageButton;
import com.cyanogenmod.eleven.R;
import com.cyanogenmod.eleven.utils.ApolloUtils;
import com.cyanogenmod.eleven.utils.MusicUtils;
-import com.cyanogenmod.eleven.widgets.theme.HoloSelector;
/**
* A custom {@link ImageButton} that represents the "play and pause" button.
- *
+ *
* @author Andrew Neal (andrewdneal@gmail.com)
*/
public class PlayPauseButton extends ImageButton implements OnClickListener, OnLongClickListener {
@@ -50,8 +49,7 @@ public class PlayPauseButton extends ImageButton implements OnClickListener, OnL
@SuppressWarnings("deprecation")
public PlayPauseButton(final Context context, final AttributeSet attrs) {
super(context, attrs);
- // Theme the selector
- setBackgroundDrawable(new HoloSelector(context));
+ setBackground(getResources().getDrawable(R.drawable.selectable_background));
// Control playback (play/pause)
setOnClickListener(this);
// Show the cheat sheet
diff --git a/src/com/cyanogenmod/eleven/widgets/PopupMenuButton.java b/src/com/cyanogenmod/eleven/widgets/PopupMenuButton.java
index f45bb47..c23ef35 100644
--- a/src/com/cyanogenmod/eleven/widgets/PopupMenuButton.java
+++ b/src/com/cyanogenmod/eleven/widgets/PopupMenuButton.java
@@ -21,6 +21,8 @@ import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
+import com.cyanogenmod.eleven.R;
+
public class PopupMenuButton extends ImageView implements IPopupMenuCallback,
View.OnClickListener {
protected int mPosition = -1;
@@ -29,6 +31,7 @@ public class PopupMenuButton extends ImageView implements IPopupMenuCallback,
public PopupMenuButton(Context context, AttributeSet attrs) {
super(context, attrs);
+ setBackground(getResources().getDrawable(R.drawable.selectable_background_light));
setOnClickListener(this);
}
diff --git a/src/com/cyanogenmod/eleven/widgets/RepeatingImageButton.java b/src/com/cyanogenmod/eleven/widgets/RepeatingImageButton.java
index 9fb6758..d51154b 100644
--- a/src/com/cyanogenmod/eleven/widgets/RepeatingImageButton.java
+++ b/src/com/cyanogenmod/eleven/widgets/RepeatingImageButton.java
@@ -23,7 +23,6 @@ import android.widget.ImageButton;
import com.cyanogenmod.eleven.R;
import com.cyanogenmod.eleven.utils.ApolloUtils;
import com.cyanogenmod.eleven.utils.MusicUtils;
-import com.cyanogenmod.eleven.widgets.theme.HoloSelector;
/**
* A {@link ImageButton} that will repeatedly call a 'listener' method as long
@@ -47,9 +46,8 @@ public class RepeatingImageButton extends ImageButton implements OnClickListener
@SuppressWarnings("deprecation")
public RepeatingImageButton(final Context context, final AttributeSet attrs) {
super(context, attrs);
- // Theme the selector
setPadding(0, 0, 0, 0);
- setBackgroundDrawable(new HoloSelector(context));
+ setBackground(getResources().getDrawable(R.drawable.selectable_background));
setFocusable(true);
setLongClickable(true);
setOnClickListener(this);
diff --git a/src/com/cyanogenmod/eleven/widgets/ViewPagerTabStrip.java b/src/com/cyanogenmod/eleven/widgets/ViewPagerTabStrip.java
new file mode 100644
index 0000000..d1ef9c3
--- /dev/null
+++ b/src/com/cyanogenmod/eleven/widgets/ViewPagerTabStrip.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.cyanogenmod.eleven.widgets;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import com.cyanogenmod.eleven.R;
+
+public class ViewPagerTabStrip extends LinearLayout {
+ private int mSelectedUnderlineThickness;
+ private final Paint mSelectedUnderlinePaint;
+
+ private int mIndexForSelection;
+ private float mSelectionOffset;
+
+ public ViewPagerTabStrip(Context context) {
+ this(context, null);
+ }
+
+ public ViewPagerTabStrip(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ final Resources res = context.getResources();
+
+ mSelectedUnderlineThickness =
+ res.getDimensionPixelSize(R.dimen.tab_selected_underline_height);
+ int underlineColor = res.getColor(R.color.tab_selected_underline_color);
+ int backgroundColor = res.getColor(R.color.header_action_bar_color);
+
+ mSelectedUnderlinePaint = new Paint();
+ mSelectedUnderlinePaint.setColor(underlineColor);
+
+ setBackgroundColor(backgroundColor);
+ setWillNotDraw(false);
+ }
+
+ /**
+ * Notifies this view that view pager has been scrolled. We save the tab index
+ * and selection offset for interpolating the position and width of selection
+ * underline.
+ */
+ void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ mIndexForSelection = position;
+ mSelectionOffset = positionOffset;
+ invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ int childCount = getChildCount();
+
+ // Thick colored underline below the current selection
+ if (childCount > 0) {
+ View selectedTitle = getChildAt(mIndexForSelection);
+ int selectedLeft = selectedTitle.getLeft();
+ int selectedRight = selectedTitle.getRight();
+ final boolean isRtl = isRtl();
+ final boolean hasNextTab = isRtl ? mIndexForSelection > 0
+ : (mIndexForSelection < (getChildCount() - 1));
+ if ((mSelectionOffset > 0.0f) && hasNextTab) {
+ // Draw the selection partway between the tabs
+ View nextTitle = getChildAt(mIndexForSelection + (isRtl ? -1 : 1));
+ int nextLeft = nextTitle.getLeft();
+ int nextRight = nextTitle.getRight();
+
+ selectedLeft = (int) (mSelectionOffset * nextLeft +
+ (1.0f - mSelectionOffset) * selectedLeft);
+ selectedRight = (int) (mSelectionOffset * nextRight +
+ (1.0f - mSelectionOffset) * selectedRight);
+ }
+
+ int height = getHeight();
+ canvas.drawRect(selectedLeft, height - mSelectedUnderlineThickness,
+ selectedRight, height, mSelectedUnderlinePaint);
+ }
+ }
+
+ private boolean isRtl() {
+ return getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+ }
+}
diff --git a/src/com/cyanogenmod/eleven/widgets/ViewPagerTabs.java b/src/com/cyanogenmod/eleven/widgets/ViewPagerTabs.java
new file mode 100644
index 0000000..c02926d
--- /dev/null
+++ b/src/com/cyanogenmod/eleven/widgets/ViewPagerTabs.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.cyanogenmod.eleven.widgets;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.TypedArray;
+import android.graphics.Outline;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+import android.widget.FrameLayout;
+import android.widget.HorizontalScrollView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.cyanogenmod.eleven.R;
+
+/**
+ * Lightweight implementation of ViewPager tabs. This looks similar to traditional actionBar tabs,
+ * but allows for the view containing the tabs to be placed anywhere on screen. Text-related
+ * attributes can also be assigned in XML - these will get propogated to the child TextViews
+ * automatically.
+ */
+public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnPageChangeListener {
+
+ ViewPager mPager;
+ private ViewPagerTabStrip mTabStrip;
+
+ /**
+ * Linearlayout that will contain the TextViews serving as tabs. This is the only child
+ * of the parent HorizontalScrollView.
+ */
+ final int mTextStyle;
+ final ColorStateList mTextColor;
+ final int mTextSize;
+ final boolean mTextAllCaps;
+ int mPrevSelected = -1;
+ int mSidePadding;
+
+ private static final ViewOutlineProvider VIEW_BOUNDS_OUTLINE_PROVIDER =
+ new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRect(0, 0, view.getWidth(), view.getHeight());
+ }
+ };
+
+ private static final int TAB_SIDE_PADDING_IN_DPS = 10;
+
+ // TODO: This should use <declare-styleable> in the future
+ private static final int[] ATTRS = new int[] {
+ android.R.attr.textSize,
+ android.R.attr.textStyle,
+ android.R.attr.textColor,
+ android.R.attr.textAllCaps
+ };
+
+ /**
+ * Simulates actionbar tab behavior by showing a toast with the tab title when long clicked.
+ */
+ private class OnTabLongClickListener implements OnLongClickListener {
+ final int mPosition;
+
+ public OnTabLongClickListener(int position) {
+ mPosition = position;
+ }
+
+ @Override
+ public boolean onLongClick(View v) {
+ final int[] screenPos = new int[2];
+ getLocationOnScreen(screenPos);
+
+ final Context context = getContext();
+ final int width = getWidth();
+ final int height = getHeight();
+ final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
+
+ Toast toast = Toast.makeText(context, mPager.getAdapter().getPageTitle(mPosition),
+ Toast.LENGTH_SHORT);
+
+ // Show the toast under the tab
+ toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL,
+ (screenPos[0] + width / 2) - screenWidth / 2, screenPos[1] + height);
+
+ toast.show();
+ return true;
+ }
+ }
+
+ public ViewPagerTabs(Context context) {
+ this(context, null);
+ }
+
+ public ViewPagerTabs(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ViewPagerTabs(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setFillViewport(true);
+
+ mSidePadding = (int) (getResources().getDisplayMetrics().density * TAB_SIDE_PADDING_IN_DPS);
+
+ final TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
+ mTextSize = a.getDimensionPixelSize(0, 0);
+ mTextStyle = a.getInt(1, 0);
+ mTextColor = a.getColorStateList(2);
+ mTextAllCaps = a.getBoolean(3, false);
+
+ mTabStrip = new ViewPagerTabStrip(context);
+ addView(mTabStrip,
+ new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
+ a.recycle();
+
+ // enable shadow casting from view bounds
+ setOutlineProvider(VIEW_BOUNDS_OUTLINE_PROVIDER);
+ }
+
+ public void setViewPager(ViewPager viewPager) {
+ mPager = viewPager;
+ addTabs(mPager.getAdapter());
+ }
+
+ private void addTabs(PagerAdapter adapter) {
+ mTabStrip.removeAllViews();
+
+ final int count = adapter.getCount();
+ for (int i = 0; i < count; i++) {
+ addTab(adapter.getPageTitle(i), i);
+ }
+ }
+
+ private void addTab(CharSequence tabTitle, final int position) {
+ final TextView textView = new TextView(getContext());
+ textView.setText(tabTitle);
+ textView.setBackgroundResource(R.drawable.view_pager_tab_background);
+ textView.setGravity(Gravity.CENTER);
+ textView.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mPager.setCurrentItem(getRtlPosition(position));
+ }
+ });
+
+ textView.setOnLongClickListener(new OnTabLongClickListener(position));
+
+ // Assign various text appearance related attributes to child views.
+ if (mTextStyle > 0) {
+ textView.setTypeface(textView.getTypeface(), mTextStyle);
+ }
+ if (mTextSize > 0) {
+ textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
+ }
+ if (mTextColor != null) {
+ textView.setTextColor(mTextColor);
+ }
+ textView.setAllCaps(mTextAllCaps);
+ textView.setPadding(mSidePadding, 0, mSidePadding, 0);
+ mTabStrip.addView(textView, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.MATCH_PARENT, 1));
+ // Default to the first child being selected
+ if (position == 0) {
+ mPrevSelected = 0;
+ textView.setSelected(true);
+ }
+ }
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ position = getRtlPosition(position);
+ int tabStripChildCount = mTabStrip.getChildCount();
+ if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
+ return;
+ }
+
+ mTabStrip.onPageScrolled(position, positionOffset, positionOffsetPixels);
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+ position = getRtlPosition(position);
+ if (mPrevSelected >= 0) {
+ mTabStrip.getChildAt(mPrevSelected).setSelected(false);
+ }
+ final View selectedChild = mTabStrip.getChildAt(position);
+ selectedChild.setSelected(true);
+
+ // Update scroll position
+ final int scrollPos = selectedChild.getLeft() - (getWidth() - selectedChild.getWidth()) / 2;
+ smoothScrollTo(scrollPos, 0);
+ mPrevSelected = position;
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ }
+
+ private int getRtlPosition(int position) {
+ if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+ return mTabStrip.getChildCount() - 1 - position;
+ }
+ return position;
+ }
+}
+
diff --git a/src/com/cyanogenmod/eleven/widgets/theme/HoloSelector.java b/src/com/cyanogenmod/eleven/widgets/theme/HoloSelector.java
deleted file mode 100644
index 2ec6348..0000000
--- a/src/com/cyanogenmod/eleven/widgets/theme/HoloSelector.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2012 Andrew Neal
- * Copyright (C) 2014 The CyanogenMod Project
- * Licensed under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
- * or agreed to in writing, software distributed under the License is
- * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
- */
-
-package com.cyanogenmod.eleven.widgets.theme;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.StateListDrawable;
-
-import com.cyanogenmod.eleven.R;
-
-import java.lang.ref.WeakReference;
-
-/**
- * A themeable {@link StateListDrawable}.
- *
- * @author Andrew Neal (andrewdneal@gmail.com)
- */
-public class HoloSelector extends StateListDrawable {
-
- /**
- * Used to theme the touched and focused colors
- */
- private static final String RESOURCE_NAME = "holo_selector";
-
- /**
- * Focused state
- */
- private static final int FOCUSED = android.R.attr.state_focused;
-
- /**
- * Pressed state
- */
- private static final int PRESSED = android.R.attr.state_pressed;
-
- /**
- * Constructor for <code>HoloSelector</code>
- *
- * @param context The {@link Context} to use.
- */
- @SuppressLint("NewApi")
- public HoloSelector(final Context context) {
- final int themeColor = context.getResources().getColor(R.color.holo_blue_light);
- // Focused
- addState(new int[] {
- FOCUSED
- }, makeColorDrawable(themeColor));
- // Pressed
- addState(new int[] {
- PRESSED
- }, makeColorDrawable(themeColor));
- // Default
- addState(new int[] {}, makeColorDrawable(Color.TRANSPARENT));
- setExitFadeDuration(400);
- }
-
- /**
- * @param color The color to use.
- * @return A new {@link ColorDrawable}.
- */
- private static final ColorDrawable makeColorDrawable(final int color) {
- return new WeakReference<ColorDrawable>(new ColorDrawable(color)).get();
- }
-}