Merge "Allow AppBarLayout to handle size changes" into lmp-mr1-ub-dev
diff --git a/design/api/current.txt b/design/api/current.txt
index 615ae54..217ba99 100644
--- a/design/api/current.txt
+++ b/design/api/current.txt
@@ -195,8 +195,10 @@
method public void setItemBackground(android.graphics.drawable.Drawable);
method public void setItemBackgroundResource(int);
method public void setItemIconTintList(android.content.res.ColorStateList);
+ method public void setItemTextAppearance(int);
method public void setItemTextColor(android.content.res.ColorStateList);
method public void setNavigationItemSelectedListener(android.support.design.widget.NavigationView.OnNavigationItemSelectedListener);
+ method public void setCheckedItem(int);
}
public static abstract interface NavigationView.OnNavigationItemSelectedListener {
@@ -336,6 +338,7 @@
method public void setError(java.lang.CharSequence);
method public void setErrorEnabled(boolean);
method public void setHint(java.lang.CharSequence);
+ method public void setTypeface(android.graphics.Typeface);
}
class ViewOffsetBehavior extends android.support.design.widget.CoordinatorLayout.Behavior {
diff --git a/design/base/android/support/design/widget/CircularBorderDrawable.java b/design/base/android/support/design/widget/CircularBorderDrawable.java
index f522277..ff57777 100644
--- a/design/base/android/support/design/widget/CircularBorderDrawable.java
+++ b/design/base/android/support/design/widget/CircularBorderDrawable.java
@@ -50,6 +50,8 @@
private int mBottomOuterStrokeColor;
private int mBottomInnerStrokeColor;
+ private int mTintColor;
+
private boolean mInvalidateShader = true;
public CircularBorderDrawable() {
@@ -113,6 +115,12 @@
invalidateSelf();
}
+ void setTintColor(int tintColor) {
+ mTintColor = tintColor;
+ mInvalidateShader = true;
+ invalidateSelf();
+ }
+
@Override
public void setColorFilter(ColorFilter colorFilter) {
mPaint.setColorFilter(colorFilter);
@@ -140,12 +148,14 @@
final float borderRatio = mBorderWidth / rect.height();
final int[] colors = new int[6];
- colors[0] = mTopOuterStrokeColor;
- colors[1] = mTopInnerStrokeColor;
- colors[2] = ColorUtils.setAlphaComponent(mTopInnerStrokeColor, 0);
- colors[3] = ColorUtils.setAlphaComponent(mBottomInnerStrokeColor, 0);
- colors[4] = mBottomInnerStrokeColor;
- colors[5] = mBottomOuterStrokeColor;
+ colors[0] = ColorUtils.compositeColors(mTopOuterStrokeColor, mTintColor);
+ colors[1] = ColorUtils.compositeColors(mTopInnerStrokeColor, mTintColor);
+ colors[2] = ColorUtils.compositeColors(
+ ColorUtils.setAlphaComponent(mTopInnerStrokeColor, 0), mTintColor);
+ colors[3] = ColorUtils.compositeColors(
+ ColorUtils.setAlphaComponent(mBottomInnerStrokeColor, 0), mTintColor);
+ colors[4] = ColorUtils.compositeColors(mBottomInnerStrokeColor, mTintColor);
+ colors[5] = ColorUtils.compositeColors(mBottomOuterStrokeColor, mTintColor);
final float[] positions = new float[6];
positions[0] = 0f;
diff --git a/design/base/android/support/design/widget/FloatingActionButtonImpl.java b/design/base/android/support/design/widget/FloatingActionButtonImpl.java
index c17aea8..6c154d4 100644
--- a/design/base/android/support/design/widget/FloatingActionButtonImpl.java
+++ b/design/base/android/support/design/widget/FloatingActionButtonImpl.java
@@ -66,11 +66,8 @@
resources.getColor(R.color.fab_stroke_end_inner_color),
resources.getColor(R.color.fab_stroke_end_outer_color));
borderDrawable.setBorderWidth(borderWidth);
-
- Drawable d = DrawableCompat.wrap(borderDrawable);
- DrawableCompat.setTintList(d, backgroundTint);
- DrawableCompat.setTintMode(d, PorterDuff.Mode.DST_OVER);
- return d;
+ borderDrawable.setTintColor(backgroundTint.getDefaultColor());
+ return borderDrawable;
}
CircularBorderDrawable newCircularDrawable() {
diff --git a/design/res/values/attrs.xml b/design/res/values/attrs.xml
index e4c1bf0..9702497 100644
--- a/design/res/values/attrs.xml
+++ b/design/res/values/attrs.xml
@@ -51,6 +51,7 @@
<attr name="itemIconTint" format="color"/>
<attr name="itemTextColor" format="color"/>
<attr name="itemBackground" format="reference"/>
+ <attr name="itemTextAppearance" format="reference"/>
<!-- Layout resource to inflate as the header -->
<attr name="headerLayout" format="reference"/>
</declare-styleable>
diff --git a/design/res/values/styles.xml b/design/res/values/styles.xml
index 4e03029..067846c 100644
--- a/design/res/values/styles.xml
+++ b/design/res/values/styles.xml
@@ -23,7 +23,7 @@
<item name="elevation">@dimen/fab_elevation</item>
<item name="pressedTranslationZ">@dimen/fab_translation_z_pressed</item>
<item name="rippleColor">?attr/colorControlHighlight</item>
- <item name="borderWidth">0dp</item>
+ <item name="borderWidth">@dimen/fab_border_width</item>
</style>
<style name="Widget.Design.ScrimInsetsFrameLayout" parent="">
diff --git a/design/src/android/support/design/internal/NavigationMenuPresenter.java b/design/src/android/support/design/internal/NavigationMenuPresenter.java
index 55a7594..f19b78a 100644
--- a/design/src/android/support/design/internal/NavigationMenuPresenter.java
+++ b/design/src/android/support/design/internal/NavigationMenuPresenter.java
@@ -26,6 +26,7 @@
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.annotation.StyleRes;
import android.support.design.R;
import android.support.v7.internal.view.menu.MenuBuilder;
import android.support.v7.internal.view.menu.MenuItemImpl;
@@ -63,6 +64,8 @@
private NavigationMenuAdapter mAdapter;
private LayoutInflater mLayoutInflater;
+ private int mTextAppearance;
+ private boolean mTextAppearanceSet;
private ColorStateList mTextColor;
private ColorStateList mIconTintList;
private Drawable mItemBackground;
@@ -184,10 +187,21 @@
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int positionInAdapter = position - mMenuView.getHeaderViewsCount();
if (positionInAdapter >= 0) {
- mMenu.performItemAction(mAdapter.getItem(positionInAdapter).getMenuItem(), this, 0);
+ setUpdateSuspended(true);
+ MenuItemImpl item = mAdapter.getItem(positionInAdapter).getMenuItem();
+ if (item != null && item.isCheckable()) {
+ setCheckedItem(item);
+ }
+ mMenu.performItemAction(item, this, 0);
+ setUpdateSuspended(false);
+ updateMenuView(false);
}
}
+ public void setCheckedItem(MenuItemImpl item) {
+ mAdapter.setCheckedItem(item);
+ }
+
public View inflateHeaderView(@LayoutRes int res) {
View view = mLayoutInflater.inflate(res, mHeader, false);
addHeaderView(view);
@@ -214,6 +228,7 @@
public void setItemIconTintList(@Nullable ColorStateList tint) {
mIconTintList = tint;
+ updateMenuView(false);
}
@Nullable
@@ -223,6 +238,13 @@
public void setItemTextColor(@Nullable ColorStateList textColor) {
mTextColor = textColor;
+ updateMenuView(false);
+ }
+
+ public void setItemTextAppearance(@StyleRes int resId) {
+ mTextAppearance = resId;
+ mTextAppearanceSet = true;
+ updateMenuView(false);
}
public Drawable getItemBackground() {
@@ -233,15 +255,22 @@
mItemBackground = itemBackground;
}
+ public void setUpdateSuspended(boolean updateSuspended) {
+ if (mAdapter != null) {
+ mAdapter.setUpdateSuspended(updateSuspended);
+ }
+ }
+
private class NavigationMenuAdapter extends BaseAdapter {
- private static final String STATE_CHECKED_ITEMS = "android:menu:checked";
+ private static final String STATE_CHECKED_ITEM = "android:menu:checked";
private static final int VIEW_TYPE_NORMAL = 0;
private static final int VIEW_TYPE_SUBHEADER = 1;
private static final int VIEW_TYPE_SEPARATOR = 2;
private final ArrayList<NavigationMenuItem> mItems = new ArrayList<>();
+ private MenuItemImpl mCheckedItem;
private ColorDrawable mTransparentIcon;
private boolean mUpdateSuspended;
@@ -293,7 +322,12 @@
}
NavigationMenuItemView itemView = (NavigationMenuItemView) convertView;
itemView.setIconTintList(mIconTintList);
- itemView.setTextColor(mTextColor);
+ if (mTextAppearanceSet) {
+ itemView.setTextAppearance(itemView.getContext(), mTextAppearance);
+ }
+ if (mTextColor != null) {
+ itemView.setTextColor(mTextColor);
+ }
itemView.setBackgroundDrawable(mItemBackground);
itemView.initialize(item.getMenuItem(), 0);
break;
@@ -347,6 +381,12 @@
boolean currentGroupHasIcon = false;
for (int i = 0, totalSize = mMenu.getVisibleItems().size(); i < totalSize; i++) {
MenuItemImpl item = mMenu.getVisibleItems().get(i);
+ if (item.isChecked()) {
+ setCheckedItem(item);
+ }
+ if (item.isCheckable()) {
+ item.setExclusiveCheckable(false);
+ }
if (item.hasSubMenu()) {
SubMenu subMenu = item.getSubMenu();
if (subMenu.hasVisibleItems()) {
@@ -357,12 +397,18 @@
boolean subMenuHasIcon = false;
int subMenuStart = mItems.size();
for (int j = 0, size = subMenu.size(); j < size; j++) {
- MenuItem subMenuItem = subMenu.getItem(j);
+ MenuItemImpl subMenuItem = (MenuItemImpl) subMenu.getItem(j);
if (subMenuItem.isVisible()) {
if (!subMenuHasIcon && subMenuItem.getIcon() != null) {
subMenuHasIcon = true;
}
- mItems.add(NavigationMenuItem.of((MenuItemImpl) subMenuItem));
+ if (subMenuItem.isCheckable()) {
+ subMenuItem.setExclusiveCheckable(false);
+ }
+ if (item.isChecked()) {
+ setCheckedItem(item);
+ }
+ mItems.add(NavigationMenuItem.of(subMenuItem));
}
}
if (subMenuHasIcon) {
@@ -404,27 +450,32 @@
}
}
+ public void setCheckedItem(MenuItemImpl checkedItem) {
+ if (mCheckedItem == checkedItem || !checkedItem.isCheckable()) {
+ return;
+ }
+ if (mCheckedItem != null) {
+ mCheckedItem.setChecked(false);
+ }
+ mCheckedItem = checkedItem;
+ checkedItem.setChecked(true);
+ }
+
public Bundle createInstanceState() {
Bundle state = new Bundle();
- ArrayList<Integer> checkedItems = new ArrayList<>();
- for (NavigationMenuItem item : mItems) {
- MenuItemImpl menuItem = item.getMenuItem();
- if (menuItem != null && menuItem.isChecked()) {
- checkedItems.add(menuItem.getItemId());
- }
- }
- state.putIntegerArrayList(STATE_CHECKED_ITEMS, checkedItems);
+ state.putInt(STATE_CHECKED_ITEM, mCheckedItem.getItemId());
return state;
}
public void restoreInstanceState(Bundle state) {
- ArrayList<Integer> checkedItems = state.getIntegerArrayList(STATE_CHECKED_ITEMS);
- if (checkedItems != null) {
+ int checkedItem = state.getInt(STATE_CHECKED_ITEM, 0);
+ if (checkedItem != 0) {
mUpdateSuspended = true;
for (NavigationMenuItem item : mItems) {
MenuItemImpl menuItem = item.getMenuItem();
- if (menuItem != null && checkedItems.contains(menuItem.getItemId())) {
- menuItem.setChecked(true);
+ if (menuItem != null && menuItem.getItemId() == checkedItem) {
+ setCheckedItem(menuItem);
+ break;
}
}
mUpdateSuspended = false;
@@ -432,6 +483,10 @@
}
}
+ public void setUpdateSuspended(boolean updateSuspended) {
+ mUpdateSuspended = updateSuspended;
+ }
+
}
/**
diff --git a/design/src/android/support/design/widget/CollapsingTextHelper.java b/design/src/android/support/design/widget/CollapsingTextHelper.java
index 437e2d1..636770e 100644
--- a/design/src/android/support/design/widget/CollapsingTextHelper.java
+++ b/design/src/android/support/design/widget/CollapsingTextHelper.java
@@ -22,6 +22,7 @@
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
+import android.graphics.Typeface;
import android.os.Build;
import android.support.design.R;
import android.support.v4.text.TextDirectionHeuristicsCompat;
@@ -136,12 +137,10 @@
void setExpandedBounds(int left, int top, int right, int bottom) {
mExpandedBounds.set(left, top, right, bottom);
- recalculate();
}
void setCollapsedBounds(int left, int top, int right, int bottom) {
mCollapsedBounds.set(left, top, right, bottom);
- recalculate();
}
void setExpandedTextVerticalGravity(int gravity) {
@@ -190,6 +189,20 @@
recalculate();
}
+ void setTypeface(Typeface typeface) {
+ if (typeface == null) {
+ typeface = Typeface.DEFAULT;
+ }
+ if (mTextPaint.getTypeface() != typeface) {
+ mTextPaint.setTypeface(typeface);
+ recalculate();
+ }
+ }
+
+ Typeface getTypeface() {
+ return mTextPaint.getTypeface();
+ }
+
/**
* Set the value indicating the current scroll value. This decides how much of the
* background will be displayed, as well as the title metrics/positioning.
@@ -425,8 +438,8 @@
}
}
- private void recalculate() {
- if (ViewCompat.isLaidOut(mView)) {
+ public void recalculate() {
+ if (mView.getHeight() > 0 && mView.getWidth() > 0) {
// If we've already been laid out, calculate everything now otherwise we'll wait
// until a layout
calculateBaselines();
@@ -442,6 +455,7 @@
void setText(CharSequence text) {
if (text == null || !text.equals(mText)) {
mText = text;
+ mTextToDraw = null;
clearTexture();
recalculate();
}
@@ -458,10 +472,6 @@
}
}
- public void onLayout(boolean changed, int left, int top, int right, int bottom) {
- recalculate();
- }
-
/**
* Returns true if {@code value} is 'close' to it's closest decimal value. Close is currently
* defined as it's difference being < 0.001.
diff --git a/design/src/android/support/design/widget/CollapsingToolbarLayout.java b/design/src/android/support/design/widget/CollapsingToolbarLayout.java
index 474a0a8..b2b55f7 100644
--- a/design/src/android/support/design/widget/CollapsingToolbarLayout.java
+++ b/design/src/android/support/design/widget/CollapsingToolbarLayout.java
@@ -332,9 +332,6 @@
getViewOffsetHelper(child).onViewLayout();
}
- // Now let the collapsing text helper update itself
- mCollapsingTextHelper.onLayout(changed, left, top, right, bottom);
-
ensureToolbar();
// Update the collapsed bounds by getting it's transformed bounds
@@ -346,6 +343,8 @@
mCollapsingTextHelper.setExpandedBounds(left + mExpandedMarginLeft,
mTmpRect.bottom + mExpandedMarginTop, right - mExpandedMarginRight,
bottom - mExpandedMarginBottom);
+
+ mCollapsingTextHelper.recalculate();
}
// Finally, set our minimum height to enable proper AppBarLayout collapsing
diff --git a/design/src/android/support/design/widget/CoordinatorLayout.java b/design/src/android/support/design/widget/CoordinatorLayout.java
index e23ba02..e2081b7 100644
--- a/design/src/android/support/design/widget/CoordinatorLayout.java
+++ b/design/src/android/support/design/widget/CoordinatorLayout.java
@@ -32,6 +32,7 @@
import android.support.design.R;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.GravityCompat;
+import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.NestedScrollingParent;
import android.support.v4.view.NestedScrollingParentHelper;
import android.support.v4.view.ViewCompat;
@@ -314,7 +315,7 @@
MotionEvent cancelEvent = null;
- final int action = ev.getActionMasked();
+ final int action = MotionEventCompat.getActionMasked(ev);
final List<View> topmostChildList = mTempList1;
getTopSortedChildren(topmostChildList);
@@ -366,7 +367,7 @@
public boolean onInterceptTouchEvent(MotionEvent ev) {
MotionEvent cancelEvent = null;
- final int action = ev.getActionMasked();
+ final int action = MotionEventCompat.getActionMasked(ev);
// Make sure we reset in case we had missed a previous important event.
if (action == MotionEvent.ACTION_DOWN) {
@@ -392,7 +393,7 @@
boolean cancelSuper = false;
MotionEvent cancelEvent = null;
- final int action = ev.getActionMasked();
+ final int action = MotionEventCompat.getActionMasked(ev);
if (mBehaviorTouchView != null || (cancelSuper = performIntercept(ev))) {
// Safe since performIntercept guarantees that
diff --git a/design/src/android/support/design/widget/NavigationView.java b/design/src/android/support/design/widget/NavigationView.java
index 02dfa3c..3e83863 100644
--- a/design/src/android/support/design/widget/NavigationView.java
+++ b/design/src/android/support/design/widget/NavigationView.java
@@ -24,9 +24,11 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.DrawableRes;
+import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.annotation.StyleRes;
import android.support.design.R;
import android.support.design.internal.NavigationMenuPresenter;
import android.support.design.internal.ScrimInsetsFrameLayout;
@@ -34,6 +36,7 @@
import android.support.v4.view.ViewCompat;
import android.support.v7.internal.view.SupportMenuInflater;
import android.support.v7.internal.view.menu.MenuBuilder;
+import android.support.v7.internal.view.menu.MenuItemImpl;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Menu;
@@ -117,10 +120,20 @@
itemIconTint = createDefaultColorStateList(android.R.attr.textColorSecondary);
}
- final ColorStateList itemTextColor;
+ boolean textAppearanceSet = false;
+ int textAppearance = 0;
+ if (a.hasValue(R.styleable.NavigationView_itemTextAppearance)) {
+ textAppearance = a.getResourceId(R.styleable.NavigationView_itemTextAppearance, 0);
+ textAppearanceSet = true;
+ }
+
+ ColorStateList itemTextColor = null;
if (a.hasValue(R.styleable.NavigationView_itemTextColor)) {
itemTextColor = a.getColorStateList(R.styleable.NavigationView_itemTextColor);
- } else {
+ }
+
+ if (!textAppearanceSet && itemTextColor == null) {
+ // If there isn't a text appearance set, we'll use a default text color
itemTextColor = createDefaultColorStateList(android.R.attr.textColorPrimary);
}
@@ -143,6 +156,9 @@
mPresenter.setId(PRESENTER_NAVIGATION_VIEW_ID);
mPresenter.initForMenu(context, mMenu);
mPresenter.setItemIconTintList(itemIconTint);
+ if (textAppearanceSet) {
+ mPresenter.setItemTextAppearance(textAppearance);
+ }
mPresenter.setItemTextColor(itemTextColor);
mPresenter.setItemBackground(itemBackground);
mMenu.addMenuPresenter(mPresenter);
@@ -207,7 +223,14 @@
* @param resId ID of a menu resource to inflate
*/
public void inflateMenu(int resId) {
+ if (mPresenter != null) {
+ mPresenter.setUpdateSuspended(true);
+ }
getMenuInflater().inflate(resId, mMenu);
+ if (mPresenter != null) {
+ mPresenter.setUpdateSuspended(false);
+ mPresenter.updateMenuView(false);
+ }
}
/**
@@ -323,6 +346,27 @@
mPresenter.setItemBackground(itemBackground);
}
+ /**
+ * Sets the currently checked item in this navigation menu.
+ *
+ * @param id The item ID of the currently checked item.
+ */
+ public void setCheckedItem(@IdRes int id) {
+ MenuItem item = mMenu.findItem(id);
+ if (item != null) {
+ mPresenter.setCheckedItem((MenuItemImpl) item);
+ }
+ }
+
+ /**
+ * Set the text appearance of the menu items to a given resource.
+ *
+ * @attr ref R.styleable#NavigationView_itemTextAppearance
+ */
+ public void setItemTextAppearance(@StyleRes int resId) {
+ mPresenter.setItemTextAppearance(resId);
+ }
+
private MenuInflater getMenuInflater() {
if (mMenuInflater == null) {
mMenuInflater = new SupportMenuInflater(getContext());
diff --git a/design/src/android/support/design/widget/TextInputLayout.java b/design/src/android/support/design/widget/TextInputLayout.java
index 6282146..884e538 100644
--- a/design/src/android/support/design/widget/TextInputLayout.java
+++ b/design/src/android/support/design/widget/TextInputLayout.java
@@ -22,6 +22,7 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
+import android.graphics.Typeface;
import android.os.Handler;
import android.os.Message;
import android.support.design.R;
@@ -49,6 +50,24 @@
*
* Also supports showing an error via {@link #setErrorEnabled(boolean)} and
* {@link #setError(CharSequence)}.
+ *
+ * <p>Please note: this class sets a {@link android.view.View.OnFocusChangeListener} on the wrapped
+ * {@link EditText}. If you need to set your own listener, then you should wrap the existing one
+ * and forward the call like so:
+ * <pre>
+ * TextInputLayout inputLayout = ...;
+ * EditText editText = inputLayout.getEditText();
+ * final OnFocusChangeListener existing = editText.getOnFocusChangeListener();
+ *
+ * editText.setOnFocusChangeListener(new OnFocusChangeListener() {
+ * public void onFocusChange(View view, boolean focused) {
+ * existing.onFocusChange(view, focused);
+ *
+ * // Your custom logic
+ * }
+ * });
+ * </pre>
+ * </p>
*/
public class TextInputLayout extends LinearLayout {
@@ -144,6 +163,15 @@
}
}
+ /**
+ * Set the typeface to use for the both the expanded and floating hint.
+ *
+ * @param typeface typeface to use, or {@code null} to use the default.
+ */
+ public void setTypeface(Typeface typeface) {
+ mCollapsingTextHelper.setTypeface(typeface);
+ }
+
private LayoutParams setEditText(EditText editText, ViewGroup.LayoutParams lp) {
// If we already have an EditText, throw an exception
if (mEditText != null) {
@@ -151,7 +179,8 @@
}
mEditText = editText;
- // Use the EditText's text size for our expanded text
+ // Use the EditText's typeface, and it's text size for our expanded text
+ mCollapsingTextHelper.setTypeface(mEditText.getTypeface());
mCollapsingTextHelper.setExpandedTextSize(mEditText.getTextSize());
// Add a TextWatcher so that we know when the text input has changed
@@ -199,6 +228,7 @@
// to the EditText so make room for the label
LayoutParams newLp = new LayoutParams(lp);
Paint paint = new Paint();
+ paint.setTypeface(mCollapsingTextHelper.getTypeface());
paint.setTextSize(mCollapsingTextHelper.getExpandedTextSize());
newLp.topMargin = (int) -paint.ascent();
@@ -323,8 +353,6 @@
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
- mCollapsingTextHelper.onLayout(changed, left, top, right, bottom);
-
if (mEditText != null) {
final int l = mEditText.getLeft() + mEditText.getCompoundPaddingLeft();
final int r = mEditText.getRight() - mEditText.getCompoundPaddingRight();
@@ -337,6 +365,8 @@
// EditText's editable area
mCollapsingTextHelper.setCollapsedBounds(l, getPaddingTop(),
r, bottom - top - getPaddingBottom());
+
+ mCollapsingTextHelper.recalculate();
}
}
@@ -370,7 +400,6 @@
} else if (mAnimator.isRunning()) {
mAnimator.cancel();
}
-
mAnimator.setFloatValues(mCollapsingTextHelper.getExpansionFraction(), target);
mAnimator.start();
}
diff --git a/v4/api21/android/support/v4/graphics/drawable/DrawableCompatLollipop.java b/v4/api21/android/support/v4/graphics/drawable/DrawableCompatLollipop.java
index e5388b9..93990b4 100644
--- a/v4/api21/android/support/v4/graphics/drawable/DrawableCompatLollipop.java
+++ b/v4/api21/android/support/v4/graphics/drawable/DrawableCompatLollipop.java
@@ -19,6 +19,7 @@
import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.DrawableContainer;
import android.graphics.drawable.GradientDrawable;
/**
@@ -69,9 +70,10 @@
}
public static Drawable wrapForTinting(Drawable drawable) {
- if (drawable instanceof GradientDrawable) {
+ if (drawable instanceof GradientDrawable || drawable instanceof DrawableContainer) {
// GradientDrawable on Lollipop does not support tinting, so we'll use our compatible
- // functionality instead
+ // functionality instead. We also do the same for DrawableContainers since they may
+ // contain GradientDrawable instances.
return new DrawableWrapperLollipop(drawable);
}
return drawable;
diff --git a/v7/appcompat/res/values-v11/styles_base_text.xml b/v7/appcompat/res/values-v11/styles_base_text.xml
index 4cf4966..4227794 100644
--- a/v7/appcompat/res/values-v11/styles_base_text.xml
+++ b/v7/appcompat/res/values-v11/styles_base_text.xml
@@ -25,7 +25,7 @@
</style>
<style name="Base.TextAppearance.AppCompat.Subhead.Inverse">
- <item name="android:textColor">?android:attr/textColorSecondaryInverse</item>
+ <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
<item name="android:textColorHint">?android:attr/textColorHintInverse</item>
<item name="android:textColorHighlight">?android:attr/textColorHighlightInverse</item>
<item name="android:textColorLink">?android:attr/textColorLinkInverse</item>
diff --git a/v7/appcompat/res/values/styles_base_text.xml b/v7/appcompat/res/values/styles_base_text.xml
index 78e119c..3a2799a 100644
--- a/v7/appcompat/res/values/styles_base_text.xml
+++ b/v7/appcompat/res/values/styles_base_text.xml
@@ -66,7 +66,7 @@
</style>
<style name="Base.TextAppearance.AppCompat.Subhead.Inverse">
- <item name="android:textColor">?android:attr/textColorSecondaryInverse</item>
+ <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
<item name="android:textColorHint">?android:attr/textColorHintInverse</item>
</style>
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java
index f379071..eb58dc5 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java
@@ -17,14 +17,12 @@
package android.support.v7.app;
import android.app.Activity;
-import android.app.Dialog;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
-import android.os.Build;
import android.os.Bundle;
+import android.support.v4.view.WindowCompat;
import android.support.v7.appcompat.R;
-import android.support.v7.internal.app.WindowDecorActionBar;
import android.support.v7.internal.view.SupportMenuInflater;
import android.support.v7.internal.view.WindowCallbackWrapper;
import android.support.v7.internal.view.menu.MenuBuilder;
@@ -43,7 +41,7 @@
final Window.Callback mOriginalWindowCallback;
final AppCompatCallback mAppCompatCallback;
- private ActionBar mActionBar;
+ ActionBar mActionBar;
private MenuInflater mMenuInflater;
// true if this activity has an action bar.
@@ -75,7 +73,7 @@
mWindow.setCallback(wrapWindowCallback(mOriginalWindowCallback));
}
- abstract ActionBar createSupportActionBar();
+ abstract void initWindowDecorActionBar();
Window.Callback wrapWindowCallback(Window.Callback callback) {
return new AppCompatWindowCallbackBase(callback);
@@ -85,15 +83,7 @@
public ActionBar getSupportActionBar() {
// The Action Bar should be lazily created as hasActionBar
// could change after onCreate
- if (mHasActionBar) {
- if (mActionBar == null) {
- mActionBar = createSupportActionBar();
- }
- } else {
- if (mActionBar instanceof WindowDecorActionBar) {
- mActionBar = null;
- }
- }
+ initWindowDecorActionBar();
return mActionBar;
}
@@ -123,17 +113,19 @@
"You need to use a Theme.AppCompat theme (or descendant) with this activity.");
}
- if (a.getBoolean(R.styleable.Theme_windowActionBar, false)) {
- mHasActionBar = true;
+ if (a.getBoolean(R.styleable.Theme_windowNoTitle, false)) {
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ } else if (a.getBoolean(R.styleable.Theme_windowActionBar, false)) {
+ // Don't allow an action bar if there is no title.
+ requestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
}
if (a.getBoolean(R.styleable.Theme_windowActionBarOverlay, false)) {
- mOverlayActionBar = true;
+ requestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY);
}
if (a.getBoolean(R.styleable.Theme_windowActionModeOverlay, false)) {
- mOverlayActionMode = true;
+ requestWindowFeature(WindowCompat.FEATURE_ACTION_MODE_OVERLAY);
}
mIsFloating = a.getBoolean(R.styleable.Theme_android_windowIsFloating, false);
- mWindowNoTitle = a.getBoolean(R.styleable.Theme_windowNoTitle, false);
a.recycle();
}
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV7.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV7.java
index 1c08a40..abb665f 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV7.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV7.java
@@ -167,18 +167,22 @@
}
@Override
- public ActionBar createSupportActionBar() {
+ public void initWindowDecorActionBar() {
ensureSubDecor();
- ActionBar ab = null;
+
+ if (!mHasActionBar || mActionBar != null) {
+ return;
+ }
+
if (mOriginalWindowCallback instanceof Activity) {
- ab = new WindowDecorActionBar((Activity) mOriginalWindowCallback, mOverlayActionBar);
+ mActionBar = new WindowDecorActionBar((Activity) mOriginalWindowCallback,
+ mOverlayActionBar);
} else if (mOriginalWindowCallback instanceof Dialog) {
- ab = new WindowDecorActionBar((Dialog) mOriginalWindowCallback);
+ mActionBar = new WindowDecorActionBar((Dialog) mOriginalWindowCallback);
}
- if (ab != null) {
- ab.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
+ if (mActionBar != null) {
+ mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
}
- return ab;
}
@Override
@@ -460,6 +464,14 @@
@Override
public boolean requestWindowFeature(int featureId) {
+ if (mWindowNoTitle && featureId == FEATURE_ACTION_BAR) {
+ return false; // Ignore. No title dominates.
+ }
+ if (mHasActionBar && featureId == Window.FEATURE_NO_TITLE) {
+ // Remove the action bar feature if we have no title. No title dominates.
+ mHasActionBar = false;
+ }
+
switch (featureId) {
case FEATURE_ACTION_BAR:
throwFeatureRequestIfSubDecorInstalled();
diff --git a/v7/appcompat/src/android/support/v7/internal/app/ToolbarActionBar.java b/v7/appcompat/src/android/support/v7/internal/app/ToolbarActionBar.java
index 9653f42..46bebe6 100644
--- a/v7/appcompat/src/android/support/v7/internal/app/ToolbarActionBar.java
+++ b/v7/appcompat/src/android/support/v7/internal/app/ToolbarActionBar.java
@@ -513,6 +513,12 @@
final Resources.Theme widgetTheme = context.getResources().newTheme();
widgetTheme.setTo(context.getTheme());
+ // First apply the actionBarPopupTheme
+ widgetTheme.resolveAttribute(R.attr.actionBarPopupTheme, outValue, true);
+ if (outValue.resourceId != 0) {
+ widgetTheme.applyStyle(outValue.resourceId, true);
+ }
+
// Apply the panelMenuListTheme
widgetTheme.resolveAttribute(R.attr.panelMenuListTheme, outValue, true);
if (outValue.resourceId != 0) {
diff --git a/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java b/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java
index 9c53920..6aa55d7 100644
--- a/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java
+++ b/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java
@@ -140,7 +140,7 @@
private Layout mOnLayout;
private Layout mOffLayout;
private TransformationMethod mSwitchTransformationMethod;
- private Animation mPositionAnimator;
+ private ThumbAnimation mPositionAnimator;
@SuppressWarnings("hiding")
private final Rect mTempRect = new Rect();
@@ -748,16 +748,7 @@
}
private void animateThumbToCheckedState(boolean newCheckedState) {
- final float startPosition = mThumbPosition;
- final float targetPosition = newCheckedState ? 1 : 0;
- final float diff = targetPosition - startPosition;
-
- mPositionAnimator = new Animation() {
- @Override
- protected void applyTransformation(float interpolatedTime, Transformation t) {
- setThumbPosition(startPosition + (diff * interpolatedTime));
- }
- };
+ mPositionAnimator = new ThumbAnimation(mThumbPosition, newCheckedState ? 1 : 0);
mPositionAnimator.setDuration(THUMB_ANIMATION_DURATION);
startAnimation(mPositionAnimator);
}
@@ -1111,6 +1102,8 @@
if (mPositionAnimator != null && !mPositionAnimator.hasEnded()) {
clearAnimation();
+ // Manually set our thumb position to the end state
+ setThumbPosition(mPositionAnimator.mEndPosition);
mPositionAnimator = null;
}
}
@@ -1148,4 +1141,21 @@
private static float constrain(float amount, float low, float high) {
return amount < low ? low : (amount > high ? high : amount);
}
+
+ private class ThumbAnimation extends Animation {
+ final float mStartPosition;
+ final float mEndPosition;
+ final float mDiff;
+
+ private ThumbAnimation(float startPosition, float endPosition) {
+ mStartPosition = startPosition;
+ mEndPosition = endPosition;
+ mDiff = endPosition - startPosition;
+ }
+
+ @Override
+ protected void applyTransformation(float interpolatedTime, Transformation t) {
+ setThumbPosition(mStartPosition + (mDiff * interpolatedTime));
+ }
+ }
}
\ No newline at end of file