112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell/* 212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Copyright (C) 2010 The Android Open Source Project 312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * you may not use this file except in compliance with the License. 612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * You may obtain a copy of the License at 712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * http://www.apache.org/licenses/LICENSE-2.0 912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 1012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Unless required by applicable law or agreed to in writing, software 1112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * distributed under the License is distributed on an "AS IS" BASIS, 1212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * See the License for the specific language governing permissions and 1412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * limitations under the License. 1512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 1612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 1712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellpackage android.widget; 1812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 19cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viveretteimport android.animation.ObjectAnimator; 2012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.content.Context; 2112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.content.res.ColorStateList; 2212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.content.res.Resources; 2312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.content.res.TypedArray; 2412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.graphics.Canvas; 25661e63658da39cccfe49a129e4860455716ff3c9Alan Viveretteimport android.graphics.Insets; 2612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.graphics.Paint; 2712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.graphics.Rect; 2812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.graphics.Typeface; 29661e63658da39cccfe49a129e4860455716ff3c9Alan Viveretteimport android.graphics.Region.Op; 3012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.graphics.drawable.Drawable; 3112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.text.Layout; 3212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.text.StaticLayout; 3312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.text.TextPaint; 3412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.text.TextUtils; 354c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandlerimport android.text.method.AllCapsTransformationMethod; 364c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandlerimport android.text.method.TransformationMethod2; 3712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.util.AttributeSet; 38cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viveretteimport android.util.FloatProperty; 39cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viveretteimport android.util.MathUtils; 4012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.view.Gravity; 4112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.view.MotionEvent; 42d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viveretteimport android.view.SoundEffectConstants; 4312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.view.VelocityTracker; 4412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.view.ViewConfiguration; 4563bce03cc69be4a45230aa8bbd89dbde60681067Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 468a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo; 4712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 48be0a4535053bbfdebd215e244b154ac810fd8edcAdam Powellimport com.android.internal.R; 49be0a4535053bbfdebd215e244b154ac810fd8edcAdam Powell 5012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell/** 5112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * A Switch is a two-state toggle switch widget that can select between two 5212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * options. The user may drag the "thumb" back and forth to choose the selected option, 53150176d83023e3c486dba10edebb72af36b4099aChet Haase * or simply tap to toggle as if it were a checkbox. The {@link #setText(CharSequence) text} 54150176d83023e3c486dba10edebb72af36b4099aChet Haase * property controls the text displayed in the label for the switch, whereas the 55150176d83023e3c486dba10edebb72af36b4099aChet Haase * {@link #setTextOff(CharSequence) off} and {@link #setTextOn(CharSequence) on} text 56150176d83023e3c486dba10edebb72af36b4099aChet Haase * controls the text on the thumb. Similarly, the 57150176d83023e3c486dba10edebb72af36b4099aChet Haase * {@link #setTextAppearance(android.content.Context, int) textAppearance} and the related 58150176d83023e3c486dba10edebb72af36b4099aChet Haase * setTypeface() methods control the typeface and style of label text, whereas the 59150176d83023e3c486dba10edebb72af36b4099aChet Haase * {@link #setSwitchTextAppearance(android.content.Context, int) switchTextAppearance} and 60150176d83023e3c486dba10edebb72af36b4099aChet Haase * the related seSwitchTypeface() methods control that of the thumb. 6112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 624c359b76f9a030f92a302ba74a528faa170bad4eScott Main * <p>See the <a href="{@docRoot}guide/topics/ui/controls/togglebutton.html">Toggle Buttons</a> 634c359b76f9a030f92a302ba74a528faa170bad4eScott Main * guide.</p> 644c359b76f9a030f92a302ba74a528faa170bad4eScott Main * 654c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_textOn 664c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_textOff 674c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_switchMinWidth 684c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_switchPadding 694c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_switchTextAppearance 704c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_thumb 714c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_thumbTextPadding 724c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_track 7312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 7412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellpublic class Switch extends CompoundButton { 75cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette private static final int THUMB_ANIMATION_DURATION = 250; 76cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette 7712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int TOUCH_MODE_IDLE = 0; 7812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int TOUCH_MODE_DOWN = 1; 7912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int TOUCH_MODE_DRAGGING = 2; 8012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 8112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell // Enum for the "typeface" XML parameter. 8212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int SANS = 1; 8312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int SERIF = 2; 8412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int MONOSPACE = 3; 8512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 8612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private Drawable mThumbDrawable; 8712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private Drawable mTrackDrawable; 8812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mThumbTextPadding; 8912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchMinWidth; 9012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchPadding; 91661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette private boolean mSplitTrack; 9212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private CharSequence mTextOn; 9312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private CharSequence mTextOff; 942a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette private boolean mShowText; 9512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 9612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mTouchMode; 9712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mTouchSlop; 9812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private float mTouchX; 9912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private float mTouchY; 10012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private VelocityTracker mVelocityTracker = VelocityTracker.obtain(); 10112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mMinFlingVelocity; 10212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 10312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private float mThumbPosition; 1040c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 1050c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette /** 1060c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette * Width required to draw the switch track and thumb. Includes padding and 1070c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette * optical bounds for both the track and thumb. 1080c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette */ 10912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchWidth; 1100c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 1110c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette /** 1120c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette * Height required to draw the switch track and thumb. Includes padding and 1130c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette * optical bounds for both the track and thumb. 1140c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette */ 11512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchHeight; 11612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 1170c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette /** 1180c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette * Width of the thumb's content region. Does not include padding or 1190c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette * optical bounds. 1200c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette */ 1210c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette private int mThumbWidth; 1220c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 1230c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette /** Left bound for drawing the switch track and thumb. */ 12412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchLeft; 1250c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 1260c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette /** Top bound for drawing the switch track and thumb. */ 12712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchTop; 1280c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 1290c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette /** Right bound for drawing the switch track and thumb. */ 13012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchRight; 1310c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 1320c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette /** Bottom bound for drawing the switch track and thumb. */ 13312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchBottom; 13412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 13512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private TextPaint mTextPaint; 13612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private ColorStateList mTextColors; 13712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private Layout mOnLayout; 13812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private Layout mOffLayout; 1394c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler private TransformationMethod2 mSwitchTransformationMethod; 140cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette private ObjectAnimator mPositionAnimator; 14112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 142be0a4535053bbfdebd215e244b154ac810fd8edcAdam Powell @SuppressWarnings("hiding") 14312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private final Rect mTempRect = new Rect(); 14412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 14512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int[] CHECKED_STATE_SET = { 14612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell R.attr.state_checked 14712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell }; 14812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 14912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 15012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Construct a new Switch with default styling. 15112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 15212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @param context The Context that will determine this widget's theming. 15312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 15412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public Switch(Context context) { 15512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell this(context, null); 15612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 15712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 15812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 15912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Construct a new Switch with default styling, overriding specific style 16012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * attributes as requested. 16112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 16212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @param context The Context that will determine this widget's theming. 16312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @param attrs Specification of attributes that should deviate from default styling. 16412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 16512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public Switch(Context context, AttributeSet attrs) { 16612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell this(context, attrs, com.android.internal.R.attr.switchStyle); 16712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 16812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 16912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 17012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Construct a new Switch with a default style determined by the given theme attribute, 17112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * overriding specific style attributes as requested. 17212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 17312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @param context The Context that will determine this widget's theming. 17412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @param attrs Specification of attributes that should deviate from the default styling. 175617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param defStyleAttr An attribute in the current theme that contains a 176617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * reference to a style resource that supplies default values for 177617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * the view. Can be 0 to not look for defaults. 17812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 179617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public Switch(Context context, AttributeSet attrs, int defStyleAttr) { 180617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette this(context, attrs, defStyleAttr, 0); 181617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette } 182617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette 183617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette 184617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette /** 185617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * Construct a new Switch with a default style determined by the given theme 186617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * attribute or style resource, overriding specific style attributes as 187617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * requested. 188617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * 189617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param context The Context that will determine this widget's theming. 190617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param attrs Specification of attributes that should deviate from the 191617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * default styling. 192617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param defStyleAttr An attribute in the current theme that contains a 193617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * reference to a style resource that supplies default values for 194617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * the view. Can be 0 to not look for defaults. 195617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param defStyleRes A resource identifier of a style resource that 196617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * supplies default values for the view, used only if 197617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * defStyleAttr is 0 or can not be found in the theme. Can be 0 198617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * to not look for defaults. 199617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette */ 200617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public Switch(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 201617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette super(context, attrs, defStyleAttr, defStyleRes); 20212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 20312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); 204661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette 205661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette final Resources res = getResources(); 20612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.density = res.getDisplayMetrics().density; 20712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.setCompatibilityScaling(res.getCompatibilityInfo().applicationScale); 20812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 209617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette final TypedArray a = context.obtainStyledAttributes( 210617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette attrs, com.android.internal.R.styleable.Switch, defStyleAttr, defStyleRes); 211150176d83023e3c486dba10edebb72af36b4099aChet Haase mThumbDrawable = a.getDrawable(com.android.internal.R.styleable.Switch_thumb); 212b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette if (mThumbDrawable != null) { 213b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette mThumbDrawable.setCallback(this); 214b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette } 215150176d83023e3c486dba10edebb72af36b4099aChet Haase mTrackDrawable = a.getDrawable(com.android.internal.R.styleable.Switch_track); 216b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette if (mTrackDrawable != null) { 217b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette mTrackDrawable.setCallback(this); 218b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette } 21912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextOn = a.getText(com.android.internal.R.styleable.Switch_textOn); 22012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextOff = a.getText(com.android.internal.R.styleable.Switch_textOff); 2212a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette mShowText = a.getBoolean(com.android.internal.R.styleable.Switch_showText, true); 22212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mThumbTextPadding = a.getDimensionPixelSize( 22312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell com.android.internal.R.styleable.Switch_thumbTextPadding, 0); 22412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchMinWidth = a.getDimensionPixelSize( 22512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell com.android.internal.R.styleable.Switch_switchMinWidth, 0); 22612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchPadding = a.getDimensionPixelSize( 22712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell com.android.internal.R.styleable.Switch_switchPadding, 0); 228661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette mSplitTrack = a.getBoolean(com.android.internal.R.styleable.Switch_splitTrack, false); 22912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 230661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette final int appearance = a.getResourceId( 23112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell com.android.internal.R.styleable.Switch_switchTextAppearance, 0); 23212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (appearance != 0) { 233150176d83023e3c486dba10edebb72af36b4099aChet Haase setSwitchTextAppearance(context, appearance); 23412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 23512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell a.recycle(); 23612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 237661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette final ViewConfiguration config = ViewConfiguration.get(context); 23812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchSlop = config.getScaledTouchSlop(); 23912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mMinFlingVelocity = config.getScaledMinimumFlingVelocity(); 24012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 24112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell // Refresh display with current params 242e724ee4b04d121556e9764f72f9b921a0e16392aGilles Debunne refreshDrawableState(); 24312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell setChecked(isChecked()); 24412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 24512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 24612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 24712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Sets the switch text color, size, style, hint color, and highlight color 24812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * from the specified TextAppearance resource. 2496c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 2506c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_switchTextAppearance 25112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 252150176d83023e3c486dba10edebb72af36b4099aChet Haase public void setSwitchTextAppearance(Context context, int resid) { 25312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell TypedArray appearance = 254150176d83023e3c486dba10edebb72af36b4099aChet Haase context.obtainStyledAttributes(resid, 25512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell com.android.internal.R.styleable.TextAppearance); 25612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 25712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell ColorStateList colors; 25812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int ts; 25912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 26012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell colors = appearance.getColorStateList(com.android.internal.R.styleable. 26112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell TextAppearance_textColor); 26212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (colors != null) { 26312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextColors = colors; 264150176d83023e3c486dba10edebb72af36b4099aChet Haase } else { 265150176d83023e3c486dba10edebb72af36b4099aChet Haase // If no color set in TextAppearance, default to the view's textColor 266150176d83023e3c486dba10edebb72af36b4099aChet Haase mTextColors = getTextColors(); 26712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 26812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 26912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell ts = appearance.getDimensionPixelSize(com.android.internal.R.styleable. 27012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell TextAppearance_textSize, 0); 27112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (ts != 0) { 27212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (ts != mTextPaint.getTextSize()) { 27312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.setTextSize(ts); 27412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell requestLayout(); 27512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 27612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 27712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 27812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int typefaceIndex, styleIndex; 27912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 28012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell typefaceIndex = appearance.getInt(com.android.internal.R.styleable. 28112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell TextAppearance_typeface, -1); 28212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell styleIndex = appearance.getInt(com.android.internal.R.styleable. 28312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell TextAppearance_textStyle, -1); 28412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 28512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell setSwitchTypefaceByIndex(typefaceIndex, styleIndex); 28612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 2874c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler boolean allCaps = appearance.getBoolean(com.android.internal.R.styleable. 2884c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler TextAppearance_textAllCaps, false); 2894c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler if (allCaps) { 2904c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler mSwitchTransformationMethod = new AllCapsTransformationMethod(getContext()); 2914c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler mSwitchTransformationMethod.setLengthChangesAllowed(true); 2924c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler } else { 2934c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler mSwitchTransformationMethod = null; 2944c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler } 2954c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler 29612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell appearance.recycle(); 29712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 29812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 29912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private void setSwitchTypefaceByIndex(int typefaceIndex, int styleIndex) { 30012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell Typeface tf = null; 30112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switch (typefaceIndex) { 30212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case SANS: 30312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell tf = Typeface.SANS_SERIF; 30412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 30512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 30612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case SERIF: 30712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell tf = Typeface.SERIF; 30812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 30912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 31012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case MONOSPACE: 31112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell tf = Typeface.MONOSPACE; 31212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 31312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 31412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 31512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell setSwitchTypeface(tf, styleIndex); 31612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 31712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 31812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 31912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Sets the typeface and style in which the text should be displayed on the 32012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * switch, and turns on the fake bold and italic bits in the Paint if the 32112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Typeface that you provided does not have all the bits in the 32212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * style that you specified. 32312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 32412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void setSwitchTypeface(Typeface tf, int style) { 32512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (style > 0) { 32612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (tf == null) { 32712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell tf = Typeface.defaultFromStyle(style); 32812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } else { 32912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell tf = Typeface.create(tf, style); 33012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 33112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 33212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell setSwitchTypeface(tf); 33312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell // now compute what (if any) algorithmic styling is needed 33412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int typefaceStyle = tf != null ? tf.getStyle() : 0; 33512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int need = style & ~typefaceStyle; 33612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.setFakeBoldText((need & Typeface.BOLD) != 0); 33712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.setTextSkewX((need & Typeface.ITALIC) != 0 ? -0.25f : 0); 33812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } else { 339aa0980afab57a6aebb06e70f60e92511708fa5afVictoria Lease mTextPaint.setFakeBoldText(false); 34012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.setTextSkewX(0); 34112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell setSwitchTypeface(tf); 34212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 34312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 34412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 34512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 346150176d83023e3c486dba10edebb72af36b4099aChet Haase * Sets the typeface in which the text should be displayed on the switch. 34712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Note that not all Typeface families actually have bold and italic 34812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * variants, so you may need to use 34912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * {@link #setSwitchTypeface(Typeface, int)} to get the appearance 35012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * that you actually want. 35112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 35212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @attr ref android.R.styleable#TextView_typeface 35312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @attr ref android.R.styleable#TextView_textStyle 35412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 35512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void setSwitchTypeface(Typeface tf) { 35612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (mTextPaint.getTypeface() != tf) { 35712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.setTypeface(tf); 35812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 35912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell requestLayout(); 36012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell invalidate(); 36112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 36212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 36312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 36412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 3656c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Set the amount of horizontal padding between the switch and the associated text. 3666c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3676c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @param pixels Amount of padding in pixels 3686c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3696c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_switchPadding 3706c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 3716c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public void setSwitchPadding(int pixels) { 3726c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell mSwitchPadding = pixels; 3736c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell requestLayout(); 3746c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 3756c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 3766c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 3776c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Get the amount of horizontal padding between the switch and the associated text. 3786c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3796c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @return Amount of padding in pixels 3806c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3816c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_switchPadding 3826c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 3836c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public int getSwitchPadding() { 3846c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell return mSwitchPadding; 3856c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 3866c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 3876c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 3886c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Set the minimum width of the switch in pixels. The switch's width will be the maximum 3896c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * of this value and its measured width as determined by the switch drawables and text used. 3906c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3916c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @param pixels Minimum width of the switch in pixels 3926c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3936c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_switchMinWidth 3946c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 3956c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public void setSwitchMinWidth(int pixels) { 3966c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell mSwitchMinWidth = pixels; 3976c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell requestLayout(); 3986c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 3996c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 4006c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 4016c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Get the minimum width of the switch in pixels. The switch's width will be the maximum 4026c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * of this value and its measured width as determined by the switch drawables and text used. 4036c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4046c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @return Minimum width of the switch in pixels 4056c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4066c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_switchMinWidth 4076c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 4086c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public int getSwitchMinWidth() { 4096c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell return mSwitchMinWidth; 4106c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 4116c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 4126c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 4136c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Set the horizontal padding around the text drawn on the switch itself. 4146c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4156c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @param pixels Horizontal padding for switch thumb text in pixels 4166c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4176c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_thumbTextPadding 4186c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 4196c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public void setThumbTextPadding(int pixels) { 4206c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell mThumbTextPadding = pixels; 4216c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell requestLayout(); 4226c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 4236c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 4246c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 4256c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Get the horizontal padding around the text drawn on the switch itself. 4266c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4276c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @return Horizontal padding for switch thumb text in pixels 4286c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4296c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_thumbTextPadding 4306c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 4316c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public int getThumbTextPadding() { 4326c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell return mThumbTextPadding; 4336c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 4346c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 4356c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 4366c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Set the drawable used for the track that the switch slides within. 4376c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4386c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @param track Track drawable 4396c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4406c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_track 4416c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 4426c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public void setTrackDrawable(Drawable track) { 443b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette if (mTrackDrawable != null) { 444b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette mTrackDrawable.setCallback(null); 445b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette } 4466c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell mTrackDrawable = track; 447b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette if (track != null) { 448b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette track.setCallback(this); 449b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette } 4506c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell requestLayout(); 4516c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 4526c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 4536c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 454d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * Set the drawable used for the track that the switch slides within. 455d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * 456dca510e026e3e75759bac84c3860dc84b83a608fAdam Powell * @param resId Resource ID of a track drawable 457d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * 458d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * @attr ref android.R.styleable#Switch_track 459d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell */ 460d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell public void setTrackResource(int resId) { 4618eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette setTrackDrawable(getContext().getDrawable(resId)); 462d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell } 463d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell 464d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell /** 4656c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Get the drawable used for the track that the switch slides within. 4666c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4676c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @return Track drawable 4686c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4696c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_track 4706c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 4716c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public Drawable getTrackDrawable() { 4726c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell return mTrackDrawable; 4736c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 4746c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 4756c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 4766c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Set the drawable used for the switch "thumb" - the piece that the user 4776c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * can physically touch and drag along the track. 4786c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4796c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @param thumb Thumb drawable 4806c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4816c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_thumb 4826c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 4836c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public void setThumbDrawable(Drawable thumb) { 484b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette if (mThumbDrawable != null) { 485b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette mThumbDrawable.setCallback(null); 486b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette } 4876c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell mThumbDrawable = thumb; 488b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette if (thumb != null) { 489b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette thumb.setCallback(this); 490b067405bf453289a6b6bfd34b06700f08be58c24Alan Viverette } 4916c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell requestLayout(); 4926c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 4936c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 4946c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 495d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * Set the drawable used for the switch "thumb" - the piece that the user 496d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * can physically touch and drag along the track. 497d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * 498dca510e026e3e75759bac84c3860dc84b83a608fAdam Powell * @param resId Resource ID of a thumb drawable 499d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * 500d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * @attr ref android.R.styleable#Switch_thumb 501d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell */ 502d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell public void setThumbResource(int resId) { 5038eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette setThumbDrawable(getContext().getDrawable(resId)); 504d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell } 505d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell 506d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell /** 5076c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Get the drawable used for the switch "thumb" - the piece that the user 5086c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * can physically touch and drag along the track. 5096c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 5106c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @return Thumb drawable 5116c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 5126c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_thumb 5136c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 5146c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public Drawable getThumbDrawable() { 5156c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell return mThumbDrawable; 5166c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 5176c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 5186c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 519661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette * Specifies whether the track should be split by the thumb. When true, 520661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette * the thumb's optical bounds will be clipped out of the track drawable, 521661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette * then the thumb will be drawn into the resulting gap. 522661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette * 523661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette * @param splitTrack Whether the track should be split by the thumb 524661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette * 525661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette * @attr ref android.R.styleable#Switch_splitTrack 526661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette */ 527661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette public void setSplitTrack(boolean splitTrack) { 528661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette mSplitTrack = splitTrack; 529661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette invalidate(); 530661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette } 531661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette 532661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette /** 533661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette * Returns whether the track should be split by the thumb. 534661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette * 535661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette * @attr ref android.R.styleable#Switch_splitTrack 536661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette */ 537661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette public boolean getSplitTrack() { 538661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette return mSplitTrack; 539661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette } 540661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette 541661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette /** 542150176d83023e3c486dba10edebb72af36b4099aChet Haase * Returns the text displayed when the button is in the checked state. 5436c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 5446c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_textOn 54512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 54612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public CharSequence getTextOn() { 54712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return mTextOn; 54812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 54912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 55012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 551150176d83023e3c486dba10edebb72af36b4099aChet Haase * Sets the text displayed when the button is in the checked state. 5526c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 5536c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_textOn 55412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 55512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void setTextOn(CharSequence textOn) { 55612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextOn = textOn; 55712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell requestLayout(); 55812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 55912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 56012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 561150176d83023e3c486dba10edebb72af36b4099aChet Haase * Returns the text displayed when the button is not in the checked state. 5626c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 5636c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_textOff 56412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 56512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public CharSequence getTextOff() { 56612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return mTextOff; 56712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 56812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 56912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 570150176d83023e3c486dba10edebb72af36b4099aChet Haase * Sets the text displayed when the button is not in the checked state. 5716c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 5726c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_textOff 57312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 57412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void setTextOff(CharSequence textOff) { 57512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextOff = textOff; 57612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell requestLayout(); 57712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 57812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 5792a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette /** 5802a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette * Sets whether the on/off text should be displayed. 5812a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette * 5822a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette * @param showText {@code true} to display on/off text 5830c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette * @attr ref android.R.styleable#Switch_showText 5842a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette */ 5852a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette public void setShowText(boolean showText) { 5862a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette if (mShowText != showText) { 5872a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette mShowText = showText; 5882a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette requestLayout(); 5892a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette } 5902a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette } 5912a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette 5922a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette /** 5932a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette * @return whether the on/off text should be displayed 5940c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette * @attr ref android.R.styleable#Switch_showText 5952a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette */ 5962a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette public boolean getShowText() { 5972a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette return mShowText; 5982a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette } 5992a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette 60012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 60112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 6022a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette if (mShowText) { 6032a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette if (mOnLayout == null) { 6042a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette mOnLayout = makeLayout(mTextOn); 6052a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette } 6065876ff4a0ac938297bfd114da6b5d8c9dcb4cef6Alan Viverette 6072a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette if (mOffLayout == null) { 6082a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette mOffLayout = makeLayout(mTextOff); 6092a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette } 61012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 61112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 6129b38f6c2cd1d97bb0d1a21e2f9545e02fae851e0Alan Viverette final Rect padding = mTempRect; 6139b38f6c2cd1d97bb0d1a21e2f9545e02fae851e0Alan Viverette final int thumbWidth; 6149b38f6c2cd1d97bb0d1a21e2f9545e02fae851e0Alan Viverette final int thumbHeight; 6158bb399069da4e46b231333cff6880a0cf35b9417Alan Viverette if (mThumbDrawable != null) { 6160c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette // Cached thumb width does not include padding. 6170c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette mThumbDrawable.getPadding(padding); 6180c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette thumbWidth = mThumbDrawable.getIntrinsicWidth() - padding.left - padding.right; 6199b38f6c2cd1d97bb0d1a21e2f9545e02fae851e0Alan Viverette thumbHeight = mThumbDrawable.getIntrinsicHeight(); 6209b38f6c2cd1d97bb0d1a21e2f9545e02fae851e0Alan Viverette } else { 6219b38f6c2cd1d97bb0d1a21e2f9545e02fae851e0Alan Viverette thumbWidth = 0; 6229b38f6c2cd1d97bb0d1a21e2f9545e02fae851e0Alan Viverette thumbHeight = 0; 6238bb399069da4e46b231333cff6880a0cf35b9417Alan Viverette } 6248bb399069da4e46b231333cff6880a0cf35b9417Alan Viverette 6250c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final int maxTextWidth; 6260c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette if (mShowText) { 6270c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette maxTextWidth = Math.max(mOnLayout.getWidth(), mOffLayout.getWidth()) 6280c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette + mThumbTextPadding * 2; 6290c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } else { 6300c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette maxTextWidth = 0; 6310c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } 6320c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 6339b38f6c2cd1d97bb0d1a21e2f9545e02fae851e0Alan Viverette mThumbWidth = Math.max(maxTextWidth, thumbWidth); 6349b38f6c2cd1d97bb0d1a21e2f9545e02fae851e0Alan Viverette 6350c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final int trackHeight; 6360c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette if (mTrackDrawable != null) { 6370c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette mTrackDrawable.getPadding(padding); 6380c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette trackHeight = mTrackDrawable.getIntrinsicHeight(); 6390c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } else { 6400c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette padding.setEmpty(); 6410c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette trackHeight = 0; 6420c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } 6430c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 6440c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette // Adjust left and right padding to ensure there's enough room for the 6450c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette // thumb's padding (when present). 6460c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette int paddingLeft = padding.left; 6470c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette int paddingRight = padding.right; 6480c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette if (mThumbDrawable != null) { 6490c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final Insets inset = mThumbDrawable.getOpticalInsets(); 6500c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette paddingLeft = Math.max(paddingLeft, inset.left); 6510c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette paddingRight = Math.max(paddingRight, inset.right); 6520c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } 6530c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 65412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int switchWidth = Math.max(mSwitchMinWidth, 6550c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 2 * mThumbWidth + paddingLeft + paddingRight); 6564d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette final int switchHeight = Math.max(trackHeight, thumbHeight); 65712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchWidth = switchWidth; 65812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchHeight = switchHeight; 65912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 66012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super.onMeasure(widthMeasureSpec, heightMeasureSpec); 6614d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette 66212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int measuredHeight = getMeasuredHeight(); 66312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (measuredHeight < switchHeight) { 664189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn setMeasuredDimension(getMeasuredWidthAndState(), switchHeight); 66512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 66612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 66712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 66863bce03cc69be4a45230aa8bbd89dbde60681067Svetoslav Ganov @Override 66963bce03cc69be4a45230aa8bbd89dbde60681067Svetoslav Ganov public void onPopulateAccessibilityEvent(AccessibilityEvent event) { 67063bce03cc69be4a45230aa8bbd89dbde60681067Svetoslav Ganov super.onPopulateAccessibilityEvent(event); 6712a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette 6722a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette final CharSequence text = isChecked() ? mTextOn : mTextOff; 6732a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette if (text != null) { 6742a37cf8d763750853e2b4e036bc7cb4486c78e1dAlan Viverette event.getText().add(text); 6757650259a597dd24137420d32acc35efc44db381eSvetoslav Ganov } 67663bce03cc69be4a45230aa8bbd89dbde60681067Svetoslav Ganov } 67763bce03cc69be4a45230aa8bbd89dbde60681067Svetoslav Ganov 67812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private Layout makeLayout(CharSequence text) { 6794c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler final CharSequence transformed = (mSwitchTransformationMethod != null) 6804c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler ? mSwitchTransformationMethod.getTransformation(text, this) 6814c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler : text; 6824c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler 6834c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler return new StaticLayout(transformed, mTextPaint, 6844c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler (int) Math.ceil(Layout.getDesiredWidth(transformed, mTextPaint)), 68512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell Layout.Alignment.ALIGN_NORMAL, 1.f, 0, true); 68612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 68712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 68812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 68912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @return true if (x, y) is within the target area of the switch thumb 69012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 69112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private boolean hitThumb(float x, float y) { 69201a09630060eccc471ba3d8d83b34a602871d5c1Alan Viverette if (mThumbDrawable == null) { 69301a09630060eccc471ba3d8d83b34a602871d5c1Alan Viverette return false; 69401a09630060eccc471ba3d8d83b34a602871d5c1Alan Viverette } 69501a09630060eccc471ba3d8d83b34a602871d5c1Alan Viverette 696cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette // Relies on mTempRect, MUST be called first! 697cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette final int thumbOffset = getThumbOffset(); 698cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette 69912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mThumbDrawable.getPadding(mTempRect); 70012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int thumbTop = mSwitchTop - mTouchSlop; 701cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette final int thumbLeft = mSwitchLeft + thumbOffset - mTouchSlop; 70212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int thumbRight = thumbLeft + mThumbWidth + 70312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTempRect.left + mTempRect.right + mTouchSlop; 70412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int thumbBottom = mSwitchBottom + mTouchSlop; 70512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return x > thumbLeft && x < thumbRight && y > thumbTop && y < thumbBottom; 70612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 70712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 70812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 70912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public boolean onTouchEvent(MotionEvent ev) { 71012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mVelocityTracker.addMovement(ev); 71112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int action = ev.getActionMasked(); 71212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switch (action) { 71312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case MotionEvent.ACTION_DOWN: { 71412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final float x = ev.getX(); 71512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final float y = ev.getY(); 716c2ab0d665c9d1c332fbd726abf582a27cf7a6701Gilles Debunne if (isEnabled() && hitThumb(x, y)) { 71712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchMode = TOUCH_MODE_DOWN; 71812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchX = x; 71912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchY = y; 72012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 72112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 72212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 72312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 72412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case MotionEvent.ACTION_MOVE: { 72512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switch (mTouchMode) { 72612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case TOUCH_MODE_IDLE: 72712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell // Didn't target the thumb, treat normally. 72812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 72912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 73012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case TOUCH_MODE_DOWN: { 73112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final float x = ev.getX(); 73212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final float y = ev.getY(); 73312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (Math.abs(x - mTouchX) > mTouchSlop || 73412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell Math.abs(y - mTouchY) > mTouchSlop) { 73512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchMode = TOUCH_MODE_DRAGGING; 73612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell getParent().requestDisallowInterceptTouchEvent(true); 73712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchX = x; 73812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchY = y; 73912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return true; 74012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 74112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 74212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 74312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 74412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case TOUCH_MODE_DRAGGING: { 74512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final float x = ev.getX(); 746cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette final int thumbScrollRange = getThumbScrollRange(); 747cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette final float thumbScrollOffset = x - mTouchX; 748cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette float dPos; 749cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette if (thumbScrollRange != 0) { 750cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette dPos = thumbScrollOffset / thumbScrollRange; 751cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette } else { 752cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette // If the thumb scroll range is empty, just use the 753cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette // movement direction to snap on or off. 754cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette dPos = thumbScrollOffset > 0 ? 1 : -1; 755cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette } 756cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette if (isLayoutRtl()) { 757cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette dPos = -dPos; 758cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette } 759cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette final float newPos = MathUtils.constrain(mThumbPosition + dPos, 0, 1); 76012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (newPos != mThumbPosition) { 76112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchX = x; 762cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette setThumbPosition(newPos); 76312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 76412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return true; 76512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 76612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 76712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 76812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 76912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 77012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case MotionEvent.ACTION_UP: 77112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case MotionEvent.ACTION_CANCEL: { 77212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (mTouchMode == TOUCH_MODE_DRAGGING) { 77312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell stopDrag(ev); 774ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette // Allow super class to handle pressed state, etc. 775ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette super.onTouchEvent(ev); 77612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return true; 77712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 77812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchMode = TOUCH_MODE_IDLE; 77912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mVelocityTracker.clear(); 78012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 78112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 78212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 78312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 78412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return super.onTouchEvent(ev); 78512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 78612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 78712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private void cancelSuperTouch(MotionEvent ev) { 78812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell MotionEvent cancel = MotionEvent.obtain(ev); 78912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell cancel.setAction(MotionEvent.ACTION_CANCEL); 79012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super.onTouchEvent(cancel); 79112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell cancel.recycle(); 79212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 79312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 79412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 79512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Called from onTouchEvent to end a drag operation. 79612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 79712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @param ev Event that triggered the end of drag mode - ACTION_UP or ACTION_CANCEL 79812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 79912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private void stopDrag(MotionEvent ev) { 80012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchMode = TOUCH_MODE_IDLE; 80112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 80286453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette // Commit the change if the event is up and not canceled and the switch 80386453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette // has not been disabled during the drag. 80486453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette final boolean commitChange = ev.getAction() == MotionEvent.ACTION_UP && isEnabled(); 805d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette final boolean oldState = isChecked(); 80686453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette final boolean newState; 80712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (commitChange) { 80812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mVelocityTracker.computeCurrentVelocity(1000); 80986453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette final float xvel = mVelocityTracker.getXVelocity(); 81012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (Math.abs(xvel) > mMinFlingVelocity) { 81128efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio newState = isLayoutRtl() ? (xvel < 0) : (xvel > 0); 81212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } else { 81312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell newState = getTargetCheckedState(); 81412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 81512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } else { 816d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette newState = oldState; 817d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette } 818d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette 819d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette if (newState != oldState) { 820d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette playSoundEffect(SoundEffectConstants.CLICK); 821d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette setChecked(newState); 82212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 82386453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette 82486453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette cancelSuperTouch(ev); 82512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 82612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 82712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private void animateThumbToCheckedState(boolean newCheckedState) { 828cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette final float targetPosition = newCheckedState ? 1 : 0; 829cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette mPositionAnimator = ObjectAnimator.ofFloat(this, THUMB_POS, targetPosition); 830cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette mPositionAnimator.setDuration(THUMB_ANIMATION_DURATION); 831cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette mPositionAnimator.setAutoCancel(true); 832cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette mPositionAnimator.start(); 83312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 83412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 835cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette private void cancelPositionAnimator() { 836cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette if (mPositionAnimator != null) { 837cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette mPositionAnimator.cancel(); 83828efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 83928efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 84028efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio 841cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette private boolean getTargetCheckedState() { 842cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette return mThumbPosition > 0.5f; 843cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette } 844cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette 845cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette /** 846cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette * Sets the thumb position as a decimal value between 0 (off) and 1 (on). 847cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette * 848cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette * @param position new position between [0,1] 849cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette */ 850cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette private void setThumbPosition(float position) { 851cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette mThumbPosition = position; 852cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette invalidate(); 853cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette } 854cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette 855cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette @Override 856cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette public void toggle() { 85786453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette setChecked(!isChecked()); 85812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 85912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 86012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 86112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void setChecked(boolean checked) { 86212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super.setChecked(checked); 863cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette 864467d629ca714cd74658043c1ddfec36c60d898c1Alan Viverette // Calling the super method may result in setChecked() getting called 865467d629ca714cd74658043c1ddfec36c60d898c1Alan Viverette // recursively with a different value, so load the REAL value... 866467d629ca714cd74658043c1ddfec36c60d898c1Alan Viverette checked = isChecked(); 867467d629ca714cd74658043c1ddfec36c60d898c1Alan Viverette 86886453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette if (isAttachedToWindow() && isLaidOut()) { 86986453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette animateThumbToCheckedState(checked); 87086453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette } else { 87186453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette // Immediately move the thumb to the new position. 87286453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette cancelPositionAnimator(); 87386453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette setThumbPosition(checked ? 1 : 0); 87486453ff147f28b0c16bea73da5b261feed50efb7Alan Viverette } 87512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 87612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 87712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 87812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 87912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super.onLayout(changed, left, top, right, bottom); 88012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 8810c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette int opticalInsetLeft = 0; 8820c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette int opticalInsetRight = 0; 8830c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette if (mThumbDrawable != null) { 8840c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final Rect trackPadding = mTempRect; 8850c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette if (mTrackDrawable != null) { 8860c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette mTrackDrawable.getPadding(trackPadding); 8870c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } else { 8880c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette trackPadding.setEmpty(); 8890c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } 8900c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 8910c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final Insets insets = mThumbDrawable.getOpticalInsets(); 8920c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette opticalInsetLeft = Math.max(0, insets.left - trackPadding.left); 8930c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette opticalInsetRight = Math.max(0, insets.right - trackPadding.right); 8940c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } 89528efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio 8960c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final int switchRight; 8970c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final int switchLeft; 89828efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio if (isLayoutRtl()) { 8990c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette switchLeft = getPaddingLeft() + opticalInsetLeft; 9000c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette switchRight = switchLeft + mSwitchWidth - opticalInsetLeft - opticalInsetRight; 90128efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } else { 9020c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette switchRight = getWidth() - getPaddingRight() - opticalInsetRight; 9030c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette switchLeft = switchRight - mSwitchWidth + opticalInsetLeft + opticalInsetRight; 90428efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 905c3eabb9b6ce7f556313c8e3870d76c5b443f1c51Joe Onorato 9060c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final int switchTop; 9070c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final int switchBottom; 90812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switch (getGravity() & Gravity.VERTICAL_GRAVITY_MASK) { 90912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell default: 91012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case Gravity.TOP: 91112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switchTop = getPaddingTop(); 91212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switchBottom = switchTop + mSwitchHeight; 91312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 91412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 91512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case Gravity.CENTER_VERTICAL: 91612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switchTop = (getPaddingTop() + getHeight() - getPaddingBottom()) / 2 - 91712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchHeight / 2; 91812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switchBottom = switchTop + mSwitchHeight; 91912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 92012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 92112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case Gravity.BOTTOM: 92212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switchBottom = getHeight() - getPaddingBottom(); 92312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switchTop = switchBottom - mSwitchHeight; 92412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 92512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 92612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 92712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchLeft = switchLeft; 92812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchTop = switchTop; 92912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchBottom = switchBottom; 93012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchRight = switchRight; 93112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 93212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 93312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 934ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public void draw(Canvas c) { 9354d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette final Rect padding = mTempRect; 9365876ff4a0ac938297bfd114da6b5d8c9dcb4cef6Alan Viverette final int switchLeft = mSwitchLeft; 9375876ff4a0ac938297bfd114da6b5d8c9dcb4cef6Alan Viverette final int switchTop = mSwitchTop; 9385876ff4a0ac938297bfd114da6b5d8c9dcb4cef6Alan Viverette final int switchRight = mSwitchRight; 9395876ff4a0ac938297bfd114da6b5d8c9dcb4cef6Alan Viverette final int switchBottom = mSwitchBottom; 9400c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 9410c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette int thumbInitialLeft = switchLeft + getThumbOffset(); 9420c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 9430c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final Insets thumbInsets; 9440c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette if (mThumbDrawable != null) { 9450c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette thumbInsets = mThumbDrawable.getOpticalInsets(); 9460c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } else { 9470c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette thumbInsets = Insets.NONE; 9488bb399069da4e46b231333cff6880a0cf35b9417Alan Viverette } 949cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette 9500c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette // Layout the track. 9510c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette if (mTrackDrawable != null) { 9520c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette mTrackDrawable.getPadding(padding); 9539b38f6c2cd1d97bb0d1a21e2f9545e02fae851e0Alan Viverette 9540c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette // Adjust thumb position for track padding. 9550c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette thumbInitialLeft += padding.left; 9560c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 9570c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette // If necessary, offset by the optical insets of the thumb asset. 9580c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette int trackLeft = switchLeft; 9590c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette int trackTop = switchTop; 9600c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette int trackRight = switchRight; 9610c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette int trackBottom = switchBottom; 9620c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette if (thumbInsets != Insets.NONE) { 9630c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette if (thumbInsets.left > padding.left) { 9640c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette trackLeft += thumbInsets.left - padding.left; 9650c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } 9660c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette if (thumbInsets.top > padding.top) { 9670c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette trackTop += thumbInsets.top - padding.top; 9680c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } 9690c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette if (thumbInsets.right > padding.right) { 9700c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette trackRight -= thumbInsets.right - padding.right; 9710c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } 9720c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette if (thumbInsets.bottom > padding.bottom) { 9730c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette trackBottom -= thumbInsets.bottom - padding.bottom; 9740c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } 9750c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } 9760c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette mTrackDrawable.setBounds(trackLeft, trackTop, trackRight, trackBottom); 9770c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } 9789b38f6c2cd1d97bb0d1a21e2f9545e02fae851e0Alan Viverette 979661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette // Layout the thumb. 9804d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette if (mThumbDrawable != null) { 9814d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette mThumbDrawable.getPadding(padding); 9820c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 9830c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final int thumbLeft = thumbInitialLeft - padding.left; 9840c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final int thumbRight = thumbInitialLeft + mThumbWidth + padding.right; 9854d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette mThumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom); 9864d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette 9874d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette final Drawable background = getBackground(); 9884d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette if (background != null) { 9894d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette background.setHotspotBounds(thumbLeft, switchTop, thumbRight, switchBottom); 9904d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette } 99161956606818918194a38e045a8e35e7108480e5eAlan Viverette } 99261956606818918194a38e045a8e35e7108480e5eAlan Viverette 993ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette // Draw the background. 994ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette super.draw(c); 995ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 996ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 997ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette @Override 998ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette protected void onDraw(Canvas canvas) { 99961956606818918194a38e045a8e35e7108480e5eAlan Viverette super.onDraw(canvas); 100061956606818918194a38e045a8e35e7108480e5eAlan Viverette 10014d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette final Rect padding = mTempRect; 1002ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette final Drawable trackDrawable = mTrackDrawable; 10034d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette if (trackDrawable != null) { 10044d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette trackDrawable.getPadding(padding); 10054d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette } else { 10064d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette padding.setEmpty(); 10074d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette } 1008ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 1009ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette final int switchTop = mSwitchTop; 1010ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette final int switchBottom = mSwitchBottom; 10114d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette final int switchInnerTop = switchTop + padding.top; 10124d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette final int switchInnerBottom = switchBottom - padding.bottom; 10134d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette 10144d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette final Drawable thumbDrawable = mThumbDrawable; 10154d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette if (trackDrawable != null) { 10164d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette if (mSplitTrack && thumbDrawable != null) { 10174d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette final Insets insets = thumbDrawable.getOpticalInsets(); 10184d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette thumbDrawable.copyBounds(padding); 10194d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette padding.left += insets.left; 10204d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette padding.right -= insets.right; 10214d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette 10224d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette final int saveCount = canvas.save(); 10234d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette canvas.clipRect(padding, Op.DIFFERENCE); 10244d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette trackDrawable.draw(canvas); 10254d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette canvas.restoreToCount(saveCount); 10264d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette } else { 10274d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette trackDrawable.draw(canvas); 10284d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette } 1029661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette } 103061956606818918194a38e045a8e35e7108480e5eAlan Viverette 103161956606818918194a38e045a8e35e7108480e5eAlan Viverette final int saveCount = canvas.save(); 10324d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette 10334d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette if (thumbDrawable != null) { 10344d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette thumbDrawable.draw(canvas); 10354d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette } 103612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 10375876ff4a0ac938297bfd114da6b5d8c9dcb4cef6Alan Viverette final Layout switchText = getTargetCheckedState() ? mOnLayout : mOffLayout; 1038be06e3292b295324b3b47d13f9a40787b666309fFabrice Di Meglio if (switchText != null) { 1039661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette final int drawableState[] = getDrawableState(); 1040661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette if (mTextColors != null) { 1041661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette mTextPaint.setColor(mTextColors.getColorForState(drawableState, 0)); 1042661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette } 1043661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette mTextPaint.drawableState = drawableState; 1044661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette 10454d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette final int cX; 10464d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette if (thumbDrawable != null) { 10474d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette final Rect bounds = thumbDrawable.getBounds(); 10484d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette cX = bounds.left + bounds.right; 10494d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette } else { 1050dec17299fef93f673d8e8cab0ec0f734bf6b8539Alan Viverette cX = getWidth(); 10514d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette } 10524d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette 10534d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette final int left = cX / 2 - switchText.getWidth() / 2; 10545876ff4a0ac938297bfd114da6b5d8c9dcb4cef6Alan Viverette final int top = (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2; 10555876ff4a0ac938297bfd114da6b5d8c9dcb4cef6Alan Viverette canvas.translate(left, top); 1056be06e3292b295324b3b47d13f9a40787b666309fFabrice Di Meglio switchText.draw(canvas); 1057be06e3292b295324b3b47d13f9a40787b666309fFabrice Di Meglio } 105812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 10595876ff4a0ac938297bfd114da6b5d8c9dcb4cef6Alan Viverette canvas.restoreToCount(saveCount); 106012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 106112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 106212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 106328efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio public int getCompoundPaddingLeft() { 106428efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio if (!isLayoutRtl()) { 106528efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio return super.getCompoundPaddingLeft(); 106628efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 106728efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio int padding = super.getCompoundPaddingLeft() + mSwitchWidth; 106828efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio if (!TextUtils.isEmpty(getText())) { 106928efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio padding += mSwitchPadding; 107028efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 107128efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio return padding; 107228efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 107328efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio 107428efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio @Override 107512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public int getCompoundPaddingRight() { 107628efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio if (isLayoutRtl()) { 107728efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio return super.getCompoundPaddingRight(); 107828efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 107912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int padding = super.getCompoundPaddingRight() + mSwitchWidth; 108012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (!TextUtils.isEmpty(getText())) { 108112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell padding += mSwitchPadding; 108212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 108312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return padding; 108412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 108512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 1086cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette /** 1087cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette * Translates thumb position to offset according to current RTL setting and 10880c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette * thumb scroll range. Accounts for both track and thumb padding. 1089cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette * 1090cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette * @return thumb offset 1091cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette */ 1092cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette private int getThumbOffset() { 1093cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette final float thumbPosition; 1094cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette if (isLayoutRtl()) { 1095cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette thumbPosition = 1 - mThumbPosition; 1096cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette } else { 1097cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette thumbPosition = mThumbPosition; 1098cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette } 1099cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette return (int) (thumbPosition * getThumbScrollRange() + 0.5f); 1100cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette } 1101cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette 110212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int getThumbScrollRange() { 11034d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette if (mTrackDrawable != null) { 11040c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final Rect padding = mTempRect; 11050c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette mTrackDrawable.getPadding(padding); 11060c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 11070c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette final Insets insets; 11080c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette if (mThumbDrawable != null) { 11090c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette insets = mThumbDrawable.getOpticalInsets(); 11100c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } else { 11110c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette insets = Insets.NONE; 11120c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette } 11130c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette 11140c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette return mSwitchWidth - mThumbWidth - padding.left - padding.right 11150c0dde7171c7ea35bbc6d64a41f94b428cb4d1f6Alan Viverette - insets.left - insets.right; 11164d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette } else { 111712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return 0; 111812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 111912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 112012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 112112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 112212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell protected int[] onCreateDrawableState(int extraSpace) { 112312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 112412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (isChecked()) { 112512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mergeDrawableStates(drawableState, CHECKED_STATE_SET); 112612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 112712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return drawableState; 112812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 112912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 113012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 113112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell protected void drawableStateChanged() { 113212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super.drawableStateChanged(); 113312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 1134661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette final int[] myDrawableState = getDrawableState(); 1135661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette 11362356c5e69b0911e6334ebf6374217898371be5acAlan Viverette if (mThumbDrawable != null) { 11372356c5e69b0911e6334ebf6374217898371be5acAlan Viverette mThumbDrawable.setState(myDrawableState); 1138661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette } 113912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 1140661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette if (mTrackDrawable != null) { 1141661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette mTrackDrawable.setState(myDrawableState); 1142661e63658da39cccfe49a129e4860455716ff3c9Alan Viverette } 114312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 114412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell invalidate(); 114512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 114612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 1147cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette @Override 11488de1494557cf1d00c1c3fce439138a28de7fbd61Alan Viverette public void drawableHotspotChanged(float x, float y) { 11498de1494557cf1d00c1c3fce439138a28de7fbd61Alan Viverette super.drawableHotspotChanged(x, y); 1150cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette 1151cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette if (mThumbDrawable != null) { 1152cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette mThumbDrawable.setHotspot(x, y); 1153cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette } 1154cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette 1155cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette if (mTrackDrawable != null) { 1156cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette mTrackDrawable.setHotspot(x, y); 1157cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette } 1158cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette } 1159cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette 116012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 116112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell protected boolean verifyDrawable(Drawable who) { 116212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return super.verifyDrawable(who) || who == mThumbDrawable || who == mTrackDrawable; 116312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 116412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 116512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 116612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void jumpDrawablesToCurrentState() { 116712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super.jumpDrawablesToCurrentState(); 11684d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette 11694d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette if (mThumbDrawable != null) { 11704d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette mThumbDrawable.jumpToCurrentState(); 11714d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette } 11724d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette 11734d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette if (mTrackDrawable != null) { 11744d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette mTrackDrawable.jumpToCurrentState(); 11754d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette } 11764d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette 11774d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette if (mPositionAnimator != null && mPositionAnimator.isRunning()) { 11784d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette mPositionAnimator.end(); 11794d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette mPositionAnimator = null; 11804d065a04ce42c07569cf20651c949c4da97aa4a9Alan Viverette } 118112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 11828a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 11838a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 11848a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 11858a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityEvent(event); 11868a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov event.setClassName(Switch.class.getName()); 11878a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 11888a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 11898a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 11908a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 11918a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityNodeInfo(info); 11928a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov info.setClassName(Switch.class.getName()); 119378bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov CharSequence switchText = isChecked() ? mTextOn : mTextOff; 119478bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov if (!TextUtils.isEmpty(switchText)) { 119578bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov CharSequence oldText = info.getText(); 119678bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov if (TextUtils.isEmpty(oldText)) { 119778bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov info.setText(switchText); 119878bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov } else { 119978bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov StringBuilder newText = new StringBuilder(); 120078bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov newText.append(oldText).append(' ').append(switchText); 120178bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov info.setText(newText); 120278bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov } 120378bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov } 12048a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 1205cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette 1206cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette private static final FloatProperty<Switch> THUMB_POS = new FloatProperty<Switch>("thumbPos") { 1207cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette @Override 1208cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette public Float get(Switch object) { 1209cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette return object.mThumbPosition; 1210cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette } 1211cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette 1212cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette @Override 1213cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette public void setValue(Switch object, float value) { 1214cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette object.setThumbPosition(value); 1215cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette } 1216cc2688d18af3f434fc6ac63289a69f6c1a9f8d9fAlan Viverette }; 121712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell} 1218