Methods Summary |
---|
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.setDuration(THUMB_ANIMATION_DURATION);
startAnimation(mPositionAnimator);
|
private void | cancelPositionAnimator()
if (mPositionAnimator != null) {
clearAnimation();
mPositionAnimator = null;
}
|
private void | cancelSuperTouch(android.view.MotionEvent ev)
MotionEvent cancel = MotionEvent.obtain(ev);
cancel.setAction(MotionEvent.ACTION_CANCEL);
super.onTouchEvent(cancel);
cancel.recycle();
|
private static float | constrain(float amount, float low, float high)Taken from android.util.MathUtils
return amount < low ? low : (amount > high ? high : amount);
|
public void | draw(android.graphics.Canvas c)
final Rect padding = mTempRect;
final int switchLeft = mSwitchLeft;
final int switchTop = mSwitchTop;
final int switchRight = mSwitchRight;
final int switchBottom = mSwitchBottom;
int thumbInitialLeft = switchLeft + getThumbOffset();
// Layout the track.
if (mTrackDrawable != null) {
mTrackDrawable.getPadding(padding);
// Adjust thumb position for track padding.
thumbInitialLeft += padding.left;
// If necessary, offset by the optical insets of the thumb asset.
int trackLeft = switchLeft;
int trackTop = switchTop;
int trackRight = switchRight;
int trackBottom = switchBottom;
mTrackDrawable.setBounds(trackLeft, trackTop, trackRight, trackBottom);
}
// Layout the thumb.
if (mThumbDrawable != null) {
mThumbDrawable.getPadding(padding);
final int thumbLeft = thumbInitialLeft - padding.left;
final int thumbRight = thumbInitialLeft + mThumbWidth + padding.right;
mThumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);
final Drawable background = getBackground();
if (background != null) {
DrawableCompat.setHotspotBounds(background, thumbLeft, switchTop,
thumbRight, switchBottom);
}
}
// Draw the background.
super.draw(c);
|
public void | drawableHotspotChanged(float x, float y)
if (Build.VERSION.SDK_INT >= 21) {
super.drawableHotspotChanged(x, y);
}
if (mThumbDrawable != null) {
DrawableCompat.setHotspot(mThumbDrawable, x, y);
}
if (mTrackDrawable != null) {
DrawableCompat.setHotspot(mTrackDrawable, x, y);
}
|
protected void | drawableStateChanged()
super.drawableStateChanged();
final int[] myDrawableState = getDrawableState();
if (mThumbDrawable != null) {
mThumbDrawable.setState(myDrawableState);
}
if (mTrackDrawable != null) {
mTrackDrawable.setState(myDrawableState);
}
invalidate();
|
public int | getCompoundPaddingLeft()
if (!ViewUtils.isLayoutRtl(this)) {
return super.getCompoundPaddingLeft();
}
int padding = super.getCompoundPaddingLeft() + mSwitchWidth;
if (!TextUtils.isEmpty(getText())) {
padding += mSwitchPadding;
}
return padding;
|
public int | getCompoundPaddingRight()
if (ViewUtils.isLayoutRtl(this)) {
return super.getCompoundPaddingRight();
}
int padding = super.getCompoundPaddingRight() + mSwitchWidth;
if (!TextUtils.isEmpty(getText())) {
padding += mSwitchPadding;
}
return padding;
|
public boolean | getShowText()
return mShowText;
|
public boolean | getSplitTrack()Returns whether the track should be split by the thumb.
return mSplitTrack;
|
public int | getSwitchMinWidth()Get the minimum width of the switch in pixels. The switch's width will be the maximum
of this value and its measured width as determined by the switch drawables and text used.
return mSwitchMinWidth;
|
public int | getSwitchPadding()Get the amount of horizontal padding between the switch and the associated text.
return mSwitchPadding;
|
private boolean | getTargetCheckedState()
return mThumbPosition > 0.5f;
|
public java.lang.CharSequence | getTextOff()Returns the text displayed when the button is not in the checked state.
return mTextOff;
|
public java.lang.CharSequence | getTextOn()Returns the text displayed when the button is in the checked state.
return mTextOn;
|
public android.graphics.drawable.Drawable | getThumbDrawable()Get the drawable used for the switch "thumb" - the piece that the user
can physically touch and drag along the track.
return mThumbDrawable;
|
private int | getThumbOffset()Translates thumb position to offset according to current RTL setting and
thumb scroll range. Accounts for both track and thumb padding.
final float thumbPosition;
if (ViewUtils.isLayoutRtl(this)) {
thumbPosition = 1 - mThumbPosition;
} else {
thumbPosition = mThumbPosition;
}
return (int) (thumbPosition * getThumbScrollRange() + 0.5f);
|
private int | getThumbScrollRange()
if (mTrackDrawable != null) {
final Rect padding = mTempRect;
mTrackDrawable.getPadding(padding);
return mSwitchWidth - mThumbWidth - padding.left - padding.right;
} else {
return 0;
}
|
public int | getThumbTextPadding()Get the horizontal padding around the text drawn on the switch itself.
return mThumbTextPadding;
|
public android.graphics.drawable.Drawable | getTrackDrawable()Get the drawable used for the track that the switch slides within.
return mTrackDrawable;
|
private boolean | hitThumb(float x, float y)
// Relies on mTempRect, MUST be called first!
final int thumbOffset = getThumbOffset();
mThumbDrawable.getPadding(mTempRect);
final int thumbTop = mSwitchTop - mTouchSlop;
final int thumbLeft = mSwitchLeft + thumbOffset - mTouchSlop;
final int thumbRight = thumbLeft + mThumbWidth +
mTempRect.left + mTempRect.right + mTouchSlop;
final int thumbBottom = mSwitchBottom + mTouchSlop;
return x > thumbLeft && x < thumbRight && y > thumbTop && y < thumbBottom;
|
public void | jumpDrawablesToCurrentState()
if (Build.VERSION.SDK_INT >= 11) {
super.jumpDrawablesToCurrentState();
if (mThumbDrawable != null) {
mThumbDrawable.jumpToCurrentState();
}
if (mTrackDrawable != null) {
mTrackDrawable.jumpToCurrentState();
}
if (mPositionAnimator != null && mPositionAnimator.hasStarted() &&
!mPositionAnimator.hasEnded()) {
clearAnimation();
mPositionAnimator = null;
}
}
|
private android.text.Layout | makeLayout(java.lang.CharSequence text)
final CharSequence transformed = (mSwitchTransformationMethod != null)
? mSwitchTransformationMethod.getTransformation(text, this)
: text;
return new StaticLayout(transformed, mTextPaint,
(int) Math.ceil(Layout.getDesiredWidth(transformed, mTextPaint)),
Layout.Alignment.ALIGN_NORMAL, 1.f, 0, true);
|
protected int[] | onCreateDrawableState(int extraSpace)
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
|
protected void | onDraw(android.graphics.Canvas canvas)
super.onDraw(canvas);
final Rect padding = mTempRect;
final Drawable trackDrawable = mTrackDrawable;
if (trackDrawable != null) {
trackDrawable.getPadding(padding);
} else {
padding.setEmpty();
}
final int switchTop = mSwitchTop;
final int switchBottom = mSwitchBottom;
final int switchInnerTop = switchTop + padding.top;
final int switchInnerBottom = switchBottom - padding.bottom;
final Drawable thumbDrawable = mThumbDrawable;
if (trackDrawable != null) {
trackDrawable.draw(canvas);
}
final int saveCount = canvas.save();
if (thumbDrawable != null) {
thumbDrawable.draw(canvas);
}
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 cX;
if (thumbDrawable != null) {
final Rect bounds = thumbDrawable.getBounds();
cX = bounds.left + bounds.right;
} else {
cX = getWidth();
}
final int left = cX / 2 - switchText.getWidth() / 2;
final int top = (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2;
canvas.translate(left, top);
switchText.draw(canvas);
}
canvas.restoreToCount(saveCount);
|
public void | onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent event)
super.onInitializeAccessibilityEvent(event);
event.setClassName(SwitchCompat.class.getName());
|
public void | onInitializeAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo info)
if (Build.VERSION.SDK_INT >= 14) {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(SwitchCompat.class.getName());
CharSequence switchText = isChecked() ? mTextOn : mTextOff;
if (!TextUtils.isEmpty(switchText)) {
CharSequence oldText = info.getText();
if (TextUtils.isEmpty(oldText)) {
info.setText(switchText);
} else {
StringBuilder newText = new StringBuilder();
newText.append(oldText).append(' ").append(switchText);
info.setText(newText);
}
}
}
|
protected void | onLayout(boolean changed, int left, int top, int right, int bottom)
super.onLayout(changed, left, top, right, bottom);
int opticalInsetLeft = 0;
int opticalInsetRight = 0;
if (mThumbDrawable != null) {
final Rect trackPadding = mTempRect;
if (mTrackDrawable != null) {
mTrackDrawable.getPadding(trackPadding);
} else {
trackPadding.setEmpty();
}
opticalInsetLeft = 0;
opticalInsetRight = 0;
}
final int switchRight;
final int switchLeft;
if (ViewUtils.isLayoutRtl(this)) {
switchLeft = getPaddingLeft() + opticalInsetLeft;
switchRight = switchLeft + mSwitchWidth - opticalInsetLeft - opticalInsetRight;
} else {
switchRight = getWidth() - getPaddingRight() - opticalInsetRight;
switchLeft = switchRight - mSwitchWidth + opticalInsetLeft + opticalInsetRight;
}
final int switchTop;
final int switchBottom;
switch (getGravity() & Gravity.VERTICAL_GRAVITY_MASK) {
default:
case Gravity.TOP:
switchTop = getPaddingTop();
switchBottom = switchTop + mSwitchHeight;
break;
case Gravity.CENTER_VERTICAL:
switchTop = (getPaddingTop() + getHeight() - getPaddingBottom()) / 2 -
mSwitchHeight / 2;
switchBottom = switchTop + mSwitchHeight;
break;
case Gravity.BOTTOM:
switchBottom = getHeight() - getPaddingBottom();
switchTop = switchBottom - mSwitchHeight;
break;
}
mSwitchLeft = switchLeft;
mSwitchTop = switchTop;
mSwitchBottom = switchBottom;
mSwitchRight = switchRight;
|
public void | onMeasure(int widthMeasureSpec, int heightMeasureSpec)
if (mShowText) {
if (mOnLayout == null) {
mOnLayout = makeLayout(mTextOn);
}
if (mOffLayout == null) {
mOffLayout = makeLayout(mTextOff);
}
}
final Rect padding = mTempRect;
final int thumbWidth;
final int thumbHeight;
if (mThumbDrawable != null) {
// Cached thumb width does not include padding.
mThumbDrawable.getPadding(padding);
thumbWidth = mThumbDrawable.getIntrinsicWidth() - padding.left - padding.right;
thumbHeight = mThumbDrawable.getIntrinsicHeight();
} else {
thumbWidth = 0;
thumbHeight = 0;
}
final int maxTextWidth;
if (mShowText) {
maxTextWidth = Math.max(mOnLayout.getWidth(), mOffLayout.getWidth())
+ mThumbTextPadding * 2;
} else {
maxTextWidth = 0;
}
mThumbWidth = Math.max(maxTextWidth, thumbWidth);
final int trackHeight;
if (mTrackDrawable != null) {
mTrackDrawable.getPadding(padding);
trackHeight = mTrackDrawable.getIntrinsicHeight();
} else {
padding.setEmpty();
trackHeight = 0;
}
// Adjust left and right padding to ensure there's enough room for the
// thumb's padding (when present).
int paddingLeft = padding.left;
int paddingRight = padding.right;
final int switchWidth = Math.max(mSwitchMinWidth,
2 * mThumbWidth + paddingLeft + paddingRight);
final int switchHeight = Math.max(trackHeight, thumbHeight);
mSwitchWidth = switchWidth;
mSwitchHeight = switchHeight;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int measuredHeight = getMeasuredHeight();
if (measuredHeight < switchHeight) {
setMeasuredDimension(ViewCompat.getMeasuredWidthAndState(this), switchHeight);
}
|
public void | onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent event)
super.onPopulateAccessibilityEvent(event);
final CharSequence text = isChecked() ? mTextOn : mTextOff;
if (text != null) {
event.getText().add(text);
}
|
public boolean | onTouchEvent(android.view.MotionEvent ev)
mVelocityTracker.addMovement(ev);
final int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
if (isEnabled() && hitThumb(x, y)) {
mTouchMode = TOUCH_MODE_DOWN;
mTouchX = x;
mTouchY = y;
}
break;
}
case MotionEvent.ACTION_MOVE: {
switch (mTouchMode) {
case TOUCH_MODE_IDLE:
// Didn't target the thumb, treat normally.
break;
case TOUCH_MODE_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
if (Math.abs(x - mTouchX) > mTouchSlop ||
Math.abs(y - mTouchY) > mTouchSlop) {
mTouchMode = TOUCH_MODE_DRAGGING;
getParent().requestDisallowInterceptTouchEvent(true);
mTouchX = x;
mTouchY = y;
return true;
}
break;
}
case TOUCH_MODE_DRAGGING: {
final float x = ev.getX();
final int thumbScrollRange = getThumbScrollRange();
final float thumbScrollOffset = x - mTouchX;
float dPos;
if (thumbScrollRange != 0) {
dPos = thumbScrollOffset / thumbScrollRange;
} else {
// If the thumb scroll range is empty, just use the
// movement direction to snap on or off.
dPos = thumbScrollOffset > 0 ? 1 : -1;
}
if (ViewUtils.isLayoutRtl(this)) {
dPos = -dPos;
}
final float newPos = constrain(mThumbPosition + dPos, 0, 1);
if (newPos != mThumbPosition) {
mTouchX = x;
setThumbPosition(newPos);
}
return true;
}
}
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: {
if (mTouchMode == TOUCH_MODE_DRAGGING) {
stopDrag(ev);
// Allow super class to handle pressed state, etc.
super.onTouchEvent(ev);
return true;
}
mTouchMode = TOUCH_MODE_IDLE;
mVelocityTracker.clear();
break;
}
}
return super.onTouchEvent(ev);
|
public void | setChecked(boolean checked)
super.setChecked(checked);
// Calling the super method may result in setChecked() getting called
// recursively with a different value, so load the REAL value...
checked = isChecked();
if (getWindowToken() != null) {
animateThumbToCheckedState(checked);
} else {
// Immediately move the thumb to the new position.
cancelPositionAnimator();
setThumbPosition(checked ? 1 : 0);
}
|
public void | setShowText(boolean showText)Sets whether the on/off text should be displayed.
if (mShowText != showText) {
mShowText = showText;
requestLayout();
}
|
public void | setSplitTrack(boolean splitTrack)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.
mSplitTrack = splitTrack;
invalidate();
|
public void | setSwitchMinWidth(int pixels)Set the minimum width of the switch in pixels. The switch's width will be the maximum
of this value and its measured width as determined by the switch drawables and text used.
mSwitchMinWidth = pixels;
requestLayout();
|
public void | setSwitchPadding(int pixels)Set the amount of horizontal padding between the switch and the associated text.
mSwitchPadding = pixels;
requestLayout();
|
public void | setSwitchTextAppearance(android.content.Context context, int resid)Sets the switch text color, size, style, hint color, and highlight color
from the specified TextAppearance resource.
TypedArray appearance = context.obtainStyledAttributes(resid,
R.styleable.SwitchCompatTextAppearance);
ColorStateList colors;
int ts;
colors = appearance.getColorStateList(
R.styleable.SwitchCompatTextAppearance_android_textColor);
if (colors != null) {
mTextColors = colors;
} else {
// If no color set in TextAppearance, default to the view's textColor
mTextColors = getTextColors();
}
ts = appearance.getDimensionPixelSize(
R.styleable.SwitchCompatTextAppearance_android_textSize, 0);
if (ts != 0) {
if (ts != mTextPaint.getTextSize()) {
mTextPaint.setTextSize(ts);
requestLayout();
}
}
boolean allCaps = appearance.getBoolean(
R.styleable.SwitchCompatTextAppearance_textAllCaps, false);
if (allCaps) {
mSwitchTransformationMethod = new AllCapsTransformationMethod(getContext());
} else {
mSwitchTransformationMethod = null;
}
appearance.recycle();
|
public void | setSwitchTypeface(android.graphics.Typeface tf, int style)Sets the typeface and style in which the text should be displayed on the
switch, and turns on the fake bold and italic bits in the Paint if the
Typeface that you provided does not have all the bits in the
style that you specified.
if (style > 0) {
if (tf == null) {
tf = Typeface.defaultFromStyle(style);
} else {
tf = Typeface.create(tf, style);
}
setSwitchTypeface(tf);
// now compute what (if any) algorithmic styling is needed
int typefaceStyle = tf != null ? tf.getStyle() : 0;
int need = style & ~typefaceStyle;
mTextPaint.setFakeBoldText((need & Typeface.BOLD) != 0);
mTextPaint.setTextSkewX((need & Typeface.ITALIC) != 0 ? -0.25f : 0);
} else {
mTextPaint.setFakeBoldText(false);
mTextPaint.setTextSkewX(0);
setSwitchTypeface(tf);
}
|
public void | setSwitchTypeface(android.graphics.Typeface tf)Sets the typeface in which the text should be displayed on the switch.
Note that not all Typeface families actually have bold and italic
variants, so you may need to use
{@link #setSwitchTypeface(Typeface, int)} to get the appearance
that you actually want.
if (mTextPaint.getTypeface() != tf) {
mTextPaint.setTypeface(tf);
requestLayout();
invalidate();
}
|
public void | setTextOff(java.lang.CharSequence textOff)Sets the text displayed when the button is not in the checked state.
mTextOff = textOff;
requestLayout();
|
public void | setTextOn(java.lang.CharSequence textOn)Sets the text displayed when the button is in the checked state.
mTextOn = textOn;
requestLayout();
|
public void | setThumbDrawable(android.graphics.drawable.Drawable thumb)Set the drawable used for the switch "thumb" - the piece that the user
can physically touch and drag along the track.
mThumbDrawable = thumb;
requestLayout();
|
private void | setThumbPosition(float position)Sets the thumb position as a decimal value between 0 (off) and 1 (on).
mThumbPosition = position;
invalidate();
|
public void | setThumbResource(int resId)Set the drawable used for the switch "thumb" - the piece that the user
can physically touch and drag along the track.
setThumbDrawable(mTintManager.getDrawable(resId));
|
public void | setThumbTextPadding(int pixels)Set the horizontal padding around the text drawn on the switch itself.
mThumbTextPadding = pixels;
requestLayout();
|
public void | setTrackDrawable(android.graphics.drawable.Drawable track)Set the drawable used for the track that the switch slides within.
mTrackDrawable = track;
requestLayout();
|
public void | setTrackResource(int resId)Set the drawable used for the track that the switch slides within.
setTrackDrawable(mTintManager.getDrawable(resId));
|
private void | stopDrag(android.view.MotionEvent ev)Called from onTouchEvent to end a drag operation.
mTouchMode = TOUCH_MODE_IDLE;
// Commit the change if the event is up and not canceled and the switch
// has not been disabled during the drag.
final boolean commitChange = ev.getAction() == MotionEvent.ACTION_UP && isEnabled();
final boolean oldState = isChecked();
final boolean newState;
if (commitChange) {
mVelocityTracker.computeCurrentVelocity(1000);
final float xvel = mVelocityTracker.getXVelocity();
if (Math.abs(xvel) > mMinFlingVelocity) {
newState = ViewUtils.isLayoutRtl(this) ? (xvel < 0) : (xvel > 0);
} else {
newState = getTargetCheckedState();
}
} else {
newState = oldState;
}
if (newState != oldState) {
playSoundEffect(SoundEffectConstants.CLICK);
setChecked(newState);
}
cancelSuperTouch(ev);
|
public void | toggle()
setChecked(!isChecked());
|
protected boolean | verifyDrawable(android.graphics.drawable.Drawable who)
return super.verifyDrawable(who) || who == mThumbDrawable || who == mTrackDrawable;
|