diff options
-rw-r--r-- | api/current.txt | 8 | ||||
-rw-r--r-- | api/system-current.txt | 8 | ||||
-rw-r--r-- | core/res/res/drawable/ic_spinner_caret.xml | 26 | ||||
-rw-r--r-- | core/res/res/drawable/spinner_background_material.xml | 35 | ||||
-rw-r--r-- | core/res/res/values/attrs.xml | 14 | ||||
-rw-r--r-- | graphics/java/android/graphics/drawable/LayerDrawable.java | 272 | ||||
-rw-r--r-- | graphics/java/android/graphics/drawable/RippleDrawable.java | 20 |
7 files changed, 346 insertions, 37 deletions
diff --git a/api/current.txt b/api/current.txt index 9a4e905..23dc128 100644 --- a/api/current.txt +++ b/api/current.txt @@ -12408,7 +12408,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); @@ -12419,9 +12421,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); @@ -12442,7 +12448,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 diff --git a/api/system-current.txt b/api/system-current.txt index 8cdf938..92000c8 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -12702,7 +12702,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); @@ -12713,9 +12715,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); @@ -12736,7 +12742,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 diff --git a/core/res/res/drawable/ic_spinner_caret.xml b/core/res/res/drawable/ic_spinner_caret.xml new file mode 100644 index 0000000..6a18f89 --- /dev/null +++ b/core/res/res/drawable/ic_spinner_caret.xml @@ -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> diff --git a/core/res/res/drawable/spinner_background_material.xml b/core/res/res/drawable/spinner_background_material.xml index d5b509f..892dbc5 100644 --- a/core/res/res/drawable/spinner_background_material.xml +++ b/core/res/res/drawable/spinner_background_material.xml @@ -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> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 674c695..a7c4800 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -5169,6 +5169,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. --> diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index 8468d9e..3bbbc71 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -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; diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index 6731a17..f67dcb3 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -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); |