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 1912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.content.Context; 2012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.content.res.ColorStateList; 2112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.content.res.Resources; 2212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.content.res.TypedArray; 2312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.graphics.Canvas; 2412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.graphics.Paint; 2512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.graphics.Rect; 2612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.graphics.Typeface; 2712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.graphics.drawable.Drawable; 2812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.text.Layout; 2912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.text.StaticLayout; 3012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.text.TextPaint; 3112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.text.TextUtils; 324c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandlerimport android.text.method.AllCapsTransformationMethod; 334c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandlerimport android.text.method.TransformationMethod2; 3412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.util.AttributeSet; 3512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.view.Gravity; 3612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.view.MotionEvent; 3712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.view.VelocityTracker; 3812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellimport android.view.ViewConfiguration; 3963bce03cc69be4a45230aa8bbd89dbde60681067Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 408a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo; 4112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 42be0a4535053bbfdebd215e244b154ac810fd8edcAdam Powellimport com.android.internal.R; 43be0a4535053bbfdebd215e244b154ac810fd8edcAdam Powell 4412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell/** 4512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * A Switch is a two-state toggle switch widget that can select between two 4612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * options. The user may drag the "thumb" back and forth to choose the selected option, 47150176d83023e3c486dba10edebb72af36b4099aChet Haase * or simply tap to toggle as if it were a checkbox. The {@link #setText(CharSequence) text} 48150176d83023e3c486dba10edebb72af36b4099aChet Haase * property controls the text displayed in the label for the switch, whereas the 49150176d83023e3c486dba10edebb72af36b4099aChet Haase * {@link #setTextOff(CharSequence) off} and {@link #setTextOn(CharSequence) on} text 50150176d83023e3c486dba10edebb72af36b4099aChet Haase * controls the text on the thumb. Similarly, the 51150176d83023e3c486dba10edebb72af36b4099aChet Haase * {@link #setTextAppearance(android.content.Context, int) textAppearance} and the related 52150176d83023e3c486dba10edebb72af36b4099aChet Haase * setTypeface() methods control the typeface and style of label text, whereas the 53150176d83023e3c486dba10edebb72af36b4099aChet Haase * {@link #setSwitchTextAppearance(android.content.Context, int) switchTextAppearance} and 54150176d83023e3c486dba10edebb72af36b4099aChet Haase * the related seSwitchTypeface() methods control that of the thumb. 5512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 564c359b76f9a030f92a302ba74a528faa170bad4eScott Main * <p>See the <a href="{@docRoot}guide/topics/ui/controls/togglebutton.html">Toggle Buttons</a> 574c359b76f9a030f92a302ba74a528faa170bad4eScott Main * guide.</p> 584c359b76f9a030f92a302ba74a528faa170bad4eScott Main * 594c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_textOn 604c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_textOff 614c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_switchMinWidth 624c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_switchPadding 634c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_switchTextAppearance 644c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_thumb 654c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_thumbTextPadding 664c359b76f9a030f92a302ba74a528faa170bad4eScott Main * @attr ref android.R.styleable#Switch_track 6712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 6812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powellpublic class Switch extends CompoundButton { 6912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int TOUCH_MODE_IDLE = 0; 7012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int TOUCH_MODE_DOWN = 1; 7112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int TOUCH_MODE_DRAGGING = 2; 7212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 7312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell // Enum for the "typeface" XML parameter. 7412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int SANS = 1; 7512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int SERIF = 2; 7612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int MONOSPACE = 3; 7712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 7812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private Drawable mThumbDrawable; 7912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private Drawable mTrackDrawable; 8012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mThumbTextPadding; 8112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchMinWidth; 8212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchPadding; 8312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private CharSequence mTextOn; 8412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private CharSequence mTextOff; 8512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 8612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mTouchMode; 8712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mTouchSlop; 8812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private float mTouchX; 8912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private float mTouchY; 9012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private VelocityTracker mVelocityTracker = VelocityTracker.obtain(); 9112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mMinFlingVelocity; 9212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 9312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private float mThumbPosition; 9412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchWidth; 9512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchHeight; 9612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mThumbWidth; // Does not include padding 9712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 9812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchLeft; 9912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchTop; 10012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchRight; 10112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int mSwitchBottom; 10212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 10312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private TextPaint mTextPaint; 10412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private ColorStateList mTextColors; 10512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private Layout mOnLayout; 10612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private Layout mOffLayout; 1074c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler private TransformationMethod2 mSwitchTransformationMethod; 10812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 109be0a4535053bbfdebd215e244b154ac810fd8edcAdam Powell @SuppressWarnings("hiding") 11012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private final Rect mTempRect = new Rect(); 11112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 11212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private static final int[] CHECKED_STATE_SET = { 11312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell R.attr.state_checked 11412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell }; 11512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 11612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 11712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Construct a new Switch with default styling. 11812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 11912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @param context The Context that will determine this widget's theming. 12012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 12112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public Switch(Context context) { 12212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell this(context, null); 12312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 12412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 12512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 12612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Construct a new Switch with default styling, overriding specific style 12712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * attributes as requested. 12812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 12912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @param context The Context that will determine this widget's theming. 13012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @param attrs Specification of attributes that should deviate from default styling. 13112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 13212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public Switch(Context context, AttributeSet attrs) { 13312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell this(context, attrs, com.android.internal.R.attr.switchStyle); 13412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 13512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 13612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 13712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Construct a new Switch with a default style determined by the given theme attribute, 13812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * overriding specific style attributes as requested. 13912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 14012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @param context The Context that will determine this widget's theming. 14112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @param attrs Specification of attributes that should deviate from the default styling. 14212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @param defStyle An attribute ID within the active theme containing a reference to the 14312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * default style for this widget. e.g. android.R.attr.switchStyle. 14412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 14512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public Switch(Context context, AttributeSet attrs, int defStyle) { 14612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super(context, attrs, defStyle); 14712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 14812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); 14912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell Resources res = getResources(); 15012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.density = res.getDisplayMetrics().density; 15112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.setCompatibilityScaling(res.getCompatibilityInfo().applicationScale); 15212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 15312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell TypedArray a = context.obtainStyledAttributes(attrs, 15412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell com.android.internal.R.styleable.Switch, defStyle, 0); 15512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 156150176d83023e3c486dba10edebb72af36b4099aChet Haase mThumbDrawable = a.getDrawable(com.android.internal.R.styleable.Switch_thumb); 157150176d83023e3c486dba10edebb72af36b4099aChet Haase mTrackDrawable = a.getDrawable(com.android.internal.R.styleable.Switch_track); 15812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextOn = a.getText(com.android.internal.R.styleable.Switch_textOn); 15912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextOff = a.getText(com.android.internal.R.styleable.Switch_textOff); 16012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mThumbTextPadding = a.getDimensionPixelSize( 16112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell com.android.internal.R.styleable.Switch_thumbTextPadding, 0); 16212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchMinWidth = a.getDimensionPixelSize( 16312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell com.android.internal.R.styleable.Switch_switchMinWidth, 0); 16412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchPadding = a.getDimensionPixelSize( 16512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell com.android.internal.R.styleable.Switch_switchPadding, 0); 16612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 16712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int appearance = a.getResourceId( 16812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell com.android.internal.R.styleable.Switch_switchTextAppearance, 0); 16912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (appearance != 0) { 170150176d83023e3c486dba10edebb72af36b4099aChet Haase setSwitchTextAppearance(context, appearance); 17112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 17212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell a.recycle(); 17312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 17412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell ViewConfiguration config = ViewConfiguration.get(context); 17512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchSlop = config.getScaledTouchSlop(); 17612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mMinFlingVelocity = config.getScaledMinimumFlingVelocity(); 17712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 17812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell // Refresh display with current params 179e724ee4b04d121556e9764f72f9b921a0e16392aGilles Debunne refreshDrawableState(); 18012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell setChecked(isChecked()); 18112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 18212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 18312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 18412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Sets the switch text color, size, style, hint color, and highlight color 18512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * from the specified TextAppearance resource. 1866c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 1876c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_switchTextAppearance 18812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 189150176d83023e3c486dba10edebb72af36b4099aChet Haase public void setSwitchTextAppearance(Context context, int resid) { 19012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell TypedArray appearance = 191150176d83023e3c486dba10edebb72af36b4099aChet Haase context.obtainStyledAttributes(resid, 19212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell com.android.internal.R.styleable.TextAppearance); 19312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 19412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell ColorStateList colors; 19512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int ts; 19612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 19712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell colors = appearance.getColorStateList(com.android.internal.R.styleable. 19812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell TextAppearance_textColor); 19912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (colors != null) { 20012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextColors = colors; 201150176d83023e3c486dba10edebb72af36b4099aChet Haase } else { 202150176d83023e3c486dba10edebb72af36b4099aChet Haase // If no color set in TextAppearance, default to the view's textColor 203150176d83023e3c486dba10edebb72af36b4099aChet Haase mTextColors = getTextColors(); 20412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 20512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 20612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell ts = appearance.getDimensionPixelSize(com.android.internal.R.styleable. 20712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell TextAppearance_textSize, 0); 20812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (ts != 0) { 20912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (ts != mTextPaint.getTextSize()) { 21012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.setTextSize(ts); 21112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell requestLayout(); 21212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 21312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 21412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 21512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int typefaceIndex, styleIndex; 21612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 21712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell typefaceIndex = appearance.getInt(com.android.internal.R.styleable. 21812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell TextAppearance_typeface, -1); 21912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell styleIndex = appearance.getInt(com.android.internal.R.styleable. 22012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell TextAppearance_textStyle, -1); 22112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 22212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell setSwitchTypefaceByIndex(typefaceIndex, styleIndex); 22312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 2244c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler boolean allCaps = appearance.getBoolean(com.android.internal.R.styleable. 2254c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler TextAppearance_textAllCaps, false); 2264c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler if (allCaps) { 2274c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler mSwitchTransformationMethod = new AllCapsTransformationMethod(getContext()); 2284c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler mSwitchTransformationMethod.setLengthChangesAllowed(true); 2294c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler } else { 2304c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler mSwitchTransformationMethod = null; 2314c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler } 2324c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler 23312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell appearance.recycle(); 23412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 23512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 23612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private void setSwitchTypefaceByIndex(int typefaceIndex, int styleIndex) { 23712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell Typeface tf = null; 23812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switch (typefaceIndex) { 23912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case SANS: 24012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell tf = Typeface.SANS_SERIF; 24112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 24212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 24312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case SERIF: 24412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell tf = Typeface.SERIF; 24512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 24612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 24712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case MONOSPACE: 24812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell tf = Typeface.MONOSPACE; 24912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 25012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 25112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 25212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell setSwitchTypeface(tf, styleIndex); 25312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 25412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 25512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 25612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Sets the typeface and style in which the text should be displayed on the 25712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * switch, and turns on the fake bold and italic bits in the Paint if the 25812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Typeface that you provided does not have all the bits in the 25912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * style that you specified. 26012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 26112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void setSwitchTypeface(Typeface tf, int style) { 26212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (style > 0) { 26312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (tf == null) { 26412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell tf = Typeface.defaultFromStyle(style); 26512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } else { 26612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell tf = Typeface.create(tf, style); 26712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 26812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 26912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell setSwitchTypeface(tf); 27012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell // now compute what (if any) algorithmic styling is needed 27112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int typefaceStyle = tf != null ? tf.getStyle() : 0; 27212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int need = style & ~typefaceStyle; 27312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.setFakeBoldText((need & Typeface.BOLD) != 0); 27412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.setTextSkewX((need & Typeface.ITALIC) != 0 ? -0.25f : 0); 27512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } else { 276aa0980afab57a6aebb06e70f60e92511708fa5afVictoria Lease mTextPaint.setFakeBoldText(false); 27712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.setTextSkewX(0); 27812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell setSwitchTypeface(tf); 27912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 28012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 28112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 28212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 283150176d83023e3c486dba10edebb72af36b4099aChet Haase * Sets the typeface in which the text should be displayed on the switch. 28412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Note that not all Typeface families actually have bold and italic 28512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * variants, so you may need to use 28612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * {@link #setSwitchTypeface(Typeface, int)} to get the appearance 28712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * that you actually want. 28812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 28912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @attr ref android.R.styleable#TextView_typeface 29012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @attr ref android.R.styleable#TextView_textStyle 29112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 29212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void setSwitchTypeface(Typeface tf) { 29312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (mTextPaint.getTypeface() != tf) { 29412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.setTypeface(tf); 29512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 29612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell requestLayout(); 29712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell invalidate(); 29812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 29912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 30012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 30112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 3026c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Set the amount of horizontal padding between the switch and the associated text. 3036c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3046c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @param pixels Amount of padding in pixels 3056c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3066c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_switchPadding 3076c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 3086c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public void setSwitchPadding(int pixels) { 3096c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell mSwitchPadding = pixels; 3106c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell requestLayout(); 3116c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 3126c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 3136c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 3146c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Get the amount of horizontal padding between the switch and the associated text. 3156c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3166c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @return Amount of padding in pixels 3176c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3186c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_switchPadding 3196c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 3206c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public int getSwitchPadding() { 3216c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell return mSwitchPadding; 3226c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 3236c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 3246c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 3256c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Set the minimum width of the switch in pixels. The switch's width will be the maximum 3266c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * of this value and its measured width as determined by the switch drawables and text used. 3276c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3286c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @param pixels Minimum width of the switch in pixels 3296c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3306c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_switchMinWidth 3316c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 3326c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public void setSwitchMinWidth(int pixels) { 3336c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell mSwitchMinWidth = pixels; 3346c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell requestLayout(); 3356c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 3366c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 3376c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 3386c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Get the minimum width of the switch in pixels. The switch's width will be the maximum 3396c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * of this value and its measured width as determined by the switch drawables and text used. 3406c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3416c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @return Minimum width of the switch in pixels 3426c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3436c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_switchMinWidth 3446c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 3456c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public int getSwitchMinWidth() { 3466c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell return mSwitchMinWidth; 3476c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 3486c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 3496c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 3506c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Set the horizontal padding around the text drawn on the switch itself. 3516c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3526c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @param pixels Horizontal padding for switch thumb text in pixels 3536c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3546c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_thumbTextPadding 3556c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 3566c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public void setThumbTextPadding(int pixels) { 3576c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell mThumbTextPadding = pixels; 3586c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell requestLayout(); 3596c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 3606c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 3616c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 3626c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Get the horizontal padding around the text drawn on the switch itself. 3636c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3646c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @return Horizontal padding for switch thumb text in pixels 3656c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3666c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_thumbTextPadding 3676c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 3686c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public int getThumbTextPadding() { 3696c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell return mThumbTextPadding; 3706c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 3716c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 3726c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 3736c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Set the drawable used for the track that the switch slides within. 3746c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3756c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @param track Track drawable 3766c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3776c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_track 3786c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 3796c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public void setTrackDrawable(Drawable track) { 3806c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell mTrackDrawable = track; 3816c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell requestLayout(); 3826c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 3836c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 3846c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 385d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * Set the drawable used for the track that the switch slides within. 386d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * 387dca510e026e3e75759bac84c3860dc84b83a608fAdam Powell * @param resId Resource ID of a track drawable 388d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * 389d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * @attr ref android.R.styleable#Switch_track 390d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell */ 391d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell public void setTrackResource(int resId) { 392d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell setTrackDrawable(getContext().getResources().getDrawable(resId)); 393d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell } 394d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell 395d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell /** 3966c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Get the drawable used for the track that the switch slides within. 3976c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 3986c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @return Track drawable 3996c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4006c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_track 4016c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 4026c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public Drawable getTrackDrawable() { 4036c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell return mTrackDrawable; 4046c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 4056c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 4066c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 4076c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Set the drawable used for the switch "thumb" - the piece that the user 4086c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * can physically touch and drag along the track. 4096c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4106c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @param thumb Thumb drawable 4116c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4126c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_thumb 4136c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 4146c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public void setThumbDrawable(Drawable thumb) { 4156c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell mThumbDrawable = thumb; 4166c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell requestLayout(); 4176c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 4186c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 4196c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 420d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * Set the drawable used for the switch "thumb" - the piece that the user 421d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * can physically touch and drag along the track. 422d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * 423dca510e026e3e75759bac84c3860dc84b83a608fAdam Powell * @param resId Resource ID of a thumb drawable 424d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * 425d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell * @attr ref android.R.styleable#Switch_thumb 426d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell */ 427d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell public void setThumbResource(int resId) { 428d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell setThumbDrawable(getContext().getResources().getDrawable(resId)); 429d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell } 430d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell 431d9c7be6cc7d18f11731e6d7a1037cc294fde3a4bAdam Powell /** 4326c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * Get the drawable used for the switch "thumb" - the piece that the user 4336c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * can physically touch and drag along the track. 4346c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4356c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @return Thumb drawable 4366c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4376c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_thumb 4386c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell */ 4396c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell public Drawable getThumbDrawable() { 4406c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell return mThumbDrawable; 4416c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell } 4426c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell 4436c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell /** 444150176d83023e3c486dba10edebb72af36b4099aChet Haase * Returns the text displayed when the button is in the checked state. 4456c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4466c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_textOn 44712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 44812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public CharSequence getTextOn() { 44912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return mTextOn; 45012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 45112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 45212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 453150176d83023e3c486dba10edebb72af36b4099aChet Haase * Sets the text displayed when the button is in the checked state. 4546c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4556c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_textOn 45612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 45712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void setTextOn(CharSequence textOn) { 45812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextOn = textOn; 45912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell requestLayout(); 46012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 46112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 46212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 463150176d83023e3c486dba10edebb72af36b4099aChet Haase * Returns the text displayed when the button is not in the checked state. 4646c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4656c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_textOff 46612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 46712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public CharSequence getTextOff() { 46812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return mTextOff; 46912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 47012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 47112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 472150176d83023e3c486dba10edebb72af36b4099aChet Haase * Sets the text displayed when the button is not in the checked state. 4736c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * 4746c86e1ba41b56ccb3668dbb044fa348cd4b47d55Adam Powell * @attr ref android.R.styleable#Switch_textOff 47512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 47612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void setTextOff(CharSequence textOff) { 47712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextOff = textOff; 47812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell requestLayout(); 47912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 48012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 48112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 48212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 48312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (mOnLayout == null) { 48412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mOnLayout = makeLayout(mTextOn); 48512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 48612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (mOffLayout == null) { 48712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mOffLayout = makeLayout(mTextOff); 48812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 48912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 49012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTrackDrawable.getPadding(mTempRect); 49112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int maxTextWidth = Math.max(mOnLayout.getWidth(), mOffLayout.getWidth()); 49212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int switchWidth = Math.max(mSwitchMinWidth, 49312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell maxTextWidth * 2 + mThumbTextPadding * 4 + mTempRect.left + mTempRect.right); 49412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int switchHeight = mTrackDrawable.getIntrinsicHeight(); 49512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 49612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mThumbWidth = maxTextWidth + mThumbTextPadding * 2; 49712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 49812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchWidth = switchWidth; 49912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchHeight = switchHeight; 50012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 50112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super.onMeasure(widthMeasureSpec, heightMeasureSpec); 50212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int measuredHeight = getMeasuredHeight(); 50312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (measuredHeight < switchHeight) { 504189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn setMeasuredDimension(getMeasuredWidthAndState(), switchHeight); 50512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 50612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 50712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 50863bce03cc69be4a45230aa8bbd89dbde60681067Svetoslav Ganov @Override 50963bce03cc69be4a45230aa8bbd89dbde60681067Svetoslav Ganov public void onPopulateAccessibilityEvent(AccessibilityEvent event) { 51063bce03cc69be4a45230aa8bbd89dbde60681067Svetoslav Ganov super.onPopulateAccessibilityEvent(event); 511b8c50e8e44bb757d18fc7f069332c186099aca77Svetoslav Ganov Layout layout = isChecked() ? mOnLayout : mOffLayout; 512b8c50e8e44bb757d18fc7f069332c186099aca77Svetoslav Ganov if (layout != null && !TextUtils.isEmpty(layout.getText())) { 513b8c50e8e44bb757d18fc7f069332c186099aca77Svetoslav Ganov event.getText().add(layout.getText()); 5147650259a597dd24137420d32acc35efc44db381eSvetoslav Ganov } 51563bce03cc69be4a45230aa8bbd89dbde60681067Svetoslav Ganov } 51663bce03cc69be4a45230aa8bbd89dbde60681067Svetoslav Ganov 51712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private Layout makeLayout(CharSequence text) { 5184c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler final CharSequence transformed = (mSwitchTransformationMethod != null) 5194c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler ? mSwitchTransformationMethod.getTransformation(text, this) 5204c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler : text; 5214c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler 5224c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler return new StaticLayout(transformed, mTextPaint, 5234c3308de7d51b16b1450c21787b442d84ace3984Daniel Sandler (int) Math.ceil(Layout.getDesiredWidth(transformed, mTextPaint)), 52412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell Layout.Alignment.ALIGN_NORMAL, 1.f, 0, true); 52512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 52612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 52712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 52812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @return true if (x, y) is within the target area of the switch thumb 52912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 53012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private boolean hitThumb(float x, float y) { 53112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mThumbDrawable.getPadding(mTempRect); 53212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int thumbTop = mSwitchTop - mTouchSlop; 53312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int thumbLeft = mSwitchLeft + (int) (mThumbPosition + 0.5f) - mTouchSlop; 53412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int thumbRight = thumbLeft + mThumbWidth + 53512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTempRect.left + mTempRect.right + mTouchSlop; 53612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int thumbBottom = mSwitchBottom + mTouchSlop; 53712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return x > thumbLeft && x < thumbRight && y > thumbTop && y < thumbBottom; 53812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 53912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 54012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 54112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public boolean onTouchEvent(MotionEvent ev) { 54212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mVelocityTracker.addMovement(ev); 54312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int action = ev.getActionMasked(); 54412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switch (action) { 54512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case MotionEvent.ACTION_DOWN: { 54612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final float x = ev.getX(); 54712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final float y = ev.getY(); 548c2ab0d665c9d1c332fbd726abf582a27cf7a6701Gilles Debunne if (isEnabled() && hitThumb(x, y)) { 54912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchMode = TOUCH_MODE_DOWN; 55012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchX = x; 55112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchY = y; 55212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 55312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 55412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 55512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 55612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case MotionEvent.ACTION_MOVE: { 55712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switch (mTouchMode) { 55812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case TOUCH_MODE_IDLE: 55912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell // Didn't target the thumb, treat normally. 56012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 56112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 56212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case TOUCH_MODE_DOWN: { 56312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final float x = ev.getX(); 56412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final float y = ev.getY(); 56512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (Math.abs(x - mTouchX) > mTouchSlop || 56612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell Math.abs(y - mTouchY) > mTouchSlop) { 56712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchMode = TOUCH_MODE_DRAGGING; 56812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell getParent().requestDisallowInterceptTouchEvent(true); 56912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchX = x; 57012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchY = y; 57112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return true; 57212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 57312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 57412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 57512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 57612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case TOUCH_MODE_DRAGGING: { 57712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final float x = ev.getX(); 57812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final float dx = x - mTouchX; 57912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell float newPos = Math.max(0, 58012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell Math.min(mThumbPosition + dx, getThumbScrollRange())); 58112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (newPos != mThumbPosition) { 58212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mThumbPosition = newPos; 58312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchX = x; 58412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell invalidate(); 58512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 58612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return true; 58712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 58812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 58912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 59012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 59112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 59212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case MotionEvent.ACTION_UP: 59312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case MotionEvent.ACTION_CANCEL: { 59412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (mTouchMode == TOUCH_MODE_DRAGGING) { 59512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell stopDrag(ev); 59612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return true; 59712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 59812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchMode = TOUCH_MODE_IDLE; 59912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mVelocityTracker.clear(); 60012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 60112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 60212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 60312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 60412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return super.onTouchEvent(ev); 60512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 60612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 60712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private void cancelSuperTouch(MotionEvent ev) { 60812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell MotionEvent cancel = MotionEvent.obtain(ev); 60912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell cancel.setAction(MotionEvent.ACTION_CANCEL); 61012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super.onTouchEvent(cancel); 61112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell cancel.recycle(); 61212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 61312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 61412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell /** 61512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * Called from onTouchEvent to end a drag operation. 61612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * 61712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell * @param ev Event that triggered the end of drag mode - ACTION_UP or ACTION_CANCEL 61812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell */ 61912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private void stopDrag(MotionEvent ev) { 62012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTouchMode = TOUCH_MODE_IDLE; 621c2ab0d665c9d1c332fbd726abf582a27cf7a6701Gilles Debunne // Up and not canceled, also checks the switch has not been disabled during the drag 622c2ab0d665c9d1c332fbd726abf582a27cf7a6701Gilles Debunne boolean commitChange = ev.getAction() == MotionEvent.ACTION_UP && isEnabled(); 62312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 62412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell cancelSuperTouch(ev); 62512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 62612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (commitChange) { 62712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell boolean newState; 62812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mVelocityTracker.computeCurrentVelocity(1000); 62912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell float xvel = mVelocityTracker.getXVelocity(); 63012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (Math.abs(xvel) > mMinFlingVelocity) { 63128efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio newState = isLayoutRtl() ? (xvel < 0) : (xvel > 0); 63212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } else { 63312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell newState = getTargetCheckedState(); 63412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 63512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell animateThumbToCheckedState(newState); 63612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } else { 63712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell animateThumbToCheckedState(isChecked()); 63812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 63912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 64012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 64112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private void animateThumbToCheckedState(boolean newCheckedState) { 64212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell // TODO animate! 643c3eabb9b6ce7f556313c8e3870d76c5b443f1c51Joe Onorato //float targetPos = newCheckedState ? 0 : getThumbScrollRange(); 644c3eabb9b6ce7f556313c8e3870d76c5b443f1c51Joe Onorato //mThumbPosition = targetPos; 64512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell setChecked(newCheckedState); 64612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 64712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 64812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private boolean getTargetCheckedState() { 64928efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio if (isLayoutRtl()) { 65028efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio return mThumbPosition <= getThumbScrollRange() / 2; 65128efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } else { 65228efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio return mThumbPosition >= getThumbScrollRange() / 2; 65328efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 65428efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 65528efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio 65628efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio private void setThumbPosition(boolean checked) { 65728efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio if (isLayoutRtl()) { 65828efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio mThumbPosition = checked ? 0 : getThumbScrollRange(); 65928efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } else { 66028efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio mThumbPosition = checked ? getThumbScrollRange() : 0; 66128efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 66212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 66312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 66412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 66512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void setChecked(boolean checked) { 66612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super.setChecked(checked); 667acbbd1142db522b15d06d6a1e076463e5c55c8b3Jean-Baptiste Queru setThumbPosition(isChecked()); 668c3eabb9b6ce7f556313c8e3870d76c5b443f1c51Joe Onorato invalidate(); 66912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 67012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 67112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 67212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 67312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super.onLayout(changed, left, top, right, bottom); 67412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 67528efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio setThumbPosition(isChecked()); 67628efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio 67728efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio int switchRight; 67828efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio int switchLeft; 67928efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio 68028efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio if (isLayoutRtl()) { 68128efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio switchLeft = getPaddingLeft(); 68228efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio switchRight = switchLeft + mSwitchWidth; 68328efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } else { 68428efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio switchRight = getWidth() - getPaddingRight(); 68528efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio switchLeft = switchRight - mSwitchWidth; 68628efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 687c3eabb9b6ce7f556313c8e3870d76c5b443f1c51Joe Onorato 68812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int switchTop = 0; 68912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int switchBottom = 0; 69012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switch (getGravity() & Gravity.VERTICAL_GRAVITY_MASK) { 69112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell default: 69212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case Gravity.TOP: 69312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switchTop = getPaddingTop(); 69412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switchBottom = switchTop + mSwitchHeight; 69512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 69612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 69712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case Gravity.CENTER_VERTICAL: 69812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switchTop = (getPaddingTop() + getHeight() - getPaddingBottom()) / 2 - 69912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchHeight / 2; 70012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switchBottom = switchTop + mSwitchHeight; 70112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 70212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 70312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell case Gravity.BOTTOM: 70412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switchBottom = getHeight() - getPaddingBottom(); 70512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell switchTop = switchBottom - mSwitchHeight; 70612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell break; 70712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 70812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 70912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchLeft = switchLeft; 71012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchTop = switchTop; 71112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchBottom = switchBottom; 71212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mSwitchRight = switchRight; 71312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 71412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 71512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 71612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell protected void onDraw(Canvas canvas) { 71712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super.onDraw(canvas); 71812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 71912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell // Draw the switch 72012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int switchLeft = mSwitchLeft; 72112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int switchTop = mSwitchTop; 72212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int switchRight = mSwitchRight; 72312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int switchBottom = mSwitchBottom; 72412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 72512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTrackDrawable.setBounds(switchLeft, switchTop, switchRight, switchBottom); 72612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTrackDrawable.draw(canvas); 72712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 72812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell canvas.save(); 72912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 73012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTrackDrawable.getPadding(mTempRect); 73112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int switchInnerLeft = switchLeft + mTempRect.left; 73212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int switchInnerTop = switchTop + mTempRect.top; 73312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int switchInnerRight = switchRight - mTempRect.right; 73412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int switchInnerBottom = switchBottom - mTempRect.bottom; 73512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell canvas.clipRect(switchInnerLeft, switchTop, switchInnerRight, switchBottom); 73612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 73712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mThumbDrawable.getPadding(mTempRect); 73812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int thumbPos = (int) (mThumbPosition + 0.5f); 73912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int thumbLeft = switchInnerLeft - mTempRect.left + thumbPos; 74012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int thumbRight = switchInnerLeft + thumbPos + mThumbWidth + mTempRect.right; 74112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 74212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mThumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom); 74312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mThumbDrawable.draw(canvas); 74412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 745150176d83023e3c486dba10edebb72af36b4099aChet Haase // mTextColors should not be null, but just in case 746150176d83023e3c486dba10edebb72af36b4099aChet Haase if (mTextColors != null) { 747150176d83023e3c486dba10edebb72af36b4099aChet Haase mTextPaint.setColor(mTextColors.getColorForState(getDrawableState(), 748150176d83023e3c486dba10edebb72af36b4099aChet Haase mTextColors.getDefaultColor())); 749150176d83023e3c486dba10edebb72af36b4099aChet Haase } 75012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTextPaint.drawableState = getDrawableState(); 75112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 75212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell Layout switchText = getTargetCheckedState() ? mOnLayout : mOffLayout; 753be06e3292b295324b3b47d13f9a40787b666309fFabrice Di Meglio if (switchText != null) { 754be06e3292b295324b3b47d13f9a40787b666309fFabrice Di Meglio canvas.translate((thumbLeft + thumbRight) / 2 - switchText.getWidth() / 2, 755be06e3292b295324b3b47d13f9a40787b666309fFabrice Di Meglio (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2); 756be06e3292b295324b3b47d13f9a40787b666309fFabrice Di Meglio switchText.draw(canvas); 757be06e3292b295324b3b47d13f9a40787b666309fFabrice Di Meglio } 75812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 75912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell canvas.restore(); 76012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 76112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 76212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 76328efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio public int getCompoundPaddingLeft() { 76428efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio if (!isLayoutRtl()) { 76528efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio return super.getCompoundPaddingLeft(); 76628efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 76728efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio int padding = super.getCompoundPaddingLeft() + mSwitchWidth; 76828efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio if (!TextUtils.isEmpty(getText())) { 76928efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio padding += mSwitchPadding; 77028efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 77128efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio return padding; 77228efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 77328efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio 77428efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio @Override 77512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public int getCompoundPaddingRight() { 77628efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio if (isLayoutRtl()) { 77728efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio return super.getCompoundPaddingRight(); 77828efba38c07c78f4a349d599b7ad3d7b517c5e97Fabrice Di Meglio } 77912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int padding = super.getCompoundPaddingRight() + mSwitchWidth; 78012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (!TextUtils.isEmpty(getText())) { 78112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell padding += mSwitchPadding; 78212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 78312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return padding; 78412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 78512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 78612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell private int getThumbScrollRange() { 78712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (mTrackDrawable == null) { 78812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return 0; 78912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 79012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTrackDrawable.getPadding(mTempRect); 79112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return mSwitchWidth - mThumbWidth - mTempRect.left - mTempRect.right; 79212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 79312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 79412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 79512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell protected int[] onCreateDrawableState(int extraSpace) { 79612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 79712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell if (isChecked()) { 79812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mergeDrawableStates(drawableState, CHECKED_STATE_SET); 79912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 80012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return drawableState; 80112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 80212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 80312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 80412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell protected void drawableStateChanged() { 80512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super.drawableStateChanged(); 80612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 80712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell int[] myDrawableState = getDrawableState(); 80812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 80912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell // Set the state of the Drawable 810e724ee4b04d121556e9764f72f9b921a0e16392aGilles Debunne // Drawable may be null when checked state is set from XML, from super constructor 811e724ee4b04d121556e9764f72f9b921a0e16392aGilles Debunne if (mThumbDrawable != null) mThumbDrawable.setState(myDrawableState); 812e724ee4b04d121556e9764f72f9b921a0e16392aGilles Debunne if (mTrackDrawable != null) mTrackDrawable.setState(myDrawableState); 81312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 81412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell invalidate(); 81512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 81612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 81712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 81812190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell protected boolean verifyDrawable(Drawable who) { 81912190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell return super.verifyDrawable(who) || who == mThumbDrawable || who == mTrackDrawable; 82012190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 82112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell 82212190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell @Override 82312190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell public void jumpDrawablesToCurrentState() { 82412190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell super.jumpDrawablesToCurrentState(); 82512190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mThumbDrawable.jumpToCurrentState(); 82612190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell mTrackDrawable.jumpToCurrentState(); 82712190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell } 8288a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 8298a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 8308a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 8318a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityEvent(event); 8328a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov event.setClassName(Switch.class.getName()); 8338a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 8348a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 8358a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 8368a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 8378a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityNodeInfo(info); 8388a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov info.setClassName(Switch.class.getName()); 83978bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov CharSequence switchText = isChecked() ? mTextOn : mTextOff; 84078bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov if (!TextUtils.isEmpty(switchText)) { 84178bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov CharSequence oldText = info.getText(); 84278bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov if (TextUtils.isEmpty(oldText)) { 84378bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov info.setText(switchText); 84478bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov } else { 84578bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov StringBuilder newText = new StringBuilder(); 84678bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov newText.append(oldText).append(' ').append(switchText); 84778bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov info.setText(newText); 84878bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov } 84978bcc15b6c5959cc3eb9bbe2459af93451b74a22Svetoslav Ganov } 8508a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 85112190b36a9da88f8db7dbd9ce16d127d76a904b7Adam Powell} 852