diff --git a/mobile/build.gradle b/mobile/build.gradle index 65f275cf3..55146e86d 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -50,13 +50,13 @@ repositories { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.google.android.gms:play-services-cast:8.3.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' compile 'com.android.support:support-v4:23.1.1' compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:cardview-v7:23.1.1' compile 'com.android.support:mediarouter-v7:23.1.1' compile 'com.android.support:leanback-v17:23.1.1' - compile (name:'CastCompanionLibrary-debug-2.6.1', ext:'aar') compile 'com.github.amlcurran.showcaseview:library:5.0.0' + compile 'com.android.support:design:23.1.1' } diff --git a/mobile/src/main/java/com/example/android/uamp/ui/ActionBarCastActivity.java b/mobile/src/main/java/com/example/android/uamp/ui/ActionBarCastActivity.java index 78d5d6b33..d728f2707 100644 --- a/mobile/src/main/java/com/example/android/uamp/ui/ActionBarCastActivity.java +++ b/mobile/src/main/java/com/example/android/uamp/ui/ActionBarCastActivity.java @@ -19,9 +19,9 @@ import android.app.FragmentManager; import android.content.Intent; import android.content.res.Configuration; -import android.graphics.Color; import android.os.Bundle; import android.os.Handler; +import android.support.design.widget.NavigationView; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; @@ -32,15 +32,10 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ListView; -import android.widget.SimpleAdapter; import com.example.android.uamp.R; import com.example.android.uamp.utils.LogHelper; import com.example.android.uamp.utils.PrefUtils; -import com.example.android.uamp.utils.ResourceHelper; import com.github.amlcurran.showcaseview.ShowcaseView; import com.github.amlcurran.showcaseview.targets.ViewTarget; import com.google.android.libraries.cast.companionlibrary.cast.VideoCastManager; @@ -67,8 +62,6 @@ public abstract class ActionBarCastActivity extends AppCompatActivity { private Toolbar mToolbar; private ActionBarDrawerToggle mDrawerToggle; private DrawerLayout mDrawerLayout; - private ListView mDrawerList; - private DrawerMenuContents mDrawerMenuContents; private boolean mToolbarInitialized; @@ -117,14 +110,23 @@ public void run() { @Override public void onDrawerClosed(View drawerView) { if (mDrawerToggle != null) mDrawerToggle.onDrawerClosed(drawerView); - int position = mItemToOpenWhenDrawerCloses; - if (position >= 0) { + if (mItemToOpenWhenDrawerCloses >= 0) { Bundle extras = ActivityOptions.makeCustomAnimation( ActionBarCastActivity.this, R.anim.fade_in, R.anim.fade_out).toBundle(); - Class activityClass = mDrawerMenuContents.getActivity(position); - startActivity(new Intent(ActionBarCastActivity.this, activityClass), extras); - finish(); + Class activityClass = null; + switch (mItemToOpenWhenDrawerCloses) { + case R.id.navigation_allmusic: + activityClass = MusicPlayerActivity.class; + break; + case R.id.navigation_playlists: + activityClass = PlaceholderActivity.class; + break; + } + if (activityClass != null) { + startActivity(new Intent(ActionBarCastActivity.this, activityClass), extras); + finish(); + } } } @@ -269,21 +271,19 @@ protected void initializeToolbar() { } mToolbar.inflateMenu(R.menu.main); - mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); + mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); if (mDrawerLayout != null) { - mDrawerList = (ListView) findViewById(R.id.drawer_list); - if (mDrawerList == null) { - throw new IllegalStateException("A layout with a drawerLayout is required to" + - "include a ListView with id 'drawerList'"); + NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); + if (navigationView == null) { + throw new IllegalStateException("Layout requires a NavigationView " + + "with id 'nav_view'"); } // Create an ActionBarDrawerToggle that will handle opening/closing of the drawer: mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.open_content_drawer, R.string.close_content_drawer); mDrawerLayout.setDrawerListener(mDrawerListener); - mDrawerLayout.setStatusBarBackgroundColor( - ResourceHelper.getThemeColor(this, R.attr.colorPrimary, android.R.color.black)); - populateDrawerItems(); + populateDrawerItems(navigationView); setSupportActionBar(mToolbar); updateDrawerToggle(); } else { @@ -293,39 +293,22 @@ protected void initializeToolbar() { mToolbarInitialized = true; } - private void populateDrawerItems() { - mDrawerMenuContents = new DrawerMenuContents(this); - final int selectedPosition = mDrawerMenuContents.getPosition(this.getClass()); - final int unselectedColor = Color.WHITE; - final int selectedColor = getResources().getColor(R.color.drawer_item_selected_background); - SimpleAdapter adapter = new SimpleAdapter(this, mDrawerMenuContents.getItems(), - R.layout.drawer_list_item, - new String[]{DrawerMenuContents.FIELD_TITLE, DrawerMenuContents.FIELD_ICON}, - new int[]{R.id.drawer_item_title, R.id.drawer_item_icon}) { - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View view = super.getView(position, convertView, parent); - int color = unselectedColor; - if (position == selectedPosition) { - color = selectedColor; - } - view.setBackgroundColor(color); - return view; - } - }; - - mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - if (position != selectedPosition) { - view.setBackgroundColor(getResources().getColor( - R.color.drawer_item_selected_background)); - mItemToOpenWhenDrawerCloses = position; - } - mDrawerLayout.closeDrawers(); - } - }); - mDrawerList.setAdapter(adapter); + private void populateDrawerItems(NavigationView navigationView) { + navigationView.setNavigationItemSelectedListener( + new NavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(MenuItem menuItem) { + menuItem.setChecked(true); + mItemToOpenWhenDrawerCloses = menuItem.getItemId(); + mDrawerLayout.closeDrawers(); + return true; + } + }); + if (MusicPlayerActivity.class.isAssignableFrom(getClass())) { + navigationView.setCheckedItem(R.id.navigation_allmusic); + } else if (PlaceholderActivity.class.isAssignableFrom(getClass())) { + navigationView.setCheckedItem(R.id.navigation_playlists); + } } protected void updateDrawerToggle() { diff --git a/mobile/src/main/java/com/example/android/uamp/ui/DrawerMenuContents.java b/mobile/src/main/java/com/example/android/uamp/ui/DrawerMenuContents.java deleted file mode 100644 index 97afe3021..000000000 --- a/mobile/src/main/java/com/example/android/uamp/ui/DrawerMenuContents.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.example.android.uamp.ui; - -import android.content.Context; - -import com.example.android.uamp.R; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class DrawerMenuContents { - public static final String FIELD_TITLE = "title"; - public static final String FIELD_ICON = "icon"; - - private final ArrayList> items; - private final Class[] activities; - - public DrawerMenuContents(Context ctx) { - activities = new Class[2]; - items = new ArrayList<>(2); - - activities[0] = MusicPlayerActivity.class; - items.add(populateDrawerItem(ctx.getString(R.string.drawer_allmusic_title), - R.drawable.ic_allmusic_black_24dp)); - - activities[1] = PlaceholderActivity.class; - items.add(populateDrawerItem(ctx.getString(R.string.drawer_playlists_title), - R.drawable.ic_playlist_music_black_24dp)); - } - - public List> getItems() { - return items; - } - - public Class getActivity(int position) { - return activities[position]; - } - - public int getPosition(Class activityClass) { - for (int i=0; i populateDrawerItem(String title, int icon) { - HashMap item = new HashMap<>(); - item.put(FIELD_TITLE, title); - item.put(FIELD_ICON, icon); - return item; - } -} diff --git a/mobile/src/main/java/com/example/android/uamp/ui/FullScreenPlayerActivity.java b/mobile/src/main/java/com/example/android/uamp/ui/FullScreenPlayerActivity.java index 5db508f63..bab060415 100644 --- a/mobile/src/main/java/com/example/android/uamp/ui/FullScreenPlayerActivity.java +++ b/mobile/src/main/java/com/example/android/uamp/ui/FullScreenPlayerActivity.java @@ -29,6 +29,7 @@ import android.os.Handler; import android.os.SystemClock; import android.support.annotation.NonNull; +import android.text.format.DateUtils; import android.view.View; import android.widget.ImageView; import android.widget.ProgressBar; @@ -39,7 +40,6 @@ import com.example.android.uamp.MusicService; import com.example.android.uamp.R; import com.example.android.uamp.utils.LogHelper; -import com.google.android.libraries.cast.companionlibrary.utils.Utils; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -186,7 +186,7 @@ public void onClick(View v) { mSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - mStart.setText(Utils.formatMillis(progress)); + mStart.setText(DateUtils.formatElapsedTime(progress / 1000)); } @Override @@ -334,7 +334,7 @@ private void updateDuration(MediaMetadata metadata) { LogHelper.d(TAG, "updateDuration called "); int duration = (int) metadata.getLong(MediaMetadata.METADATA_KEY_DURATION); mSeekbar.setMax(duration); - mEnd.setText(Utils.formatMillis(duration)); + mEnd.setText(DateUtils.formatElapsedTime(duration/1000)); } private void updatePlaybackState(PlaybackState state) { diff --git a/mobile/src/main/java/com/example/android/uamp/ui/ScrimInsetsRelativeLayout.java b/mobile/src/main/java/com/example/android/uamp/ui/ScrimInsetsRelativeLayout.java deleted file mode 100644 index d4850adab..000000000 --- a/mobile/src/main/java/com/example/android/uamp/ui/ScrimInsetsRelativeLayout.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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.example.android.uamp.ui; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.support.annotation.NonNull; -import android.support.v4.view.ViewCompat; -import android.util.AttributeSet; -import android.widget.RelativeLayout; - -import com.example.android.uamp.R; - -/** - * A layout that draws something in the insets passed to {@link #fitSystemWindows(Rect)}, i.e. - * the area above UI chrome (status and navigation bars, overlay action bars). - */ -public class ScrimInsetsRelativeLayout extends RelativeLayout { - private Drawable mInsetForeground; - - private Rect mInsets; - private final Rect mTempRect = new Rect(); - private OnInsetsCallback mOnInsetsCallback; - - public ScrimInsetsRelativeLayout(Context context) { - super(context); - init(context, null, 0); - } - - public ScrimInsetsRelativeLayout(Context context, AttributeSet attrs) { - super(context, attrs); - init(context, attrs, 0); - } - - public ScrimInsetsRelativeLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(context, attrs, defStyle); - } - - private void init(Context context, AttributeSet attrs, int defStyle) { - final TypedArray a = context.obtainStyledAttributes(attrs, - R.styleable.ScrimInsetsView, defStyle, 0); - if (a == null) { - return; - } - mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsView_insetForeground); - a.recycle(); - - setWillNotDraw(true); - } - - @SuppressWarnings("deprecation") - @Override - protected boolean fitSystemWindows(@NonNull Rect insets) { - mInsets = new Rect(insets); - setWillNotDraw(mInsetForeground == null); - ViewCompat.postInvalidateOnAnimation(this); - if (mOnInsetsCallback != null) { - mOnInsetsCallback.onInsetsChanged(insets); - } - return true; // consume insets - } - - @Override - public void draw(@NonNull Canvas canvas) { - super.draw(canvas); - - int width = getWidth(); - int height = getHeight(); - if (mInsets != null && mInsetForeground != null) { - int sc = canvas.save(); - canvas.translate(getScrollX(), getScrollY()); - - // Top - mTempRect.set(0, 0, width, mInsets.top); - mInsetForeground.setBounds(mTempRect); - mInsetForeground.draw(canvas); - - // Bottom - mTempRect.set(0, height - mInsets.bottom, width, height); - mInsetForeground.setBounds(mTempRect); - mInsetForeground.draw(canvas); - - // Left - mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom); - mInsetForeground.setBounds(mTempRect); - mInsetForeground.draw(canvas); - - // Right - mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom); - mInsetForeground.setBounds(mTempRect); - mInsetForeground.draw(canvas); - - canvas.restoreToCount(sc); - } - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - if (mInsetForeground != null) { - mInsetForeground.setCallback(this); - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - if (mInsetForeground != null) { - mInsetForeground.setCallback(null); - } - } - - /** - * Allows the calling container to specify a callback for custom processing when insets change - * (i.e. when {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on - * UI elements based on UI chrome insets (e.g. a Google Map or a ListView). When using with - * ListView or GridView, remember to set clipToPadding to false. - */ - public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) { - mOnInsetsCallback = onInsetsCallback; - } - - public interface OnInsetsCallback { - void onInsetsChanged(Rect insets); - } -} \ No newline at end of file diff --git a/mobile/src/main/res/drawable-hdpi/ic_menu.png b/mobile/src/main/res/drawable-hdpi/ic_menu.png new file mode 100644 index 000000000..8962cbd91 Binary files /dev/null and b/mobile/src/main/res/drawable-hdpi/ic_menu.png differ diff --git a/mobile/src/main/res/drawable-mdpi/ic_menu.png b/mobile/src/main/res/drawable-mdpi/ic_menu.png new file mode 100644 index 000000000..c62db8c86 Binary files /dev/null and b/mobile/src/main/res/drawable-mdpi/ic_menu.png differ diff --git a/mobile/src/main/res/drawable-xhdpi/ic_menu.png b/mobile/src/main/res/drawable-xhdpi/ic_menu.png new file mode 100644 index 000000000..36859f094 Binary files /dev/null and b/mobile/src/main/res/drawable-xhdpi/ic_menu.png differ diff --git a/mobile/src/main/res/drawable-xxhdpi/ic_menu.png b/mobile/src/main/res/drawable-xxhdpi/ic_menu.png new file mode 100644 index 000000000..1a5109828 Binary files /dev/null and b/mobile/src/main/res/drawable-xxhdpi/ic_menu.png differ diff --git a/mobile/src/main/res/drawable-xxxhdpi/ic_menu.png b/mobile/src/main/res/drawable-xxxhdpi/ic_menu.png new file mode 100644 index 000000000..c15d63467 Binary files /dev/null and b/mobile/src/main/res/drawable-xxxhdpi/ic_menu.png differ diff --git a/mobile/src/main/res/values/attrs.xml b/mobile/src/main/res/drawable/fullscreen_toolbar_bg_gradient.xml similarity index 74% rename from mobile/src/main/res/values/attrs.xml rename to mobile/src/main/res/drawable/fullscreen_toolbar_bg_gradient.xml index 8cb5af64b..78360acad 100644 --- a/mobile/src/main/res/values/attrs.xml +++ b/mobile/src/main/res/drawable/fullscreen_toolbar_bg_gradient.xml @@ -14,8 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - - - \ No newline at end of file + + + \ No newline at end of file diff --git a/mobile/src/main/res/layout/activity_full_player.xml b/mobile/src/main/res/layout/activity_full_player.xml index 69abf2b87..0453df1c6 100644 --- a/mobile/src/main/res/layout/activity_full_player.xml +++ b/mobile/src/main/res/layout/activity_full_player.xml @@ -173,7 +173,7 @@ limitations under the License. android:layout_height="?attr/actionBarSize" android:layout_alignParentStart="true" android:layout_alignParentTop="true" - android:background="@drawable/actionbar_bg_gradient_light" + android:background="@drawable/fullscreen_toolbar_bg_gradient" android:popupTheme="@style/ThemeOverlay.AppCompat.Light" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/> diff --git a/mobile/src/main/res/layout/activity_placeholder.xml b/mobile/src/main/res/layout/activity_placeholder.xml index 4bae121da..c5df14f1b 100644 --- a/mobile/src/main/res/layout/activity_placeholder.xml +++ b/mobile/src/main/res/layout/activity_placeholder.xml @@ -16,9 +16,9 @@ --> - + + app:cardElevation="8dp"> - + diff --git a/mobile/src/main/res/layout/activity_player.xml b/mobile/src/main/res/layout/activity_player.xml index 0dd969690..4ca99092d 100644 --- a/mobile/src/main/res/layout/activity_player.xml +++ b/mobile/src/main/res/layout/activity_player.xml @@ -16,9 +16,9 @@ --> - + + app:cardElevation="8dp"> + android:id="@+id/fragment_playback_controls" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + tools:layout="@layout/fragment_playback_controls" /> - + \ No newline at end of file diff --git a/mobile/src/main/res/layout/drawer_list_item.xml b/mobile/src/main/res/layout/drawer_list_item.xml deleted file mode 100644 index 02eeb14d7..000000000 --- a/mobile/src/main/res/layout/drawer_list_item.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - diff --git a/mobile/src/main/res/layout/include_drawerlist.xml b/mobile/src/main/res/layout/include_drawerlist.xml deleted file mode 100644 index 380de853b..000000000 --- a/mobile/src/main/res/layout/include_drawerlist.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - diff --git a/mobile/src/main/res/layout/include_toolbar.xml b/mobile/src/main/res/layout/include_toolbar.xml index ca1749a8f..7f8fd2ccd 100644 --- a/mobile/src/main/res/layout/include_toolbar.xml +++ b/mobile/src/main/res/layout/include_toolbar.xml @@ -14,13 +14,20 @@ See the License for the specific language governing permissions and limitations under the License. --> - + android:layout_width="match_parent" + android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> + + + + \ No newline at end of file diff --git a/mobile/src/main/res/layout/nav_header.xml b/mobile/src/main/res/layout/nav_header.xml new file mode 100644 index 000000000..e3bdb2654 --- /dev/null +++ b/mobile/src/main/res/layout/nav_header.xml @@ -0,0 +1,33 @@ + + + + + + + + \ No newline at end of file diff --git a/mobile/src/main/res/menu/drawer.xml b/mobile/src/main/res/menu/drawer.xml new file mode 100644 index 000000000..475541d82 --- /dev/null +++ b/mobile/src/main/res/menu/drawer.xml @@ -0,0 +1,29 @@ + + + + + + + + \ No newline at end of file