Last active
October 26, 2020 16:04
-
-
Save se-bastiaan/bb1d2e1d2b528a4971c2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<declare-styleable name="Switch"> | |
<!-- Drawable to use as the "thumb" that switches back and forth. --> | |
<attr name="thumb" format="reference" /> | |
<!-- Drawable to use as the "track" that the switch thumb slides within. --> | |
<attr name="track" format="reference" /> | |
<!-- Text to use when the switch is in the checked/"on" state. --> | |
<attr name="textOn" format="reference" /> | |
<!-- Text to use when the switch is in the unchecked/"off" state. --> | |
<attr name="textOff" format="reference" /> | |
<!-- Amount of padding on either side of text within the switch thumb. --> | |
<attr name="thumbTextPadding" format="dimension" /> | |
<!-- TextAppearance style for text displayed on the switch thumb. --> | |
<attr name="switchTextAppearance" format="reference" /> | |
<!-- Minimum width for the switch component --> | |
<attr name="switchMinWidth" format="dimension" /> | |
<!-- Minimum space between the switch and caption text --> | |
<attr name="switchPadding" format="dimension" /> | |
<attr name="trackLeft" format="reference" /> | |
<attr name="trackRight" format="reference" /> | |
</declare-styleable> | |
<declare-styleable name="AppTheme"> | |
<attr name="customSwitchStyle" format="reference" /> | |
</declare-styleable> | |
<declare-styleable name="Android"> | |
<!-- Text color. --> | |
<attr name="android:textColor" /> | |
<!-- Size of the text. Recommended dimension type for text is "sp" for scaled-pixels (example: 15sp). --> | |
<attr name="android:textSize" /> | |
<!-- Style (bold, italic, bolditalic) for the text. --> | |
<attr name="android:textStyle" /> | |
<!-- Typeface (normal, sans, serif, monospace) for the text. --> | |
<attr name="android:typeface" /> | |
<!-- Color of the text selection highlight. --> | |
<attr name="android:textColorHighlight" /> | |
<!-- Color of the hint text. --> | |
<attr name="android:textColorHint" /> | |
<!-- Color of the links. --> | |
<attr name="android:textColorLink" /> | |
</declare-styleable> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* | |
* Copyright (C) 2013 Sébastiaan Versteeg ([email protected]) | |
* Copyright (C) 2012 Benoit 'BoD' Lubek ([email protected]) | |
* Copyright (C) 2010 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. | |
*/ | |
package eu.se_bastiaan.app.widget; | |
import android.annotation.TargetApi; | |
import android.content.Context; | |
import android.content.res.ColorStateList; | |
import android.content.res.Resources; | |
import android.content.res.TypedArray; | |
import android.graphics.Canvas; | |
import android.graphics.Color; | |
import android.graphics.Paint; | |
import android.graphics.Rect; | |
import android.graphics.RectF; | |
import android.graphics.Typeface; | |
import android.graphics.drawable.Drawable; | |
import android.os.Build; | |
import android.text.Layout; | |
import android.text.StaticLayout; | |
import android.text.TextPaint; | |
import android.text.TextUtils; | |
import android.util.AttributeSet; | |
import android.view.Gravity; | |
import android.view.MotionEvent; | |
import android.view.VelocityTracker; | |
import android.view.View; | |
import android.view.ViewConfiguration; | |
import android.widget.CompoundButton; | |
import eu.se_bastiaan.app.R; | |
/** | |
* A Switch is a two-state toggle switch widget that can select between two | |
* options. The user may drag the "thumb" back and forth to choose the selected option, | |
* or simply tap to toggle as if it were a checkbox. The {@link #setText(CharSequence) text} property controls the text displayed in the label for the switch, | |
* whereas the {@link #setTextOff(CharSequence) off} and {@link #setTextOn(CharSequence) on} text | |
* controls the text on the thumb. Similarly, the {@link #setTextAppearance(android.content.Context, int) textAppearance} and the related | |
* setTypeface() methods control the typeface and style of label text, whereas the {@link #setSwitchTextAppearance(android.content.Context, int) | |
* switchTextAppearance} and | |
* the related seSwitchTypeface() methods control that of the thumb. | |
* | |
*/ | |
public class Switch extends CompoundButton { | |
private static final int TOUCH_MODE_IDLE = 0; | |
private static final int TOUCH_MODE_DOWN = 1; | |
private static final int TOUCH_MODE_DRAGGING = 2; | |
// Enum for the "typeface" XML parameter. | |
private static final int SANS = 1; | |
private static final int SERIF = 2; | |
private static final int MONOSPACE = 3; | |
private final Drawable mThumbDrawable; | |
private final int mLeftTrackColor; | |
private final int mRightTrackColor; | |
private final int mThumbTextPadding; | |
private final int mSwitchMinWidth; | |
private final int mSwitchPadding; | |
private CharSequence mTextOn; | |
private CharSequence mTextOff; | |
private int mTouchMode; | |
private final int mTouchSlop; | |
private float mTouchX; | |
private float mTouchY; | |
private final VelocityTracker mVelocityTracker = VelocityTracker.obtain(); | |
private final int mMinFlingVelocity; | |
private float mThumbPosition; | |
private int mSwitchWidth; | |
private int mSwitchHeight; | |
private int mThumbWidth; // Does not include padding | |
private int mSwitchLeft; | |
private int mSwitchTop; | |
private int mSwitchRight; | |
private int mSwitchBottom; | |
private final TextPaint mTextPaint; | |
private ColorStateList mTextColors; | |
private Layout mOnLayout; | |
private Layout mOffLayout; | |
private final Rect mTempRect = new Rect(); | |
private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked }; | |
private OnClickListener mOnClickListener; | |
/** | |
* Construct a new Switch with default styling. | |
* | |
* @param context The Context that will determine this widget's theming. | |
*/ | |
public Switch(Context context) { | |
this(context, null); | |
} | |
/** | |
* Construct a new Switch with default styling, overriding specific style | |
* attributes as requested. | |
* | |
* @param context The Context that will determine this widget's theming. | |
* @param attrs Specification of attributes that should deviate from default styling. | |
*/ | |
public Switch(Context context, AttributeSet attrs) { | |
this(context, attrs, R.attr.customSwitchStyle); | |
} | |
/** | |
* Construct a new Switch with a default style determined by the given theme attribute, | |
* overriding specific style attributes as requested. | |
* | |
* @param context The Context that will determine this widget's theming. | |
* @param attrs Specification of attributes that should deviate from the default styling. | |
* @param defStyle An attribute ID within the active theme containing a reference to the | |
* default style for this widget. e.g. android.R.attr.switchStyle. | |
*/ | |
public Switch(Context context, AttributeSet attrs, int defStyle) { | |
super(context, attrs, defStyle); | |
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); | |
final Resources res = getResources(); | |
mTextPaint.density = res.getDisplayMetrics().density; | |
// XXX Was on the Android source, but had to comment it out (doesn't exist in 2.1). -- BoD | |
// mTextPaint.setCompatibilityScaling(res.getCompatibilityInfo().applicationScale); | |
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Switch, defStyle, 0); | |
mThumbDrawable = a.getDrawable(R.styleable.Switch_thumb); | |
mRightTrackColor = a.getColor(R.styleable.Switch_trackRight, Color.BLACK); | |
mLeftTrackColor = a.getColor(R.styleable.Switch_trackLeft, Color.GRAY); | |
mTextOn = a.getText(R.styleable.Switch_textOn); | |
mTextOff = a.getText(R.styleable.Switch_textOff); | |
mThumbTextPadding = a.getDimensionPixelSize(R.styleable.Switch_thumbTextPadding, 0); | |
mSwitchMinWidth = a.getDimensionPixelSize(R.styleable.Switch_switchMinWidth, 0); | |
mSwitchPadding = a.getDimensionPixelSize(R.styleable.Switch_switchPadding, 0); | |
final int appearance = a.getResourceId(R.styleable.Switch_switchTextAppearance, 0); | |
if (appearance != 0) { | |
setSwitchTextAppearance(context, appearance); | |
} | |
a.recycle(); | |
final ViewConfiguration config = ViewConfiguration.get(context); | |
mTouchSlop = config.getScaledTouchSlop(); | |
mMinFlingVelocity = config.getScaledMinimumFlingVelocity(); | |
// Refresh display with current params | |
refreshDrawableState(); | |
setChecked(isChecked()); | |
if(!isInEditMode()) { | |
Typeface tf = Typeface.createFromAsset(context.getAssets(), "fonts/museo500.otf"); | |
setSwitchTypeface(tf); | |
} | |
} | |
/** | |
* Sets the switch text color, size, style, hint color, and highlight color | |
* from the specified TextAppearance resource. | |
*/ | |
public void setSwitchTextAppearance(Context context, int resid) { | |
final TypedArray appearance = context.obtainStyledAttributes(resid, R.styleable.Android); | |
ColorStateList colors; | |
int ts; | |
colors = appearance.getColorStateList(R.styleable.Android_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.Android_android_textSize, 0); | |
if (ts != 0) { | |
if (ts != mTextPaint.getTextSize()) { | |
mTextPaint.setTextSize(ts); | |
requestLayout(); | |
} | |
} | |
int typefaceIndex, styleIndex; | |
typefaceIndex = appearance.getInt(R.styleable.Android_android_typeface, -1); | |
styleIndex = appearance.getInt(R.styleable.Android_android_textStyle, -1); | |
setSwitchTypefaceByIndex(typefaceIndex, styleIndex); | |
appearance.recycle(); | |
} | |
private void setSwitchTypefaceByIndex(int typefaceIndex, int styleIndex) { | |
Typeface tf = null; | |
switch (typefaceIndex) { | |
case SANS: | |
tf = Typeface.SANS_SERIF; | |
break; | |
case SERIF: | |
tf = Typeface.SERIF; | |
break; | |
case MONOSPACE: | |
tf = Typeface.MONOSPACE; | |
break; | |
} | |
setSwitchTypeface(tf, styleIndex); | |
} | |
/** | |
* 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. | |
*/ | |
public void setSwitchTypeface(Typeface tf, int style) { | |
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 | |
final int typefaceStyle = tf != null ? tf.getStyle() : 0; | |
final 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); | |
} | |
} | |
/** | |
* 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. | |
* | |
* @attr ref android.R.styleable#TextView_typeface | |
* @attr ref android.R.styleable#TextView_textStyle | |
*/ | |
public void setSwitchTypeface(Typeface tf) { | |
if (mTextPaint.getTypeface() != tf) { | |
mTextPaint.setTypeface(tf); | |
requestLayout(); | |
invalidate(); | |
} | |
} | |
/** | |
* Returns the text displayed when the button is in the checked state. | |
*/ | |
public CharSequence getTextOn() { | |
return mTextOn; | |
} | |
/** | |
* Sets the text displayed when the button is in the checked state. | |
*/ | |
public void setTextOn(CharSequence textOn) { | |
mTextOn = textOn; | |
requestLayout(); | |
} | |
/** | |
* Returns the text displayed when the button is not in the checked state. | |
*/ | |
public CharSequence getTextOff() { | |
return mTextOff; | |
} | |
/** | |
* Sets the text displayed when the button is not in the checked state. | |
*/ | |
public void setTextOff(CharSequence textOff) { | |
mTextOff = textOff; | |
requestLayout(); | |
} | |
@Override | |
@TargetApi(Build.VERSION_CODES.HONEYCOMB) | |
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
View.MeasureSpec.getMode(widthMeasureSpec); | |
if (mOnLayout == null) { | |
mOnLayout = makeLayout(mTextOn); | |
} | |
if (mOffLayout == null) { | |
mOffLayout = makeLayout(mTextOff); | |
} | |
final int switchWidth = View.MeasureSpec.getSize(widthMeasureSpec); | |
final int switchHeight = View.MeasureSpec.getSize(heightMeasureSpec); | |
mThumbWidth = View.MeasureSpec.getSize(heightMeasureSpec); | |
mSwitchWidth = switchWidth; | |
mSwitchHeight = switchHeight; | |
super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
final int measuredHeight = getMeasuredHeight(); | |
if (measuredHeight < switchHeight) { | |
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { | |
setMeasuredDimension(getMeasuredWidth(), switchHeight); | |
} | |
else { | |
setMeasuredDimension(getMeasuredWidthAndState(), switchHeight); | |
} | |
} | |
} | |
// XXX Was on the Android source, but had to comment it out (doesn't exist in 2.1). -- BoD | |
// @Override | |
// public void onPopulateAccessibilityEvent(AccessibilityEvent event) { | |
// super.onPopulateAccessibilityEvent(event); | |
// if (isChecked()) { | |
// CharSequence text = mOnLayout.getText(); | |
// if (TextUtils.isEmpty(text)) { | |
// text = getContext().getString(R.string.switch_on); | |
// } | |
// event.getText().add(text); | |
// } else { | |
// CharSequence text = mOffLayout.getText(); | |
// if (TextUtils.isEmpty(text)) { | |
// text = getContext().getString(R.string.switch_off); | |
// } | |
// event.getText().add(text); | |
// } | |
// } | |
private Layout makeLayout(CharSequence text) { | |
return new StaticLayout(text, mTextPaint, (int) Math.ceil(Layout.getDesiredWidth(text, mTextPaint)), Layout.Alignment.ALIGN_NORMAL, 1.f, 0, true); | |
} | |
/** | |
* @return true if (x, y) is within the target area of the switch thumb | |
*/ | |
private boolean hitThumb(float x, float y) { | |
final int thumbTop = mSwitchTop - mTouchSlop; | |
final int thumbLeft = mSwitchLeft + (int) (mThumbPosition + 0.5f) - mTouchSlop; | |
final int thumbRight = thumbLeft + mThumbWidth + mTouchSlop; | |
final int thumbBottom = mSwitchBottom + mTouchSlop; | |
return x > thumbLeft && x < thumbRight && y > thumbTop && y < thumbBottom; | |
} | |
@Override | |
public boolean onTouchEvent(MotionEvent ev) { | |
mVelocityTracker.addMovement(ev); | |
final int action; | |
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) | |
action = ev.getAction(); | |
else | |
action = ev.getActionMasked(); | |
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 float dx = x - mTouchX; | |
final float newPos = Math.max(0, Math.min(mThumbPosition + dx, getThumbScrollRange())); | |
if (newPos != mThumbPosition) { | |
mThumbPosition = newPos; | |
mTouchX = x; | |
invalidate(); | |
} | |
return true; | |
} | |
} | |
break; | |
} | |
case MotionEvent.ACTION_UP: | |
case MotionEvent.ACTION_CANCEL: { | |
if (mTouchMode == TOUCH_MODE_DRAGGING) { | |
stopDrag(ev); | |
return true; | |
} | |
mTouchMode = TOUCH_MODE_IDLE; | |
mVelocityTracker.clear(); | |
break; | |
} | |
} | |
return super.onTouchEvent(ev); | |
} | |
private void cancelSuperTouch(MotionEvent ev) { | |
final MotionEvent cancel = MotionEvent.obtain(ev); | |
cancel.setAction(MotionEvent.ACTION_CANCEL); | |
super.onTouchEvent(cancel); | |
cancel.recycle(); | |
} | |
/** | |
* Called from onTouchEvent to end a drag operation. | |
* | |
* @param ev Event that triggered the end of drag mode - ACTION_UP or ACTION_CANCEL | |
*/ | |
private void stopDrag(MotionEvent ev) { | |
mTouchMode = TOUCH_MODE_IDLE; | |
// Up and not canceled, also checks the switch has not been disabled during the drag | |
final boolean commitChange = ev.getAction() == MotionEvent.ACTION_UP && isEnabled(); | |
cancelSuperTouch(ev); | |
if (commitChange) { | |
boolean newState; | |
mVelocityTracker.computeCurrentVelocity(1000); | |
final float xvel = mVelocityTracker.getXVelocity(); | |
if (Math.abs(xvel) > mMinFlingVelocity) { | |
newState = xvel > 0; | |
} else { | |
newState = getTargetCheckedState(); | |
} | |
animateThumbToCheckedState(newState); | |
} else { | |
animateThumbToCheckedState(isChecked()); | |
} | |
} | |
private void animateThumbToCheckedState(boolean newCheckedState) { | |
try | |
{ | |
float f1 = this.mThumbPosition; | |
float f2 = 0; | |
if(newCheckedState) f2 = getThumbScrollRange(); | |
SwitchAnimate.slideAnimate(this, f1, f2, 300); | |
super.setChecked(newCheckedState); | |
return; | |
} | |
catch (NoClassDefFoundError localNoClassDefFoundError) | |
{ | |
setChecked(newCheckedState); | |
} | |
} | |
public void setThumbPosition(float paramFloat) | |
{ | |
mThumbPosition = paramFloat; | |
invalidate(); | |
} | |
private boolean getTargetCheckedState() { | |
return mThumbPosition >= getThumbScrollRange() / 2; | |
} | |
@Override | |
public void setChecked(boolean checked) { | |
super.setChecked(checked); | |
mThumbPosition = checked ? getThumbScrollRange() : 0; | |
invalidate(); | |
} | |
@Override | |
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { | |
super.onLayout(changed, left, top, right, bottom); | |
mThumbPosition = isChecked() ? getThumbScrollRange() : 0; | |
final int switchRight = getWidth() - getPaddingRight(); | |
final int switchLeft = switchRight - mSwitchWidth; | |
int switchTop = 0; | |
int switchBottom = 0; | |
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; | |
} | |
@Override | |
protected void onDraw(Canvas paramCanvas) { | |
int switchLeft = mSwitchLeft; | |
int switchTop = mSwitchTop; | |
int switchRight = mSwitchRight; | |
int switchBottom = mSwitchBottom; | |
int borderRadius = mSwitchHeight / 2; | |
if(mSwitchWidth < mSwitchHeight) { | |
borderRadius = mSwitchWidth / 2; | |
} | |
int n = (int)(0.5F + mThumbPosition); | |
int thumbLeft = switchLeft + n; | |
int thumbCenterRight = switchLeft + n + mThumbWidth; | |
int thumbRight = thumbLeft + mThumbWidth; | |
int thumbCenter = thumbLeft + mThumbWidth / 2; | |
int textAlpha = (int) (255.0F * ((double)thumbCenter / (double)mSwitchWidth)); | |
if (mTextColors != null) mTextPaint.setColor(mTextColors.getColorForState(getDrawableState(), mTextColors.getDefaultColor())); | |
mTextPaint.drawableState = getDrawableState(); | |
Paint paint = new Paint(); | |
paint.setColor(mLeftTrackColor); | |
paint.setAntiAlias(true); | |
paramCanvas.drawRoundRect(new RectF(switchLeft, switchTop, thumbRight, switchBottom), borderRadius, borderRadius, paint); | |
paramCanvas.save(); | |
getTextOn(); | |
mTextPaint.setAlpha(textAlpha); | |
int textWidth = mSwitchWidth - mThumbWidth; | |
int textLeft = -(mSwitchWidth - thumbRight) + (textWidth - mOnLayout.getWidth()) / 2; | |
int textTop = mSwitchHeight / 2 - mOnLayout.getHeight() / 2; | |
paramCanvas.translate(textLeft, textTop); | |
mOnLayout.draw(paramCanvas); | |
paramCanvas.restore(); | |
paint = new Paint(); | |
paint.setColor(mRightTrackColor); | |
paint.setAntiAlias(true); | |
paramCanvas.drawRoundRect(new RectF(thumbLeft, switchTop, switchRight, switchBottom), borderRadius, borderRadius, paint); | |
paramCanvas.save(); | |
getTextOff(); | |
mTextPaint.setAlpha(255 - textAlpha); | |
int textRight = thumbLeft + (textWidth - mOffLayout.getWidth()) / 2 + mThumbWidth; | |
paramCanvas.translate(textRight, textTop); | |
mOffLayout.draw(paramCanvas); | |
paramCanvas.restore(); | |
paramCanvas.clipRect(switchLeft, switchTop, switchRight, switchBottom); | |
mThumbDrawable.setBounds(thumbLeft, switchTop, thumbCenterRight, switchBottom); | |
mThumbDrawable.draw(paramCanvas); | |
paramCanvas.restore(); | |
} | |
@Override | |
public int getCompoundPaddingRight() { | |
int padding = super.getCompoundPaddingRight() + mSwitchWidth; | |
if (!TextUtils.isEmpty(getText())) { | |
padding += mSwitchPadding; | |
} | |
return padding; | |
} | |
private int getThumbScrollRange() { | |
return mSwitchWidth - mThumbWidth; | |
} | |
@Override | |
protected int[] onCreateDrawableState(int extraSpace) { | |
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); | |
if (isChecked()) { | |
mergeDrawableStates(drawableState, CHECKED_STATE_SET); | |
} | |
return drawableState; | |
} | |
@Override | |
protected void drawableStateChanged() { | |
super.drawableStateChanged(); | |
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); | |
invalidate(); | |
} | |
@Override | |
protected boolean verifyDrawable(Drawable who) { | |
return (super.verifyDrawable(who)) || (who == this.mThumbDrawable); | |
} | |
public void setOnClickListener(OnClickListener onClickListener) { | |
mOnClickListener = onClickListener; | |
} | |
public boolean performClick() | |
{ | |
try | |
{ | |
if (!SwitchAnimate.isAnimating) | |
{ | |
if(isEnabled()) { | |
if(isChecked()) { | |
int i = getThumbScrollRange(); | |
SwitchAnimate.indicateSlidableAnimation(this, i, i - 30, 300); | |
} else { | |
SwitchAnimate.indicateSlidableAnimation(this, 0, 30, 300); | |
} | |
if(mOnClickListener != null) mOnClickListener.onClick(this); | |
} | |
} | |
} | |
catch (NoClassDefFoundError localNoClassDefFoundError) | |
{ | |
} | |
return true; | |
} | |
// XXX Was on the Android source, but had to comment it out (doesn't exist in 2.1). -- BoD | |
// @Override | |
// public void jumpDrawablesToCurrentState() { | |
// super.jumpDrawablesToCurrentState(); | |
// mThumbDrawable.jumpToCurrentState(); | |
// mTrackDrawable.jumpToCurrentState(); | |
// } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style name="Custom.Switch" parent="android:Widget.CompoundButton"> | |
<item name="thumb">@drawable/slider_selector</item> | |
<item name="trackLeft">@color/slider_background_left</item> | |
<item name="trackRight">@color/slider_background_right</item> | |
<item name="switchTextAppearance">@style/Custom.Switch.TextAppearance</item> | |
<item name="textOn">@string/on</item> | |
<item name="textOff">@string/off</item> | |
<item name="thumbTextPadding">4.0dip</item> | |
<item name="switchMinWidth">96dip</item> | |
<item name="switchPadding">0.0dip</item> | |
</style> | |
<style name="Custom.Switch.TextAppearance" parent="android:TextAppearance.Small"> | |
<item name="android:textColor">@color/switch_dim_foreground</item> | |
<item name="android:textSize">13dp</item> | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment