Merge "Support for hollow switch and seek bar thumbs"
@@ -1047,6 +1047,7 @@ package android {
|
||||
field public static final int spinnerStyle = 16842881; // 0x1010081
|
||||
field public static final int spinnersShown = 16843595; // 0x101034b
|
||||
field public static final int splitMotionEvents = 16843503; // 0x10102ef
|
||||
field public static final int splitTrack = 16843858; // 0x1010452
|
||||
field public static final int src = 16843033; // 0x1010119
|
||||
field public static final int ssp = 16843747; // 0x10103e3
|
||||
field public static final int sspPattern = 16843749; // 0x10103e5
|
||||
@@ -34386,9 +34387,11 @@ package android.widget {
|
||||
ctor public AbsSeekBar(android.content.Context, android.util.AttributeSet, int);
|
||||
ctor public AbsSeekBar(android.content.Context, android.util.AttributeSet, int, int);
|
||||
method public int getKeyProgressIncrement();
|
||||
method public boolean getSplitTrack();
|
||||
method public android.graphics.drawable.Drawable getThumb();
|
||||
method public int getThumbOffset();
|
||||
method public void setKeyProgressIncrement(int);
|
||||
method public void setSplitTrack(boolean);
|
||||
method public void setThumb(android.graphics.drawable.Drawable);
|
||||
method public void setThumbOffset(int);
|
||||
}
|
||||
@@ -36193,6 +36196,7 @@ package android.widget {
|
||||
ctor public Switch(android.content.Context, android.util.AttributeSet);
|
||||
ctor public Switch(android.content.Context, android.util.AttributeSet, int);
|
||||
ctor public Switch(android.content.Context, android.util.AttributeSet, int, int);
|
||||
method public boolean getSplitTrack();
|
||||
method public int getSwitchMinWidth();
|
||||
method public int getSwitchPadding();
|
||||
method public java.lang.CharSequence getTextOff();
|
||||
@@ -36201,6 +36205,7 @@ package android.widget {
|
||||
method public int getThumbTextPadding();
|
||||
method public android.graphics.drawable.Drawable getTrackDrawable();
|
||||
method public void onMeasure(int, int);
|
||||
method public void setSplitTrack(boolean);
|
||||
method public void setSwitchMinWidth(int);
|
||||
method public void setSwitchPadding(int);
|
||||
method public void setSwitchTextAppearance(android.content.Context, int);
|
||||
|
||||
@@ -19,7 +19,9 @@ package android.widget;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region.Op;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
@@ -32,9 +34,12 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import com.android.internal.R;
|
||||
|
||||
public abstract class AbsSeekBar extends ProgressBar {
|
||||
private final Rect mTempRect = new Rect();
|
||||
|
||||
private Drawable mThumb;
|
||||
private int mThumbOffset;
|
||||
|
||||
private boolean mSplitTrack;
|
||||
|
||||
/**
|
||||
* On touch, this offset plus the scaled value from the position of the
|
||||
* touch will form the progress value. Usually 0.
|
||||
@@ -51,10 +56,10 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
* progress.
|
||||
*/
|
||||
private int mKeyProgressIncrement = 1;
|
||||
|
||||
|
||||
private static final int NO_ALPHA = 0xFF;
|
||||
private float mDisabledAlpha;
|
||||
|
||||
|
||||
private int mScaledTouchSlop;
|
||||
private float mTouchDownX;
|
||||
private boolean mIsDragging;
|
||||
@@ -76,12 +81,16 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
|
||||
TypedArray a = context.obtainStyledAttributes(
|
||||
attrs, com.android.internal.R.styleable.SeekBar, defStyleAttr, defStyleRes);
|
||||
Drawable thumb = a.getDrawable(com.android.internal.R.styleable.SeekBar_thumb);
|
||||
setThumb(thumb); // will guess mThumbOffset if thumb != null...
|
||||
// ...but allow layout to override this
|
||||
int thumbOffset = a.getDimensionPixelOffset(
|
||||
|
||||
final Drawable thumb = a.getDrawable(com.android.internal.R.styleable.SeekBar_thumb);
|
||||
setThumb(thumb);
|
||||
|
||||
// Guess thumb offset if thumb != null, but allow layout to override.
|
||||
final int thumbOffset = a.getDimensionPixelOffset(
|
||||
com.android.internal.R.styleable.SeekBar_thumbOffset, getThumbOffset());
|
||||
setThumbOffset(thumbOffset);
|
||||
|
||||
mSplitTrack = a.getBoolean(com.android.internal.R.styleable.SeekBar_splitTrack, false);
|
||||
a.recycle();
|
||||
|
||||
a = context.obtainStyledAttributes(attrs,
|
||||
@@ -97,7 +106,7 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
* <p>
|
||||
* If the thumb is a valid drawable (i.e. not null), half its width will be
|
||||
* used as the new thumb offset (@see #setThumbOffset(int)).
|
||||
*
|
||||
*
|
||||
* @param thumb Drawable representing the thumb
|
||||
*/
|
||||
public void setThumb(Drawable thumb) {
|
||||
@@ -132,7 +141,7 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
mThumb = thumb;
|
||||
invalidate();
|
||||
if (needUpdate) {
|
||||
updateThumbPos(getWidth(), getHeight());
|
||||
updateThumbAndTrackPos(getWidth(), getHeight());
|
||||
if (thumb != null && thumb.isStateful()) {
|
||||
// Note that if the states are different this won't work.
|
||||
// For now, let's consider that an app bug.
|
||||
@@ -162,7 +171,7 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
/**
|
||||
* Sets the thumb offset that allows the thumb to extend out of the range of
|
||||
* the track.
|
||||
*
|
||||
*
|
||||
* @param thumbOffset The offset amount in pixels.
|
||||
*/
|
||||
public void setThumbOffset(int thumbOffset) {
|
||||
@@ -170,9 +179,28 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether the track should be split by the thumb. When true,
|
||||
* the thumb's optical bounds will be clipped out of the track drawable,
|
||||
* then the thumb will be drawn into the resulting gap.
|
||||
*
|
||||
* @param splitTrack Whether the track should be split by the thumb
|
||||
*/
|
||||
public void setSplitTrack(boolean splitTrack) {
|
||||
mSplitTrack = splitTrack;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the track should be split by the thumb.
|
||||
*/
|
||||
public boolean getSplitTrack() {
|
||||
return mSplitTrack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of progress changed via the arrow keys.
|
||||
*
|
||||
*
|
||||
* @param increment The amount to increment or decrement when the user
|
||||
* presses the arrow keys.
|
||||
*/
|
||||
@@ -184,14 +212,14 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
* Returns the amount of progress changed via the arrow keys.
|
||||
* <p>
|
||||
* By default, this will be a value that is derived from the max progress.
|
||||
*
|
||||
*
|
||||
* @return The amount to increment or decrement when the user presses the
|
||||
* arrow keys. This will be positive.
|
||||
*/
|
||||
public int getKeyProgressIncrement() {
|
||||
return mKeyProgressIncrement;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void setMax(int max) {
|
||||
super.setMax(max);
|
||||
@@ -217,79 +245,85 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
@Override
|
||||
protected void drawableStateChanged() {
|
||||
super.drawableStateChanged();
|
||||
|
||||
Drawable progressDrawable = getProgressDrawable();
|
||||
|
||||
final Drawable progressDrawable = getProgressDrawable();
|
||||
if (progressDrawable != null) {
|
||||
progressDrawable.setAlpha(isEnabled() ? NO_ALPHA : (int) (NO_ALPHA * mDisabledAlpha));
|
||||
}
|
||||
|
||||
if (mThumb != null && mThumb.isStateful()) {
|
||||
int[] state = getDrawableState();
|
||||
mThumb.setState(state);
|
||||
|
||||
final Drawable thumb = mThumb;
|
||||
if (thumb != null && thumb.isStateful()) {
|
||||
thumb.setState(getDrawableState());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
void onProgressRefresh(float scale, boolean fromUser) {
|
||||
super.onProgressRefresh(scale, fromUser);
|
||||
Drawable thumb = mThumb;
|
||||
|
||||
final Drawable thumb = mThumb;
|
||||
if (thumb != null) {
|
||||
setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);
|
||||
/*
|
||||
* Since we draw translated, the drawable's bounds that it signals
|
||||
* for invalidation won't be the actual bounds we want invalidated,
|
||||
* so just invalidate this whole view.
|
||||
*/
|
||||
|
||||
// Since we draw translated, the drawable's bounds that it signals
|
||||
// for invalidation won't be the actual bounds we want invalidated,
|
||||
// so just invalidate this whole view.
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
updateThumbPos(w, h);
|
||||
|
||||
updateThumbAndTrackPos(w, h);
|
||||
}
|
||||
|
||||
private void updateThumbPos(int w, int h) {
|
||||
Drawable d = getCurrentDrawable();
|
||||
Drawable thumb = mThumb;
|
||||
int thumbHeight = thumb == null ? 0 : thumb.getIntrinsicHeight();
|
||||
private void updateThumbAndTrackPos(int w, int h) {
|
||||
final Drawable track = getCurrentDrawable();
|
||||
final Drawable thumb = mThumb;
|
||||
|
||||
// The max height does not incorporate padding, whereas the height
|
||||
// parameter does
|
||||
int trackHeight = Math.min(mMaxHeight, h - mPaddingTop - mPaddingBottom);
|
||||
|
||||
int max = getMax();
|
||||
float scale = max > 0 ? (float) getProgress() / (float) max : 0;
|
||||
|
||||
// parameter does.
|
||||
final int trackHeight = Math.min(mMaxHeight, h - mPaddingTop - mPaddingBottom);
|
||||
final int thumbHeight = thumb == null ? 0 : thumb.getIntrinsicHeight();
|
||||
|
||||
// Apply offset to whichever item is taller.
|
||||
final int trackOffset;
|
||||
final int thumbOffset;
|
||||
if (thumbHeight > trackHeight) {
|
||||
if (thumb != null) {
|
||||
setThumbPos(w, thumb, scale, 0);
|
||||
}
|
||||
int gapForCenteringTrack = (thumbHeight - trackHeight) / 2;
|
||||
if (d != null) {
|
||||
// Canvas will be translated by the padding, so 0,0 is where we start drawing
|
||||
d.setBounds(0, gapForCenteringTrack,
|
||||
w - mPaddingRight - mPaddingLeft, h - mPaddingBottom - gapForCenteringTrack
|
||||
- mPaddingTop);
|
||||
}
|
||||
trackOffset = (thumbHeight - trackHeight) / 2;
|
||||
thumbOffset = 0;
|
||||
} else {
|
||||
if (d != null) {
|
||||
// Canvas will be translated by the padding, so 0,0 is where we start drawing
|
||||
d.setBounds(0, 0, w - mPaddingRight - mPaddingLeft, h - mPaddingBottom
|
||||
- mPaddingTop);
|
||||
}
|
||||
int gap = (trackHeight - thumbHeight) / 2;
|
||||
if (thumb != null) {
|
||||
setThumbPos(w, thumb, scale, gap);
|
||||
}
|
||||
trackOffset = 0;
|
||||
thumbOffset = (trackHeight - thumbHeight) / 2;
|
||||
}
|
||||
|
||||
if (track != null) {
|
||||
track.setBounds(0, trackOffset, w - mPaddingRight - mPaddingLeft,
|
||||
h - mPaddingBottom - trackOffset - mPaddingTop);
|
||||
}
|
||||
|
||||
if (thumb != null) {
|
||||
setThumbPos(w, thumb, getScale(), thumbOffset);
|
||||
}
|
||||
}
|
||||
|
||||
private float getScale() {
|
||||
final int max = getMax();
|
||||
return max > 0 ? getProgress() / (float) max : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gap If set to {@link Integer#MIN_VALUE}, this will be ignored and
|
||||
* Updates the thumb drawable bounds.
|
||||
*
|
||||
* @param w Width of the view, including padding
|
||||
* @param thumb Drawable used for the thumb
|
||||
* @param scale Current progress between 0 and 1
|
||||
* @param offset Vertical offset for centering. If set to
|
||||
* {@link Integer#MIN_VALUE}, the current offset will be used.
|
||||
*/
|
||||
private void setThumbPos(int w, Drawable thumb, float scale, int gap) {
|
||||
private void setThumbPos(int w, Drawable thumb, float scale, int offset) {
|
||||
int available = w - mPaddingLeft - mPaddingRight;
|
||||
final int thumbWidth = thumb.getIntrinsicWidth();
|
||||
final int thumbHeight = thumb.getIntrinsicHeight();
|
||||
@@ -301,13 +335,13 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
final int thumbPos = (int) (scale * available + 0.5f);
|
||||
|
||||
final int top, bottom;
|
||||
if (gap == Integer.MIN_VALUE) {
|
||||
if (offset == Integer.MIN_VALUE) {
|
||||
final Rect oldBounds = thumb.getBounds();
|
||||
top = oldBounds.top;
|
||||
bottom = oldBounds.bottom;
|
||||
} else {
|
||||
top = gap;
|
||||
bottom = gap + thumbHeight;
|
||||
top = offset;
|
||||
bottom = offset + thumbHeight;
|
||||
}
|
||||
|
||||
final int left = (isLayoutRtl() && mMirrorForRtl) ? available - thumbPos : thumbPos;
|
||||
@@ -342,6 +376,33 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
protected synchronized void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
drawThumb(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
void drawTrack(Canvas canvas) {
|
||||
final Drawable thumbDrawable = mThumb;
|
||||
if (thumbDrawable != null && mSplitTrack) {
|
||||
final Insets insets = thumbDrawable.getOpticalInsets();
|
||||
final Rect tempRect = mTempRect;
|
||||
thumbDrawable.copyBounds(tempRect);
|
||||
tempRect.offset(mPaddingLeft - mThumbOffset, mPaddingTop);
|
||||
tempRect.left += insets.left;
|
||||
tempRect.right -= insets.right;
|
||||
|
||||
final int saveCount = canvas.save();
|
||||
canvas.clipRect(tempRect, Op.DIFFERENCE);
|
||||
super.drawTrack(canvas);
|
||||
canvas.restoreToCount(saveCount);
|
||||
} else {
|
||||
super.drawTrack(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the thumb.
|
||||
*/
|
||||
void drawThumb(Canvas canvas) {
|
||||
if (mThumb != null) {
|
||||
canvas.save();
|
||||
// Translate the padding. For the x, we need to allow the thumb to
|
||||
@@ -366,17 +427,17 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
}
|
||||
dw += mPaddingLeft + mPaddingRight;
|
||||
dh += mPaddingTop + mPaddingBottom;
|
||||
|
||||
|
||||
setMeasuredDimension(resolveSizeAndState(dw, widthMeasureSpec, 0),
|
||||
resolveSizeAndState(dh, heightMeasureSpec, 0));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (!mIsUserSeekable || !isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if (isInScrollingContainer()) {
|
||||
@@ -391,7 +452,7 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
attemptClaimDrag();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (mIsDragging) {
|
||||
trackTouchEvent(event);
|
||||
@@ -408,7 +469,7 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (mIsDragging) {
|
||||
trackTouchEvent(event);
|
||||
@@ -426,7 +487,7 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
// value has not apparently changed)
|
||||
invalidate();
|
||||
break;
|
||||
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
if (mIsDragging) {
|
||||
onStopTrackingTouch();
|
||||
@@ -493,7 +554,7 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
mParent.requestDisallowInterceptTouchEvent(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is called when the user has started touching this widget.
|
||||
*/
|
||||
@@ -526,7 +587,7 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
setProgress(progress - mKeyProgressIncrement, true);
|
||||
onKeyChange();
|
||||
return true;
|
||||
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
if (progress >= getMax()) break;
|
||||
setProgress(progress + mKeyProgressIncrement, true);
|
||||
@@ -595,17 +656,13 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
public void onRtlPropertiesChanged(int layoutDirection) {
|
||||
super.onRtlPropertiesChanged(layoutDirection);
|
||||
|
||||
int max = getMax();
|
||||
float scale = max > 0 ? (float) getProgress() / (float) max : 0;
|
||||
|
||||
Drawable thumb = mThumb;
|
||||
final Drawable thumb = mThumb;
|
||||
if (thumb != null) {
|
||||
setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);
|
||||
/*
|
||||
* Since we draw translated, the drawable's bounds that it signals
|
||||
* for invalidation won't be the actual bounds we want invalidated,
|
||||
* so just invalidate this whole view.
|
||||
*/
|
||||
setThumbPos(getWidth(), thumb, getScale(), Integer.MIN_VALUE);
|
||||
|
||||
// Since we draw translated, the drawable's bounds that it signals
|
||||
// for invalidation won't be the actual bounds we want invalidated,
|
||||
// so just invalidate this whole view.
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1066,21 +1066,30 @@ public class ProgressBar extends View {
|
||||
protected synchronized void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
Drawable d = mCurrentDrawable;
|
||||
drawTrack(canvas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the progress bar track.
|
||||
*/
|
||||
void drawTrack(Canvas canvas) {
|
||||
final Drawable d = mCurrentDrawable;
|
||||
if (d != null) {
|
||||
// Translate canvas so a indeterminate circular progress bar with padding
|
||||
// rotates properly in its animation
|
||||
canvas.save();
|
||||
final int saveCount = canvas.save();
|
||||
|
||||
if(isLayoutRtl() && mMirrorForRtl) {
|
||||
canvas.translate(getWidth() - mPaddingRight, mPaddingTop);
|
||||
canvas.scale(-1.0f, 1.0f);
|
||||
} else {
|
||||
canvas.translate(mPaddingLeft, mPaddingTop);
|
||||
}
|
||||
long time = getDrawingTime();
|
||||
|
||||
final long time = getDrawingTime();
|
||||
if (mHasAnimation) {
|
||||
mAnimation.getTransformation(time, mTransformation);
|
||||
float scale = mTransformation.getAlpha();
|
||||
final float scale = mTransformation.getAlpha();
|
||||
try {
|
||||
mInDrawing = true;
|
||||
d.setLevel((int) (scale * MAX_LEVEL));
|
||||
@@ -1089,8 +1098,10 @@ public class ProgressBar extends View {
|
||||
}
|
||||
postInvalidateOnAnimation();
|
||||
}
|
||||
|
||||
d.draw(canvas);
|
||||
canvas.restore();
|
||||
canvas.restoreToCount(saveCount);
|
||||
|
||||
if (mShouldStartAnimationDrawable && d instanceof Animatable) {
|
||||
((Animatable) d).start();
|
||||
mShouldStartAnimationDrawable = false;
|
||||
|
||||
@@ -22,9 +22,11 @@ import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.Region.Op;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.Layout;
|
||||
import android.text.StaticLayout;
|
||||
@@ -85,6 +87,7 @@ public class Switch extends CompoundButton {
|
||||
private int mThumbTextPadding;
|
||||
private int mSwitchMinWidth;
|
||||
private int mSwitchPadding;
|
||||
private boolean mSplitTrack;
|
||||
private CharSequence mTextOn;
|
||||
private CharSequence mTextOff;
|
||||
|
||||
@@ -174,13 +177,13 @@ public class Switch extends CompoundButton {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
|
||||
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
|
||||
Resources res = getResources();
|
||||
|
||||
final Resources res = getResources();
|
||||
mTextPaint.density = res.getDisplayMetrics().density;
|
||||
mTextPaint.setCompatibilityScaling(res.getCompatibilityInfo().applicationScale);
|
||||
|
||||
final TypedArray a = context.obtainStyledAttributes(
|
||||
attrs, com.android.internal.R.styleable.Switch, defStyleAttr, defStyleRes);
|
||||
|
||||
mThumbDrawable = a.getDrawable(com.android.internal.R.styleable.Switch_thumb);
|
||||
mTrackDrawable = a.getDrawable(com.android.internal.R.styleable.Switch_track);
|
||||
mTextOn = a.getText(com.android.internal.R.styleable.Switch_textOn);
|
||||
@@ -191,15 +194,16 @@ public class Switch extends CompoundButton {
|
||||
com.android.internal.R.styleable.Switch_switchMinWidth, 0);
|
||||
mSwitchPadding = a.getDimensionPixelSize(
|
||||
com.android.internal.R.styleable.Switch_switchPadding, 0);
|
||||
mSplitTrack = a.getBoolean(com.android.internal.R.styleable.Switch_splitTrack, false);
|
||||
|
||||
int appearance = a.getResourceId(
|
||||
final int appearance = a.getResourceId(
|
||||
com.android.internal.R.styleable.Switch_switchTextAppearance, 0);
|
||||
if (appearance != 0) {
|
||||
setSwitchTextAppearance(context, appearance);
|
||||
}
|
||||
a.recycle();
|
||||
|
||||
ViewConfiguration config = ViewConfiguration.get(context);
|
||||
final ViewConfiguration config = ViewConfiguration.get(context);
|
||||
mTouchSlop = config.getScaledTouchSlop();
|
||||
mMinFlingVelocity = config.getScaledMinimumFlingVelocity();
|
||||
|
||||
@@ -468,6 +472,29 @@ public class Switch extends CompoundButton {
|
||||
return mThumbDrawable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether the track should be split by the thumb. When true,
|
||||
* the thumb's optical bounds will be clipped out of the track drawable,
|
||||
* then the thumb will be drawn into the resulting gap.
|
||||
*
|
||||
* @param splitTrack Whether the track should be split by the thumb
|
||||
*
|
||||
* @attr ref android.R.styleable#Switch_splitTrack
|
||||
*/
|
||||
public void setSplitTrack(boolean splitTrack) {
|
||||
mSplitTrack = splitTrack;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the track should be split by the thumb.
|
||||
*
|
||||
* @attr ref android.R.styleable#Switch_splitTrack
|
||||
*/
|
||||
public boolean getSplitTrack() {
|
||||
return mSplitTrack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text displayed when the button is in the checked state.
|
||||
*
|
||||
@@ -518,13 +545,15 @@ public class Switch extends CompoundButton {
|
||||
|
||||
mTrackDrawable.getPadding(mTempRect);
|
||||
|
||||
final int maxTextWidth = Math.max(mOnLayout.getWidth(), mOffLayout.getWidth());
|
||||
final int maxTextWidth = Math.max(mOnLayout.getWidth(), mOffLayout.getWidth())
|
||||
+ mThumbTextPadding * 2;
|
||||
mThumbWidth = Math.max(maxTextWidth, mThumbDrawable.getIntrinsicWidth());
|
||||
|
||||
final int switchWidth = Math.max(mSwitchMinWidth,
|
||||
maxTextWidth * 2 + mThumbTextPadding * 4 + mTempRect.left + mTempRect.right);
|
||||
2 * mThumbWidth + mTempRect.left + mTempRect.right);
|
||||
final int switchHeight = Math.max(mTrackDrawable.getIntrinsicHeight(),
|
||||
mThumbDrawable.getIntrinsicHeight());
|
||||
|
||||
mThumbWidth = maxTextWidth + mThumbTextPadding * 2;
|
||||
|
||||
mSwitchWidth = switchWidth;
|
||||
mSwitchHeight = switchHeight;
|
||||
@@ -777,7 +806,7 @@ public class Switch extends CompoundButton {
|
||||
final Drawable trackDrawable = mTrackDrawable;
|
||||
final Drawable thumbDrawable = mThumbDrawable;
|
||||
|
||||
// Draw the switch
|
||||
// Layout the track.
|
||||
final int switchLeft = mSwitchLeft;
|
||||
final int switchTop = mSwitchTop;
|
||||
final int switchRight = mSwitchRight;
|
||||
@@ -793,9 +822,10 @@ public class Switch extends CompoundButton {
|
||||
// Relies on mTempRect, MUST be called first!
|
||||
final int thumbPos = getThumbOffset();
|
||||
|
||||
// Layout the thumb.
|
||||
thumbDrawable.getPadding(tempRect);
|
||||
int thumbLeft = switchInnerLeft - tempRect.left + thumbPos;
|
||||
int thumbRight = switchInnerLeft + thumbPos + mThumbWidth + tempRect.right;
|
||||
final int thumbLeft = switchInnerLeft - tempRect.left + thumbPos;
|
||||
final int thumbRight = switchInnerLeft + thumbPos + mThumbWidth + tempRect.right;
|
||||
thumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);
|
||||
|
||||
final Drawable background = getBackground();
|
||||
@@ -805,20 +835,32 @@ public class Switch extends CompoundButton {
|
||||
|
||||
super.onDraw(canvas);
|
||||
|
||||
trackDrawable.draw(canvas);
|
||||
if (mSplitTrack) {
|
||||
final Insets insets = thumbDrawable.getOpticalInsets();
|
||||
thumbDrawable.copyBounds(tempRect);
|
||||
tempRect.left += insets.left;
|
||||
tempRect.right -= insets.right;
|
||||
|
||||
final int saveCount = canvas.save();
|
||||
canvas.clipRect(tempRect, Op.DIFFERENCE);
|
||||
trackDrawable.draw(canvas);
|
||||
canvas.restoreToCount(saveCount);
|
||||
} else {
|
||||
trackDrawable.draw(canvas);
|
||||
}
|
||||
|
||||
final int saveCount = canvas.save();
|
||||
canvas.clipRect(switchInnerLeft, switchTop, switchInnerRight, switchBottom);
|
||||
thumbDrawable.draw(canvas);
|
||||
|
||||
final int drawableState[] = getDrawableState();
|
||||
if (mTextColors != null) {
|
||||
mTextPaint.setColor(mTextColors.getColorForState(drawableState, 0));
|
||||
}
|
||||
mTextPaint.drawableState = drawableState;
|
||||
|
||||
final Layout switchText = getTargetCheckedState() ? mOnLayout : mOffLayout;
|
||||
if (switchText != null) {
|
||||
final int drawableState[] = getDrawableState();
|
||||
if (mTextColors != null) {
|
||||
mTextPaint.setColor(mTextColors.getColorForState(drawableState, 0));
|
||||
}
|
||||
mTextPaint.drawableState = drawableState;
|
||||
|
||||
final int left = (thumbLeft + thumbRight) / 2 - switchText.getWidth() / 2;
|
||||
final int top = (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2;
|
||||
canvas.translate(left, top);
|
||||
@@ -889,12 +931,16 @@ public class Switch extends CompoundButton {
|
||||
protected void drawableStateChanged() {
|
||||
super.drawableStateChanged();
|
||||
|
||||
int[] myDrawableState = getDrawableState();
|
||||
final int[] myDrawableState = getDrawableState();
|
||||
|
||||
// Set the state of the Drawable
|
||||
// Drawable may be null when checked state is set from XML, from super constructor
|
||||
if (mThumbDrawable != null) mThumbDrawable.setState(myDrawableState);
|
||||
if (mTrackDrawable != null) mTrackDrawable.setState(myDrawableState);
|
||||
if (mThumbDrawable != null && mThumbDrawable.setState(myDrawableState)) {
|
||||
// Handle changes to thumb width and height.
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
if (mTrackDrawable != null) {
|
||||
mTrackDrawable.setState(myDrawableState);
|
||||
}
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 341 B After Width: | Height: | Size: 232 B |
|
Before Width: | Height: | Size: 241 B After Width: | Height: | Size: 184 B |
|
Before Width: | Height: | Size: 546 B After Width: | Height: | Size: 523 B |
|
Before Width: | Height: | Size: 222 B After Width: | Height: | Size: 187 B |
|
Before Width: | Height: | Size: 230 B After Width: | Height: | Size: 181 B |
|
Before Width: | Height: | Size: 182 B After Width: | Height: | Size: 154 B |
|
Before Width: | Height: | Size: 390 B After Width: | Height: | Size: 371 B |
|
Before Width: | Height: | Size: 184 B After Width: | Height: | Size: 156 B |
|
Before Width: | Height: | Size: 495 B After Width: | Height: | Size: 314 B |
|
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 248 B |
|
Before Width: | Height: | Size: 827 B After Width: | Height: | Size: 767 B |
|
Before Width: | Height: | Size: 279 B After Width: | Height: | Size: 223 B |
|
Before Width: | Height: | Size: 1014 B After Width: | Height: | Size: 388 B |
|
Before Width: | Height: | Size: 881 B After Width: | Height: | Size: 294 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 508 B After Width: | Height: | Size: 293 B |
@@ -16,22 +16,26 @@
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_enabled="false">
|
||||
<bitmap android:src="@drawable/scrubber_track_qntm_alpha"
|
||||
<nine-patch android:src="@drawable/scrubber_track_qntm_alpha"
|
||||
android:tint="?attr/colorControlNormal" />
|
||||
</item>
|
||||
<item>
|
||||
<layer-list>
|
||||
<item android:id="@id/background">
|
||||
<bitmap android:src="@drawable/scrubber_track_qntm_alpha"
|
||||
<nine-patch android:src="@drawable/scrubber_track_qntm_alpha"
|
||||
android:tint="?attr/colorControlNormal" />
|
||||
</item>
|
||||
<item android:id="@id/secondaryProgress">
|
||||
<bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
|
||||
android:tint="?attr/colorControlNormal" />
|
||||
<scale android:scaleWidth="100%">
|
||||
<nine-patch android:src="@drawable/scrubber_primary_qntm_alpha"
|
||||
android:tint="?attr/colorControlNormal" />
|
||||
</scale>
|
||||
</item>
|
||||
<item android:id="@id/progress">
|
||||
<bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
|
||||
android:tint="?attr/colorControlActivated" />
|
||||
<scale android:scaleWidth="100%">
|
||||
<nine-patch android:src="@drawable/scrubber_primary_qntm_alpha"
|
||||
android:tint="?attr/colorControlActivated" />
|
||||
</scale>
|
||||
</item>
|
||||
</layer-list>
|
||||
</item>
|
||||
|
||||
@@ -3343,6 +3343,8 @@
|
||||
<attr name="thumb" format="reference" />
|
||||
<!-- An offset for the thumb that allows it to extend out of the range of the track. -->
|
||||
<attr name="thumbOffset" format="dimension" />
|
||||
<!-- Whether to split the track and leave a gap for the thumb drawable. -->
|
||||
<attr name="splitTrack" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="StackView">
|
||||
@@ -6393,6 +6395,8 @@
|
||||
<attr name="switchMinWidth" format="dimension" />
|
||||
<!-- Minimum space between the switch and caption text -->
|
||||
<attr name="switchPadding" format="dimension" />
|
||||
<!-- Whether to split the track and leave a gap for the thumb drawable. -->
|
||||
<attr name="splitTrack" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="Pointer">
|
||||
|
||||
@@ -2169,6 +2169,7 @@
|
||||
<public type="attr" name="toId" />
|
||||
<public type="attr" name="fromId" />
|
||||
<public type="attr" name="reversible" />
|
||||
<public type="attr" name="splitTrack" />
|
||||
|
||||
<public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
|
||||
|
||||
|
||||
@@ -455,10 +455,10 @@ please see styles_device_defaults.xml.
|
||||
<style name="Widget.Quantum.CompoundButton.Switch">
|
||||
<item name="track">@drawable/switch_track_quantum</item>
|
||||
<item name="thumb">@drawable/switch_inner_quantum</item>
|
||||
<item name="splitTrack">true</item>
|
||||
<item name="switchTextAppearance">@style/TextAppearance.Quantum.Widget.Switch</item>
|
||||
<item name="textOn"></item>
|
||||
<item name="textOff"></item>
|
||||
<item name="thumbTextPadding">12dip</item>
|
||||
<item name="switchMinWidth">72dip</item>
|
||||
<item name="switchPadding">16dip</item>
|
||||
<item name="background">?attr/selectableItemBackground</item>
|
||||
@@ -572,10 +572,8 @@ please see styles_device_defaults.xml.
|
||||
<item name="indeterminateOnly">false</item>
|
||||
<item name="progressDrawable">@drawable/scrubber_progress_horizontal_quantum</item>
|
||||
<item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_quantum</item>
|
||||
<item name="minHeight">13dip</item>
|
||||
<item name="maxHeight">13dip</item>
|
||||
<item name="thumb">@drawable/scrubber_control_selector_quantum</item>
|
||||
<item name="thumbOffset">16dip</item>
|
||||
<item name="splitTrack">true</item>
|
||||
<item name="focusable">true</item>
|
||||
<item name="paddingStart">16dip</item>
|
||||
<item name="paddingEnd">16dip</item>
|
||||
|
||||