merge in nyc-mr1-release history after reset to nyc-mr1-dev
diff --git a/design/res/layout/design_bottom_navigation_item.xml b/design/res/layout/design_bottom_navigation_item.xml
index cc7bb5f..67df838 100644
--- a/design/res/layout/design_bottom_navigation_item.xml
+++ b/design/res/layout/design_bottom_navigation_item.xml
@@ -34,6 +34,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/design_bottom_navigation_text_size"
+ android:singleLine="true"
android:duplicateParentState="true" />
<TextView
android:id="@+id/largeLabel"
@@ -41,6 +42,7 @@
android:layout_height="wrap_content"
android:visibility="invisible"
android:textSize="@dimen/design_bottom_navigation_active_text_size"
+ android:singleLine="true"
android:duplicateParentState="true" />
</android.support.design.internal.BaselineLayout>
</merge>
\ No newline at end of file
diff --git a/design/src/android/support/design/internal/BottomNavigationMenuView.java b/design/src/android/support/design/internal/BottomNavigationMenuView.java
index 158dda7..096bdd8 100644
--- a/design/src/android/support/design/internal/BottomNavigationMenuView.java
+++ b/design/src/android/support/design/internal/BottomNavigationMenuView.java
@@ -16,6 +16,8 @@
package android.support.design.internal;
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -32,8 +34,6 @@
import android.view.View;
import android.view.ViewGroup;
-import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
-
/**
* @hide For internal use only.
*/
@@ -55,6 +55,7 @@
private ColorStateList mItemIconTint;
private ColorStateList mItemTextColor;
private int mItemBackgroundRes;
+ private int[] mTempChildWidths;
private BottomNavigationPresenter mPresenter;
private MenuBuilder mMenu;
@@ -85,10 +86,12 @@
public void onClick(View v) {
final BottomNavigationItemView itemView = (BottomNavigationItemView) v;
final int itemPosition = itemView.getItemPosition();
- activateNewButton(itemPosition);
- mMenu.performItemAction(itemView.getItemData(), mPresenter, 0);
+ if (!mMenu.performItemAction(itemView.getItemData(), mPresenter, 0)) {
+ activateNewButton(itemPosition);
+ }
}
};
+ mTempChildWidths = new int[BottomNavigationMenu.MAX_ITEM_COUNT];
}
@Override
@@ -105,10 +108,8 @@
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int count = getChildCount();
- final int childState = 0;
final int heightSpec = MeasureSpec.makeMeasureSpec(mItemHeight, MeasureSpec.EXACTLY);
- final int[] childWidths = new int[count];
if (mShiftingMode) {
final int inactiveCount = count - 1;
final int activeMaxAvailable = width - inactiveCount * mInactiveItemMinWidth;
@@ -117,9 +118,9 @@
final int inactiveWidth = Math.min(inactiveMaxAvailable, mInactiveItemMaxWidth);
int extra = width - activeWidth - inactiveWidth * inactiveCount;
for (int i = 0; i < count; i++) {
- childWidths[i] = (i == mActiveButton) ? activeWidth : inactiveWidth;
+ mTempChildWidths[i] = (i == mActiveButton) ? activeWidth : inactiveWidth;
if (extra > 0) {
- childWidths[i]++;
+ mTempChildWidths[i]++;
extra--;
}
}
@@ -128,9 +129,9 @@
final int childWidth = Math.min(maxAvailable, mActiveItemMaxWidth);
int extra = width - childWidth * count;
for (int i = 0; i < count; i++) {
- childWidths[i] = childWidth;
+ mTempChildWidths[i] = childWidth;
if (extra > 0) {
- childWidths[i]++;
+ mTempChildWidths[i]++;
extra--;
}
}
@@ -142,7 +143,7 @@
if (child.getVisibility() == GONE) {
continue;
}
- child.measure(MeasureSpec.makeMeasureSpec(childWidths[i], MeasureSpec.EXACTLY),
+ child.measure(MeasureSpec.makeMeasureSpec(mTempChildWidths[i], MeasureSpec.EXACTLY),
heightSpec);
ViewGroup.LayoutParams params = child.getLayoutParams();
params.width = child.getMeasuredWidth();
@@ -150,9 +151,8 @@
}
setMeasuredDimension(
ViewCompat.resolveSizeAndState(totalWidth,
- MeasureSpec.makeMeasureSpec(totalWidth, MeasureSpec.EXACTLY), childState),
- ViewCompat.resolveSizeAndState(mItemHeight, heightSpec,
- childState << MEASURED_HEIGHT_STATE_SHIFT));
+ MeasureSpec.makeMeasureSpec(totalWidth, MeasureSpec.EXACTLY), 0),
+ ViewCompat.resolveSizeAndState(mItemHeight, heightSpec, 0));
}
@Override
@@ -180,19 +180,34 @@
return 0;
}
- public void setIconTintList(ColorStateList color) {
- mItemIconTint = color;
+ /**
+ * Set the tint which is applied to the menu items' icons.
+ *
+ * @param tint the tint to apply.
+ */
+ public void setIconTintList(ColorStateList tint) {
+ mItemIconTint = tint;
if (mButtons == null) return;
for (BottomNavigationItemView item : mButtons) {
- item.setIconTintList(color);
+ item.setIconTintList(tint);
}
}
+ /**
+ * Returns the tint which is applied to menu items' icons.
+ *
+ * @return The ColorStateList that is used to tint menu items' icons.
+ */
@Nullable
public ColorStateList getIconTintList() {
return mItemIconTint;
}
+ /**
+ * Set the text color to be used on menu items.
+ *
+ * @param color the ColorStateList used for menu items' text.
+ */
public void setItemTextColor(ColorStateList color) {
mItemTextColor = color;
if (mButtons == null) return;
@@ -201,10 +216,19 @@
}
}
+ /**
+ * Returns the text color used on menu items.
+ *
+ * @return the ColorStateList used for menu items' text.
+ */
public ColorStateList getItemTextColor() {
return mItemTextColor;
}
+ /**
+ * Sets the resource id to be used for item background.
+ * @param background the resource id of the background.
+ */
public void setItemBackgroundRes(int background) {
mItemBackgroundRes = background;
if (mButtons == null) return;
@@ -213,6 +237,11 @@
}
}
+ /**
+ * Returns the background resource of the menu items.
+ *
+ * @return the resource id of the background.
+ */
public int getItemBackgroundRes() {
return mItemBackgroundRes;
}
diff --git a/design/src/android/support/design/widget/BottomNavigationView.java b/design/src/android/support/design/widget/BottomNavigationView.java
index 476889f..8a8e0bd 100644
--- a/design/src/android/support/design/widget/BottomNavigationView.java
+++ b/design/src/android/support/design/widget/BottomNavigationView.java
@@ -56,14 +56,28 @@
* </p>
*
* <pre>
+ * layout resource file:
* <android.support.design.widget.BottomNavigationView
* xmlns:android="http://schemas.android.com/apk/res/android"
* xmlns:design="http://schema.android.com/apk/res/android.support.design"
* android:id="@+id/navigation"
- * android:layout_width="wrap_content"
- * android:layout_height="match_parent"
+ * android:layout_width="match_parent"
+ * android:layout_height="56dp"
* android:layout_gravity="start"
* design:menu="@menu/my_navigation_items" />
+ *
+ * res/menu/my_navigation_items.xml:
+ * <menu xmlns:android="http://schemas.android.com/apk/res/android">
+ * <item android:id="@+id/action_search"
+ * android:title="@string/menu_search"
+ * android:icon="@drawable/ic_search" />
+ * <item android:id="@+id/action_settings"
+ * android:title="@string/menu_settings"
+ * android:icon="@drawable/ic_add" />
+ * <item android:id="@+id/action_navigation"
+ * android:title="@string/menu_navigation"
+ * android:icon="@drawable/ic_action_navigation_menu" />
+ * </menu>
* </pre>
*/
public class BottomNavigationView extends FrameLayout {
@@ -138,7 +152,7 @@
mMenu.setCallback(new MenuBuilder.Callback() {
@Override
public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
- return mListener != null && mListener.onNavigationItemSelected(item);
+ return mListener != null && !mListener.onNavigationItemSelected(item);
}
@Override
@@ -210,7 +224,7 @@
}
/**
- * Returns the tint which is applied to menu items' icons.
+ * Returns the text color used on menu items.
*
* @see #setItemTextColor(ColorStateList)
*
@@ -265,7 +279,9 @@
*
* @param item The selected item
*
- * @return true to display the item as the selected item
+ * @return true to display the item as the selected item and false if the item should not
+ * be selected. Consider setting non-selectable items as disabled preemptively to
+ * make them appear non-interactive.
*/
boolean onNavigationItemSelected(@NonNull MenuItem item);
}
diff --git a/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java b/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java
index 98851b4..0ddbc6d 100644
--- a/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java
+++ b/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java
@@ -27,11 +27,15 @@
import static org.hamcrest.core.AllOf.allOf;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
import android.content.res.Resources;
import android.support.annotation.ColorInt;
@@ -95,22 +99,38 @@
mock(BottomNavigationView.OnNavigationItemSelectedListener.class);
mBottomNavigation.setOnNavigationItemSelectedListener(mockedListener);
- // Click one of our items
+ // Make the listener return true to allow selecting the item.
+ when(mockedListener.onNavigationItemSelected(any(MenuItem.class))).thenReturn(true);
onView(allOf(withText(mMenuStringContent.get(R.id.destination_profile)),
isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click());
- // And that our listener has been notified of the click
+ // Verify our listener has been notified of the click
verify(mockedListener, times(1)).onNavigationItemSelected(
mBottomNavigation.getMenu().findItem(R.id.destination_profile));
+ // Verify the item is now selected
+ assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_profile).isChecked());
+
+ // Make the listener return false to disallow selecting the item.
+ when(mockedListener.onNavigationItemSelected(any(MenuItem.class))).thenReturn(false);
+ onView(allOf(withText(mMenuStringContent.get(R.id.destination_people)),
+ isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click());
+ // Verify our listener has been notified of the click
+ verify(mockedListener, times(1)).onNavigationItemSelected(
+ mBottomNavigation.getMenu().findItem(R.id.destination_people));
+ // Verify the previous item is still selected
+ assertFalse(mBottomNavigation.getMenu().findItem(R.id.destination_people).isChecked());
+ assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_profile).isChecked());
// Set null listener to test that the next click is not going to notify the
- // previously set listener
+ // previously set listener and will allow selecting items.
mBottomNavigation.setOnNavigationItemSelectedListener(null);
// Click one of our items
- onView(allOf(withText(mMenuStringContent.get(R.id.destination_people)),
+ onView(allOf(withText(mMenuStringContent.get(R.id.destination_home)),
isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click());
// And that our previous listener has not been notified of the click
verifyNoMoreInteractions(mockedListener);
+ // Verify the correct item is now selected.
+ assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_home).isChecked());
}
@Test
diff --git a/samples/SupportDesignDemos/res/layout/design_bottom_navigation_view.xml b/samples/SupportDesignDemos/res/layout/design_bottom_navigation_view.xml
index 83e7314..c868430 100644
--- a/samples/SupportDesignDemos/res/layout/design_bottom_navigation_view.xml
+++ b/samples/SupportDesignDemos/res/layout/design_bottom_navigation_view.xml
@@ -14,46 +14,56 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<RelativeLayout
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <Button
- android:id="@+id/button_disable"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/bottomnavigation_disable"/>
+ <ScrollView android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginBottom="56dp">
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <Button
+ android:id="@+id/button_disable"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/bottomnavigation_disable"/>
+ <Button
+ android:id="@+id/button_add"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/bottomnavigation_add"
+ android:layout_below="@+id/button_disable"/>
- <Button
- android:id="@+id/button_add"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/bottomnavigation_add"
- android:layout_below="@+id/button_disable"/>
+ <Button
+ android:id="@+id/button_remove"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/bottomnavigation_remove"
+ android:layout_below="@+id/button_add"/>
- <Button
- android:id="@+id/button_remove"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/bottomnavigation_remove"
- android:layout_below="@+id/button_add"/>
+ <Button
+ android:id="@+id/button_tint"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/bottomnavigation_tint"
+ android:layout_below="@+id/button_remove"/>
- <Button
- android:id="@+id/button_tint"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/bottomnavigation_tint"
- android:layout_below="@+id/button_remove"/>
-
+ <TextView
+ android:id="@+id/selected_item"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/button_tint"/>
+ </RelativeLayout>
+ </ScrollView>
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_gravity="bottom"
android:background="#eee"
- android:layout_alignParentBottom="true"
app:menu="@menu/sample_bottom_menu"/>
-
-</RelativeLayout>
+</FrameLayout>
diff --git a/samples/SupportDesignDemos/res/menu/sample_bottom_menu.xml b/samples/SupportDesignDemos/res/menu/sample_bottom_menu.xml
index 4294f80..d6d4761 100644
--- a/samples/SupportDesignDemos/res/menu/sample_bottom_menu.xml
+++ b/samples/SupportDesignDemos/res/menu/sample_bottom_menu.xml
@@ -20,7 +20,7 @@
<item android:id="@+id/action_settings"
android:title="@string/menu_settings"
android:icon="@drawable/ic_add"/>
- <item android:id="@+id/action_navigation"
+ <item android:id="@+id/action_music"
android:title="@string/tab_text"
android:icon="@drawable/ic_action_navigation_menu"/>
</menu>
\ No newline at end of file
diff --git a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/BottomNavigationViewUsage.java b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/BottomNavigationViewUsage.java
index 72b50db..3442218 100644
--- a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/BottomNavigationViewUsage.java
+++ b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/BottomNavigationViewUsage.java
@@ -18,11 +18,13 @@
import android.content.res.ColorStateList;
import android.os.Bundle;
+import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
+import android.widget.TextView;
import com.example.android.support.design.R;
@@ -74,5 +76,26 @@
}
}
});
+ final TextView selectedItem = (TextView) findViewById(R.id.selected_item);
+ bottom.setOnNavigationItemSelectedListener(
+ new BottomNavigationView.OnNavigationItemSelectedListener() {
+ @Override
+ public boolean onNavigationItemSelected(@NonNull MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.action_search:
+ selectedItem.setText("Entering searching mode");
+ break;
+ case R.id.action_settings:
+ selectedItem.setText("Entering settings!?!");
+ break;
+ case R.id.action_music:
+ selectedItem.setText("Play some music");
+ break;
+ default:
+ selectedItem.setText("Selected " + item.getTitle());
+ }
+ return true;
+ }
+ });
}
}
diff --git a/v17/leanback/res/animator/lb_playback_now_bar1_animator.xml b/v17/leanback/res/animator/lb_playback_now_bar1_animator.xml
deleted file mode 100644
index 10be669..0000000
--- a/v17/leanback/res/animator/lb_playback_now_bar1_animator.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2016 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.
--->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
- android:duration="2320"
- android:repeatCount="infinite"
- android:interpolator="@android:anim/linear_interpolator">
- <propertyValuesHolder android:propertyName="scaleY" >
-
- <keyframe android:value="0.417" />
- <keyframe android:value="0.25" />
- <keyframe android:value="0.417" />
- <keyframe android:value="0.583" />
- <keyframe android:value="0.75" />
-
- <keyframe android:value="0.833" />
- <keyframe android:value="0.917" />
- <keyframe android:value="1.0" />
- <keyframe android:value="0.917" />
- <keyframe android:value="1.0" />
-
- <keyframe android:value="0.833" />
- <keyframe android:value="0.667" />
- <keyframe android:value="0.5" />
- <keyframe android:value="0.333" />
- <keyframe android:value="0.167" />
-
- <keyframe android:value="0.333" />
- <keyframe android:value="0.5" />
- <keyframe android:value="0.583" />
- <keyframe android:value="0.75" />
- <keyframe android:value="0.917" />
-
- <keyframe android:value="0.75" />
- <keyframe android:value="0.583" />
- <keyframe android:value="0.417" />
- <keyframe android:value="0.25" />
- <keyframe android:value="0.417" />
-
- <keyframe android:value="0.667" />
- <keyframe android:value="0.417" />
- <keyframe android:value="0.25" />
- <keyframe android:value="0.333" />
- <keyframe android:value="0.417" />
-
- </propertyValuesHolder>
-</objectAnimator>
\ No newline at end of file
diff --git a/v17/leanback/res/animator/lb_playback_now_bar2_animator.xml b/v17/leanback/res/animator/lb_playback_now_bar2_animator.xml
deleted file mode 100644
index 9b583b9..0000000
--- a/v17/leanback/res/animator/lb_playback_now_bar2_animator.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2016 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.
--->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
- android:duration="2080"
- android:repeatCount="infinite"
- android:interpolator="@android:anim/linear_interpolator">
- <propertyValuesHolder android:propertyName="scaleY" >
-
- <keyframe android:value="1.0" />
- <keyframe android:value="0.917" />
- <keyframe android:value="0.833" />
- <keyframe android:value="0.917" />
- <keyframe android:value="1.0" />
-
- <keyframe android:value="0.917" />
- <keyframe android:value="0.75" />
- <keyframe android:value="0.583" />
- <keyframe android:value="0.75" />
- <keyframe android:value="0.917" />
-
- <keyframe android:value="1.0" />
- <keyframe android:value="0.833" />
- <keyframe android:value="0.667" />
- <keyframe android:value="0.833" />
- <keyframe android:value="1.0" />
-
- <keyframe android:value="0.917" />
- <keyframe android:value="0.75" />
- <keyframe android:value="0.417" />
- <keyframe android:value="0.25" />
- <keyframe android:value="0.417" />
-
- <keyframe android:value="0.667" />
- <keyframe android:value="0.833" />
- <keyframe android:value="1.0" />
- <keyframe android:value="0.833" />
- <keyframe android:value="0.75" />
-
- <keyframe android:value="0.667" />
- <keyframe android:value="1.0" />
-
- </propertyValuesHolder>
-</objectAnimator>
\ No newline at end of file
diff --git a/v17/leanback/res/animator/lb_playback_now_bar3_animator.xml b/v17/leanback/res/animator/lb_playback_now_bar3_animator.xml
deleted file mode 100644
index c842100..0000000
--- a/v17/leanback/res/animator/lb_playback_now_bar3_animator.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2016 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.
--->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
- android:duration="2000"
- android:repeatCount="infinite"
- android:interpolator="@android:anim/linear_interpolator">
- <propertyValuesHolder android:propertyName="scaleY" >
-
- <keyframe android:value="0.667" />
- <keyframe android:value="0.75" />
- <keyframe android:value="0.833" />
- <keyframe android:value="1.0" />
- <keyframe android:value="0.917" />
-
- <keyframe android:value="0.75" />
- <keyframe android:value="0.583" />
- <keyframe android:value="0.417" />
- <keyframe android:value="0.583" />
- <keyframe android:value="0.667" />
-
- <keyframe android:value="0.75" />
- <keyframe android:value="1.0" />
- <keyframe android:value="0.917" />
- <keyframe android:value="1.0" />
- <keyframe android:value="0.75" />
-
- <keyframe android:value="0.583" />
- <keyframe android:value="0.75" />
- <keyframe android:value="0.917" />
- <keyframe android:value="1.0" />
- <keyframe android:value="0.833" />
-
- <keyframe android:value="0.667" />
- <keyframe android:value="0.75" />
- <keyframe android:value="0.583" />
- <keyframe android:value="0.417" />
- <keyframe android:value="0.25" />
-
- <keyframe android:value="0.667" />
-
- </propertyValuesHolder>
-</objectAnimator>
\ No newline at end of file
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/MediaNowPlayingView.java b/v17/leanback/src/android/support/v17/leanback/widget/MediaNowPlayingView.java
index cb2691c..901ff55 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/MediaNowPlayingView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/MediaNowPlayingView.java
@@ -13,19 +13,20 @@
*/
package android.support.v17.leanback.widget;
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
import android.animation.Animator;
-import android.animation.AnimatorInflater;
import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.support.annotation.RestrictTo;
+import android.support.v17.leanback.R;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.support.v17.leanback.R;
-
-import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
/**
* The view displaying 3 animated peak meters next to each other when a media item is playing.
@@ -40,6 +41,7 @@
private final ObjectAnimator mObjectAnimator1;
private final ObjectAnimator mObjectAnimator2;
private final ObjectAnimator mObjectAnimator3;
+ protected final LinearInterpolator mLinearInterpolator = new LinearInterpolator();
public MediaNowPlayingView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -57,17 +59,31 @@
setDropScale(mImage2);
setDropScale(mImage3);
- mObjectAnimator1 = (ObjectAnimator) AnimatorInflater.loadAnimator(context,
- R.animator.lb_playback_now_bar1_animator);
- mObjectAnimator1.setTarget(mImage1);
+ mObjectAnimator1 = ObjectAnimator.ofFloat(mImage1, "scaleY", 5f / 12f, 3f / 12f, 5f / 12f,
+ 7f / 12f, 9f / 12f, 10f / 12f, 11f / 12f, 12f / 12f, 11f / 12f, 12f / 12f,
+ 10f / 12f, 8f / 12f, 6f / 12f, 4f / 12f, 2f / 12f, 4f / 12f, 6f / 12f, 7f / 12f,
+ 9f / 12f, 11f / 12f, 9f / 12f, 7f / 12f, 5f / 12f, 3f / 12f, 5f / 12f, 8f / 12f,
+ 5f / 12f, 3f / 12f, 4f / 12f, 5f / 12f);
+ mObjectAnimator1.setRepeatCount(ValueAnimator.INFINITE);
+ mObjectAnimator1.setDuration(2320);
+ mObjectAnimator1.setInterpolator(mLinearInterpolator);
- mObjectAnimator2 = (ObjectAnimator) AnimatorInflater.loadAnimator(context,
- R.animator.lb_playback_now_bar2_animator);
- mObjectAnimator2.setTarget(mImage2);
+ mObjectAnimator2 = ObjectAnimator.ofFloat(mImage2, "scaleY", 12f / 12f, 11f / 12f,
+ 10f / 12f, 11f / 12f, 12f / 12f, 11f / 12f, 9f / 12f, 7f / 12f, 9f / 12f, 11f / 12f,
+ 12f / 12f, 10f / 12f, 8f / 12f, 10f / 12f, 12f / 12f, 11f / 12f, 9f / 12f, 5f / 12f,
+ 3f / 12f, 5f / 12f, 8f / 12f, 10f / 12f, 12f / 12f, 10f / 12f, 9f / 12f, 8f / 12f,
+ 12f / 12f);
+ mObjectAnimator2.setRepeatCount(ValueAnimator.INFINITE);
+ mObjectAnimator2.setDuration(2080);
+ mObjectAnimator2.setInterpolator(mLinearInterpolator);
- mObjectAnimator3 = (ObjectAnimator) AnimatorInflater.loadAnimator(context,
- R.animator.lb_playback_now_bar3_animator);
- mObjectAnimator3.setTarget(mImage3);
+ mObjectAnimator3 = ObjectAnimator.ofFloat(mImage3, "scaleY", 8f / 12f, 9f / 12f, 10f / 12f,
+ 12f / 12f, 11f / 12f, 9f / 12f, 7f / 12f, 5f / 12f, 7f / 12f, 8f / 12f, 9f / 12f,
+ 12f / 12f, 11f / 12f, 12f / 12f, 9f / 12f, 7f / 12f, 9f / 12f, 11f / 12f, 12f / 12f,
+ 10f / 12f, 8f / 12f, 9f / 12f, 7f / 12f, 5f / 12f, 3f / 12f, 8f / 12f);
+ mObjectAnimator3.setRepeatCount(ValueAnimator.INFINITE);
+ mObjectAnimator3.setDuration(2000);
+ mObjectAnimator3.setInterpolator(mLinearInterpolator);
}
static void setDropScale(View view) {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/MediaNowPlayingViewTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/MediaNowPlayingViewTest.java
new file mode 100644
index 0000000..dc6354c
--- /dev/null
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/MediaNowPlayingViewTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 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 android.support.v17.leanback.widget;
+
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+/**
+ * Testing MediaNowPlayingView widget
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+
+public class MediaNowPlayingViewTest {
+ private Context mContext;
+
+ @Before
+ public void setup() throws Exception {
+ mContext = InstrumentationRegistry.getTargetContext();
+ }
+
+ @Test
+ public void testViewCreation() {
+ new MediaNowPlayingView(mContext, null);
+ }
+}
diff --git a/v7/appcompat/tests/src/android/support/v7/app/AppCompatVectorDrawableIntegrationTest.java b/v7/appcompat/tests/src/android/support/v7/app/AppCompatVectorDrawableIntegrationTest.java
index b021ade..905521d 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/AppCompatVectorDrawableIntegrationTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/AppCompatVectorDrawableIntegrationTest.java
@@ -73,8 +73,9 @@
assertEquals("Left side should be white", Color.red(leftColor), 255);
assertEquals("Right side should be black", Color.red(rightColor), 0);
- if (Build.VERSION.SDK_INT >= 17) {
- // setLayoutDirection is only available after API 17.
+ if (Build.VERSION.SDK_INT >= 19) {
+ // setLayoutDirection is only available after API 17. However, it correctly set its
+ // drawable's layout direction until API 19.
view1.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
vectorDrawable.draw(mCanvas);
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
index 4eb81a1..46da1b8 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
@@ -2389,9 +2389,12 @@
// We only query the display/refresh rate once, since it's an expensive binder call
float refreshRate = 60.0f;
Display display = ViewCompat.getDisplay(this);
- if (display != null && display.getRefreshRate() >= 30.0f) {
- // break 60 fps assumption if data appears good
- refreshRate = display.getRefreshRate();
+ if (!isInEditMode() && display != null) {
+ float displayRefreshRate = display.getRefreshRate();
+ if (displayRefreshRate >= 30.0f) {
+ // break 60 fps assumption if data appears good
+ refreshRate = displayRefreshRate;
+ }
}
sFrameIntervalNanos = (long) (1000000000 / refreshRate);
}