Merge "Fix visual styling for Material Spinner background"

This commit is contained in:
Alan Viverette
2015-04-22 20:41:29 +00:00
committed by Android (Google) Code Review
7 changed files with 346 additions and 37 deletions

View File

@@ -12412,7 +12412,9 @@ package android.graphics.drawable {
method public void draw(android.graphics.Canvas);
method public android.graphics.drawable.Drawable findDrawableByLayerId(int);
method public int findIndexByLayerId(int);
method public int getBottomPadding();
method public android.graphics.drawable.Drawable getDrawable(int);
method public int getEndPadding();
method public int getId(int);
method public int getLayerGravity(int);
method public int getLayerHeight(int);
@@ -12423,9 +12425,13 @@ package android.graphics.drawable {
method public int getLayerInsetStart(int);
method public int getLayerInsetTop(int);
method public int getLayerWidth(int);
method public int getLeftPadding();
method public int getNumberOfLayers();
method public int getOpacity();
method public int getPaddingMode();
method public int getRightPadding();
method public int getStartPadding();
method public int getTopPadding();
method public void invalidateDrawable(android.graphics.drawable.Drawable);
method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
method public void setAlpha(int);
@@ -12446,7 +12452,9 @@ package android.graphics.drawable {
method public void setLayerSize(int, int, int);
method public void setLayerWidth(int, int);
method public void setOpacity(int);
method public void setPadding(int, int, int, int);
method public void setPaddingMode(int);
method public void setPaddingRelative(int, int, int, int);
method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
field public static final int PADDING_MODE_NEST = 0; // 0x0
field public static final int PADDING_MODE_STACK = 1; // 0x1

View File

@@ -12706,7 +12706,9 @@ package android.graphics.drawable {
method public void draw(android.graphics.Canvas);
method public android.graphics.drawable.Drawable findDrawableByLayerId(int);
method public int findIndexByLayerId(int);
method public int getBottomPadding();
method public android.graphics.drawable.Drawable getDrawable(int);
method public int getEndPadding();
method public int getId(int);
method public int getLayerGravity(int);
method public int getLayerHeight(int);
@@ -12717,9 +12719,13 @@ package android.graphics.drawable {
method public int getLayerInsetStart(int);
method public int getLayerInsetTop(int);
method public int getLayerWidth(int);
method public int getLeftPadding();
method public int getNumberOfLayers();
method public int getOpacity();
method public int getPaddingMode();
method public int getRightPadding();
method public int getStartPadding();
method public int getTopPadding();
method public void invalidateDrawable(android.graphics.drawable.Drawable);
method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
method public void setAlpha(int);
@@ -12740,7 +12746,9 @@ package android.graphics.drawable {
method public void setLayerSize(int, int, int);
method public void setLayerWidth(int, int);
method public void setOpacity(int);
method public void setPadding(int, int, int, int);
method public void setPaddingMode(int);
method public void setPaddingRelative(int, int, int, int);
method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
field public static final int PADDING_MODE_NEST = 0; // 0x0
field public static final int PADDING_MODE_STACK = 1; // 0x1

View File

@@ -0,0 +1,26 @@
<!--
Copyright (C) 2015 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal">
<path
android:pathData="M7,10l5,5,5-5z"
android:fillColor="@color/white"/>
</vector>

View File

@@ -15,21 +15,24 @@
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingMode="stack">
<item android:drawable="@drawable/item_background_borderless_material"
android:gravity="end|center_vertical"
android:width="24dp"
android:height="24dp" />
<item android:gravity="end|center_vertical">
<vector android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal">
<path android:pathData="M7,10l5,5,5-5z"
android:fillColor="@color/white"/>
</vector>
android:paddingMode="stack"
android:paddingStart="0dp"
android:paddingEnd="48dp"
android:paddingLeft="0dp"
android:paddingRight="0dp">
<item
android:gravity="end|center_vertical"
android:width="48dp"
android:height="48dp">
<ripple
android:color="?attr/colorControlHighlight"
android:radius="24dp" />
</item>
<item android:end="48dp"
android:drawable="@color/transparent" />
<item
android:drawable="@drawable/ic_spinner_caret"
android:gravity="end|center_vertical"
android:width="24dp"
android:height="24dp"
android:end="12dp" />
</layer-list>

View File

@@ -5183,6 +5183,20 @@
<!-- Stack each layer directly atop the previous layer. -->
<enum name="stack" value="1" />
</attr>
<!-- Explicit top padding. Overrides child padding. -->
<attr name="paddingTop" />
<!-- Explicit bottom padding. Overrides child padding. -->
<attr name="paddingBottom" />
<!-- Explicit left padding. Overrides child padding. -->
<attr name="paddingLeft" />
<!-- Explicit right padding. Overrides child padding. -->
<attr name="paddingRight" />
<!-- Explicit start padding. Overrides child padding. Takes precedence
over absolute padding (e.g. left when layout direction is LTR). -->
<attr name="paddingStart" />
<!-- Explicit end padding. Overrides child padding. Takes precedence
over absolute padding (e.g. right when layout direction is LTR). -->
<attr name="paddingEnd" />
</declare-styleable>
<!-- Describes an item (or child) of a LayerDrawable. -->

View File

@@ -86,7 +86,6 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
LayerState mLayerState;
private int mOpacityOverride = PixelFormat.UNKNOWN;
private int[] mPaddingL;
private int[] mPaddingT;
private int[] mPaddingR;
@@ -177,12 +176,39 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
// Extract the theme attributes, if any.
state.mThemeAttrs = a.extractThemeAttrs();
mOpacityOverride = a.getInt(R.styleable.LayerDrawable_opacity, mOpacityOverride);
state.mAutoMirrored = a.getBoolean(R.styleable.LayerDrawable_autoMirrored,
state.mAutoMirrored);
state.mPaddingMode = a.getInteger(R.styleable.LayerDrawable_paddingMode,
state.mPaddingMode);
final int N = a.getIndexCount();
for (int i = 0; i < N; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.LayerDrawable_opacity:
state.mOpacityOverride = a.getInt(attr, state.mOpacityOverride);
break;
case R.styleable.LayerDrawable_paddingTop:
state.mPaddingTop = a.getDimensionPixelOffset(attr, state.mPaddingTop);
break;
case R.styleable.LayerDrawable_paddingBottom:
state.mPaddingBottom = a.getDimensionPixelOffset(attr, state.mPaddingBottom);
break;
case R.styleable.LayerDrawable_paddingLeft:
state.mPaddingLeft = a.getDimensionPixelOffset(attr, state.mPaddingLeft);
break;
case R.styleable.LayerDrawable_paddingRight:
state.mPaddingRight = a.getDimensionPixelOffset(attr, state.mPaddingRight);
break;
case R.styleable.LayerDrawable_paddingStart:
state.mPaddingStart = a.getDimensionPixelOffset(attr, state.mPaddingStart);
break;
case R.styleable.LayerDrawable_paddingEnd:
state.mPaddingEnd = a.getDimensionPixelOffset(attr, state.mPaddingEnd);
break;
case R.styleable.LayerDrawable_autoMirrored:
state.mAutoMirrored = a.getBoolean(attr, state.mAutoMirrored);
break;
case R.styleable.LayerDrawable_paddingMode:
state.mPaddingMode = a.getInteger(attr, state.mPaddingMode);
break;
}
}
}
/**
@@ -895,15 +921,210 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
@Override
public boolean getPadding(Rect padding) {
if (mLayerState.mPaddingMode == PADDING_MODE_NEST) {
final LayerState layerState = mLayerState;
if (layerState.mPaddingMode == PADDING_MODE_NEST) {
computeNestedPadding(padding);
} else {
computeStackedPadding(padding);
}
// If padding was explicitly specified (e.g. not -1) then override the
// computed padding in that dimension.
if (layerState.mPaddingTop >= 0) {
padding.top = layerState.mPaddingTop;
}
if (layerState.mPaddingBottom >= 0) {
padding.bottom = layerState.mPaddingBottom;
}
final int paddingRtlLeft;
final int paddingRtlRight;
if (getLayoutDirection() == LayoutDirection.RTL) {
paddingRtlLeft = layerState.mPaddingEnd;
paddingRtlRight = layerState.mPaddingStart;
} else {
paddingRtlLeft = layerState.mPaddingStart;
paddingRtlRight = layerState.mPaddingEnd;
}
final int paddingLeft = paddingRtlLeft >= 0 ? paddingRtlLeft : layerState.mPaddingLeft;
if (paddingLeft >= 0) {
padding.left = paddingLeft;
}
final int paddingRight = paddingRtlRight >= 0 ? paddingRtlRight : layerState.mPaddingRight;
if (paddingRight >= 0) {
padding.right = paddingRight;
}
return padding.left != 0 || padding.top != 0 || padding.right != 0 || padding.bottom != 0;
}
/**
* Sets the absolute padding.
* <p>
* If padding in a dimension is specified as {@code -1}, the resolved
* padding will use the value computed according to the padding mode (see
* {@link #setPaddingMode(int)}).
* <p>
* Calling this method clears any relative padding values previously set
* using {@link #setPaddingRelative(int, int, int, int)}.
*
* @param left the left padding in pixels, or -1 to use computed padding
* @param top the top padding in pixels, or -1 to use computed padding
* @param right the right padding in pixels, or -1 to use computed padding
* @param bottom the bottom padding in pixels, or -1 to use computed
* padding
* @attr ref android.R.styleable#LayerDrawable_paddingLeft
* @attr ref android.R.styleable#LayerDrawable_paddingTop
* @attr ref android.R.styleable#LayerDrawable_paddingRight
* @attr ref android.R.styleable#LayerDrawable_paddingBottom
* @see #setPaddingRelative(int, int, int, int)
*/
public void setPadding(int left, int top, int right, int bottom) {
final LayerState layerState = mLayerState;
layerState.mPaddingLeft = left;
layerState.mPaddingTop = top;
layerState.mPaddingRight = right;
layerState.mPaddingBottom = bottom;
// Clear relative padding values.
layerState.mPaddingStart = -1;
layerState.mPaddingEnd = -1;
}
/**
* Sets the relative padding.
* <p>
* If padding in a dimension is specified as {@code -1}, the resolved
* padding will use the value computed according to the padding mode (see
* {@link #setPaddingMode(int)}).
* <p>
* Calling this method clears any absolute padding values previously set
* using {@link #setPadding(int, int, int, int)}.
*
* @param start the start padding in pixels, or -1 to use computed padding
* @param top the top padding in pixels, or -1 to use computed padding
* @param end the end padding in pixels, or -1 to use computed padding
* @param bottom the bottom padding in pixels, or -1 to use computed
* padding
* @attr ref android.R.styleable#LayerDrawable_paddingStart
* @attr ref android.R.styleable#LayerDrawable_paddingTop
* @attr ref android.R.styleable#LayerDrawable_paddingEnd
* @attr ref android.R.styleable#LayerDrawable_paddingBottom
* @see #setPadding(int, int, int, int)
*/
public void setPaddingRelative(int start, int top, int end, int bottom) {
final LayerState layerState = mLayerState;
layerState.mPaddingStart = start;
layerState.mPaddingTop = top;
layerState.mPaddingEnd = end;
layerState.mPaddingBottom = bottom;
// Clear absolute padding values.
layerState.mPaddingLeft = -1;
layerState.mPaddingRight = -1;
}
/**
* Returns the left padding in pixels.
* <p>
* A return value of {@code -1} means there is no explicit padding set for
* this dimension. As a result, the value for this dimension returned by
* {@link #getPadding(Rect)} will be computed from the child layers
* according to the padding mode (see {@link #getPaddingMode()}.
*
* @return the left padding in pixels, or -1 if not explicitly specified
* @see #setPadding(int, int, int, int)
* @see #getPadding(Rect)
*/
public int getLeftPadding() {
return mLayerState.mPaddingLeft;
}
/**
* Returns the right padding in pixels.
* <p>
* A return value of {@code -1} means there is no explicit padding set for
* this dimension. As a result, the value for this dimension returned by
* {@link #getPadding(Rect)} will be computed from the child layers
* according to the padding mode (see {@link #getPaddingMode()}.
*
* @return the right padding in pixels, or -1 if not explicitly specified
* @see #setPadding(int, int, int, int)
* @see #getPadding(Rect)
*/
public int getRightPadding() {
return mLayerState.mPaddingRight;
}
/**
* Returns the start padding in pixels.
* <p>
* A return value of {@code -1} means there is no explicit padding set for
* this dimension. As a result, the value for this dimension returned by
* {@link #getPadding(Rect)} will be computed from the child layers
* according to the padding mode (see {@link #getPaddingMode()}.
*
* @return the start padding in pixels, or -1 if not explicitly specified
* @see #setPaddingRelative(int, int, int, int)
* @see #getPadding(Rect)
*/
public int getStartPadding() {
return mLayerState.mPaddingStart;
}
/**
* Returns the end padding in pixels.
* <p>
* A return value of {@code -1} means there is no explicit padding set for
* this dimension. As a result, the value for this dimension returned by
* {@link #getPadding(Rect)} will be computed from the child layers
* according to the padding mode (see {@link #getPaddingMode()}.
*
* @return the end padding in pixels, or -1 if not explicitly specified
* @see #setPaddingRelative(int, int, int, int)
* @see #getPadding(Rect)
*/
public int getEndPadding() {
return mLayerState.mPaddingEnd;
}
/**
* Returns the top padding in pixels.
* <p>
* A return value of {@code -1} means there is no explicit padding set for
* this dimension. As a result, the value for this dimension returned by
* {@link #getPadding(Rect)} will be computed from the child layers
* according to the padding mode (see {@link #getPaddingMode()}.
*
* @return the top padding in pixels, or -1 if not explicitly specified
* @see #setPadding(int, int, int, int)
* @see #setPaddingRelative(int, int, int, int)
* @see #getPadding(Rect)
*/
public int getTopPadding() {
return mLayerState.mPaddingTop;
}
/**
* Returns the bottom padding in pixels.
* <p>
* A return value of {@code -1} means there is no explicit padding set for
* this dimension. As a result, the value for this dimension returned by
* {@link #getPadding(Rect)} will be computed from the child layers
* according to the padding mode (see {@link #getPaddingMode()}.
*
* @return the bottom padding in pixels, or -1 if not explicitly specified
* @see #setPadding(int, int, int, int)
* @see #setPaddingRelative(int, int, int, int)
* @see #getPadding(Rect)
*/
public int getBottomPadding() {
return mLayerState.mPaddingBottom;
}
private void computeNestedPadding(Rect padding) {
padding.left = 0;
padding.top = 0;
@@ -1109,8 +1330,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
}
/**
* Sets the opacity of this drawable directly, instead of collecting the
* states from the layers
* Sets the opacity of this drawable directly instead of collecting the
* states from the layers.
*
* @param opacity The opacity to use, or {@link PixelFormat#UNKNOWN
* PixelFormat.UNKNOWN} for the default behavior
@@ -1120,13 +1341,13 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
* @see PixelFormat#OPAQUE
*/
public void setOpacity(int opacity) {
mOpacityOverride = opacity;
mLayerState.mOpacityOverride = opacity;
}
@Override
public int getOpacity() {
if (mOpacityOverride != PixelFormat.UNKNOWN) {
return mOpacityOverride;
if (mLayerState.mOpacityOverride != PixelFormat.UNKNOWN) {
return mLayerState.mOpacityOverride;
}
return mLayerState.getOpacity();
}
@@ -1265,12 +1486,12 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
* dimension, defaults to START or TOP. Otherwise, defaults to FILL to
* preserve legacy behavior.
*
* @param gravity
* @param width
* @param height
* @return
* @param gravity layer gravity
* @param width width of the layer if set, -1 otherwise
* @param height height of the layer if set, -1 otherwise
* @return the default gravity for the layer
*/
private int resolveGravity(int gravity, int width, int height) {
private static int resolveGravity(int gravity, int width, int height) {
if (!Gravity.isHorizontal(gravity)) {
if (width < 0) {
gravity |= Gravity.FILL_HORIZONTAL;
@@ -1504,6 +1725,14 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
ChildDrawable[] mChildren;
int[] mThemeAttrs;
int mPaddingTop = -1;
int mPaddingBottom = -1;
int mPaddingLeft = -1;
int mPaddingRight = -1;
int mPaddingStart = -1;
int mPaddingEnd = -1;
int mOpacityOverride = PixelFormat.UNKNOWN;
int mChangingConfigurations;
int mChildrenChangingConfigurations;
@@ -1540,6 +1769,13 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
mAutoMirrored = orig.mAutoMirrored;
mPaddingMode = orig.mPaddingMode;
mThemeAttrs = orig.mThemeAttrs;
mPaddingTop = orig.mPaddingTop;
mPaddingBottom = orig.mPaddingBottom;
mPaddingLeft = orig.mPaddingLeft;
mPaddingRight = orig.mPaddingRight;
mPaddingStart = orig.mPaddingStart;
mPaddingEnd = orig.mPaddingEnd;
mOpacityOverride = orig.mOpacityOverride;
} else {
mNum = 0;
mChildren = null;

View File

@@ -323,7 +323,21 @@ public class RippleDrawable extends LayerDrawable {
*/
@Override
public boolean isProjected() {
return getNumberOfLayers() == 0;
// If the maximum radius is contained entirely within the bounds, we
// don't need to project this ripple.
final int radius = mState.mMaxRadius;
final Rect bounds = getBounds();
if (radius != RADIUS_AUTO && radius <= bounds.width() / 2
&& radius <= bounds.height() / 2) {
return false;
}
// Otherwise, if the layer is bounded then we don't need to project.
return !isBounded();
}
private boolean isBounded() {
return getNumberOfLayers() > 0;
}
@Override
@@ -545,7 +559,7 @@ public class RippleDrawable extends LayerDrawable {
y = mHotspotBounds.exactCenterY();
}
final boolean isBounded = !isProjected();
final boolean isBounded = isBounded();
mRipple = new RippleForeground(this, mHotspotBounds, x, y, isBounded);
}
@@ -866,7 +880,7 @@ public class RippleDrawable extends LayerDrawable {
@Override
public Rect getDirtyBounds() {
if (isProjected()) {
if (!isBounded()) {
final Rect drawingBounds = mDrawingBounds;
final Rect dirtyBounds = mDirtyBounds;
dirtyBounds.set(drawingBounds);