1af83b02b1d78576b685a116767d62df824fd285fPin Ting/* 2af83b02b1d78576b685a116767d62df824fd285fPin Ting * Copyright (C) 2012 The Android Open Source Project 3af83b02b1d78576b685a116767d62df824fd285fPin Ting * 4af83b02b1d78576b685a116767d62df824fd285fPin Ting * Licensed under the Apache License, Version 2.0 (the "License"); 5af83b02b1d78576b685a116767d62df824fd285fPin Ting * you may not use this file except in compliance with the License. 6af83b02b1d78576b685a116767d62df824fd285fPin Ting * You may obtain a copy of the License at 7af83b02b1d78576b685a116767d62df824fd285fPin Ting * 8af83b02b1d78576b685a116767d62df824fd285fPin Ting * http://www.apache.org/licenses/LICENSE-2.0 9af83b02b1d78576b685a116767d62df824fd285fPin Ting * 10af83b02b1d78576b685a116767d62df824fd285fPin Ting * Unless required by applicable law or agreed to in writing, software 11af83b02b1d78576b685a116767d62df824fd285fPin Ting * distributed under the License is distributed on an "AS IS" BASIS, 12af83b02b1d78576b685a116767d62df824fd285fPin Ting * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13af83b02b1d78576b685a116767d62df824fd285fPin Ting * See the License for the specific language governing permissions and 14af83b02b1d78576b685a116767d62df824fd285fPin Ting * limitations under the License. 15af83b02b1d78576b685a116767d62df824fd285fPin Ting */ 16af83b02b1d78576b685a116767d62df824fd285fPin Ting 17af83b02b1d78576b685a116767d62df824fd285fPin Tingpackage com.android.camera.ui; 18af83b02b1d78576b685a116767d62df824fd285fPin Ting 192e6df147d54efb9c076647cb0fa3728322bdd16aPin Tingimport android.annotation.TargetApi; 20af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.content.Context; 21af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.content.res.ColorStateList; 22af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.content.res.Resources; 23af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.content.res.TypedArray; 24af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.graphics.Canvas; 25af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.graphics.Paint; 26af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.graphics.Rect; 27af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.graphics.Typeface; 28af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.graphics.drawable.Drawable; 29af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.text.Layout; 30af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.text.StaticLayout; 31af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.text.TextPaint; 32af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.text.TextUtils; 33af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.util.AttributeSet; 34af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.util.DisplayMetrics; 35af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.util.Log; 36af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.util.TypedValue; 37af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.view.Gravity; 38af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.view.MotionEvent; 39af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.view.VelocityTracker; 40af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.view.ViewConfiguration; 41af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.view.accessibility.AccessibilityEvent; 42af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.view.accessibility.AccessibilityNodeInfo; 43af83b02b1d78576b685a116767d62df824fd285fPin Tingimport android.widget.CompoundButton; 44af83b02b1d78576b685a116767d62df824fd285fPin Ting 45af83b02b1d78576b685a116767d62df824fd285fPin Tingimport com.android.camera.R; 462e6df147d54efb9c076647cb0fa3728322bdd16aPin Tingimport com.android.gallery3d.common.ApiHelper; 47af83b02b1d78576b685a116767d62df824fd285fPin Ting 48af83b02b1d78576b685a116767d62df824fd285fPin Tingimport java.util.Arrays; 49af83b02b1d78576b685a116767d62df824fd285fPin Ting 50af83b02b1d78576b685a116767d62df824fd285fPin Ting/** 51af83b02b1d78576b685a116767d62df824fd285fPin Ting * A Switch is a two-state toggle switch widget that can select between two 52af83b02b1d78576b685a116767d62df824fd285fPin Ting * options. The user may drag the "thumb" back and forth to choose the selected option, 53af83b02b1d78576b685a116767d62df824fd285fPin Ting * or simply tap to toggle as if it were a checkbox. 54af83b02b1d78576b685a116767d62df824fd285fPin Ting */ 55af83b02b1d78576b685a116767d62df824fd285fPin Tingpublic class Switch extends CompoundButton { 56af83b02b1d78576b685a116767d62df824fd285fPin Ting private static final int TOUCH_MODE_IDLE = 0; 57af83b02b1d78576b685a116767d62df824fd285fPin Ting private static final int TOUCH_MODE_DOWN = 1; 58af83b02b1d78576b685a116767d62df824fd285fPin Ting private static final int TOUCH_MODE_DRAGGING = 2; 59af83b02b1d78576b685a116767d62df824fd285fPin Ting 60af83b02b1d78576b685a116767d62df824fd285fPin Ting private Drawable mThumbDrawable; 61af83b02b1d78576b685a116767d62df824fd285fPin Ting private Drawable mTrackDrawable; 62af83b02b1d78576b685a116767d62df824fd285fPin Ting private int mThumbTextPadding; 63af83b02b1d78576b685a116767d62df824fd285fPin Ting private int mSwitchMinWidth; 64623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk private int mSwitchTextMaxWidth; 65af83b02b1d78576b685a116767d62df824fd285fPin Ting private int mSwitchPadding; 66af83b02b1d78576b685a116767d62df824fd285fPin Ting private CharSequence mTextOn; 67af83b02b1d78576b685a116767d62df824fd285fPin Ting private CharSequence mTextOff; 68af83b02b1d78576b685a116767d62df824fd285fPin Ting 69af83b02b1d78576b685a116767d62df824fd285fPin Ting private int mTouchMode; 70af83b02b1d78576b685a116767d62df824fd285fPin Ting private int mTouchSlop; 71af83b02b1d78576b685a116767d62df824fd285fPin Ting private float mTouchX; 72af83b02b1d78576b685a116767d62df824fd285fPin Ting private float mTouchY; 73af83b02b1d78576b685a116767d62df824fd285fPin Ting private VelocityTracker mVelocityTracker = VelocityTracker.obtain(); 74af83b02b1d78576b685a116767d62df824fd285fPin Ting private int mMinFlingVelocity; 75af83b02b1d78576b685a116767d62df824fd285fPin Ting 76af83b02b1d78576b685a116767d62df824fd285fPin Ting private float mThumbPosition; 77af83b02b1d78576b685a116767d62df824fd285fPin Ting private int mSwitchWidth; 78af83b02b1d78576b685a116767d62df824fd285fPin Ting private int mSwitchHeight; 79af83b02b1d78576b685a116767d62df824fd285fPin Ting private int mThumbWidth; // Does not include padding 80af83b02b1d78576b685a116767d62df824fd285fPin Ting 81af83b02b1d78576b685a116767d62df824fd285fPin Ting private int mSwitchLeft; 82af83b02b1d78576b685a116767d62df824fd285fPin Ting private int mSwitchTop; 83af83b02b1d78576b685a116767d62df824fd285fPin Ting private int mSwitchRight; 84af83b02b1d78576b685a116767d62df824fd285fPin Ting private int mSwitchBottom; 85af83b02b1d78576b685a116767d62df824fd285fPin Ting 86af83b02b1d78576b685a116767d62df824fd285fPin Ting private TextPaint mTextPaint; 87af83b02b1d78576b685a116767d62df824fd285fPin Ting private ColorStateList mTextColors; 88af83b02b1d78576b685a116767d62df824fd285fPin Ting private Layout mOnLayout; 89af83b02b1d78576b685a116767d62df824fd285fPin Ting private Layout mOffLayout; 90af83b02b1d78576b685a116767d62df824fd285fPin Ting 91af83b02b1d78576b685a116767d62df824fd285fPin Ting @SuppressWarnings("hiding") 92af83b02b1d78576b685a116767d62df824fd285fPin Ting private final Rect mTempRect = new Rect(); 93af83b02b1d78576b685a116767d62df824fd285fPin Ting 94af83b02b1d78576b685a116767d62df824fd285fPin Ting private static final int[] CHECKED_STATE_SET = { 95af83b02b1d78576b685a116767d62df824fd285fPin Ting android.R.attr.state_checked 96af83b02b1d78576b685a116767d62df824fd285fPin Ting }; 97af83b02b1d78576b685a116767d62df824fd285fPin Ting 98af83b02b1d78576b685a116767d62df824fd285fPin Ting /** 99af83b02b1d78576b685a116767d62df824fd285fPin Ting * Construct a new Switch with default styling, overriding specific style 100af83b02b1d78576b685a116767d62df824fd285fPin Ting * attributes as requested. 101af83b02b1d78576b685a116767d62df824fd285fPin Ting * 102af83b02b1d78576b685a116767d62df824fd285fPin Ting * @param context The Context that will determine this widget's theming. 103af83b02b1d78576b685a116767d62df824fd285fPin Ting * @param attrs Specification of attributes that should deviate from default styling. 104af83b02b1d78576b685a116767d62df824fd285fPin Ting */ 105af83b02b1d78576b685a116767d62df824fd285fPin Ting public Switch(Context context, AttributeSet attrs) { 106af83b02b1d78576b685a116767d62df824fd285fPin Ting this(context, attrs, R.attr.switchStyle); 107af83b02b1d78576b685a116767d62df824fd285fPin Ting } 108af83b02b1d78576b685a116767d62df824fd285fPin Ting 109af83b02b1d78576b685a116767d62df824fd285fPin Ting /** 110af83b02b1d78576b685a116767d62df824fd285fPin Ting * Construct a new Switch with a default style determined by the given theme attribute, 111af83b02b1d78576b685a116767d62df824fd285fPin Ting * overriding specific style attributes as requested. 112af83b02b1d78576b685a116767d62df824fd285fPin Ting * 113af83b02b1d78576b685a116767d62df824fd285fPin Ting * @param context The Context that will determine this widget's theming. 114af83b02b1d78576b685a116767d62df824fd285fPin Ting * @param attrs Specification of attributes that should deviate from the default styling. 115af83b02b1d78576b685a116767d62df824fd285fPin Ting * @param defStyle An attribute ID within the active theme containing a reference to the 116af83b02b1d78576b685a116767d62df824fd285fPin Ting * default style for this widget. e.g. android.R.attr.switchStyle. 117af83b02b1d78576b685a116767d62df824fd285fPin Ting */ 118af83b02b1d78576b685a116767d62df824fd285fPin Ting public Switch(Context context, AttributeSet attrs, int defStyle) { 119af83b02b1d78576b685a116767d62df824fd285fPin Ting super(context, attrs, defStyle); 120af83b02b1d78576b685a116767d62df824fd285fPin Ting 121af83b02b1d78576b685a116767d62df824fd285fPin Ting mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); 122af83b02b1d78576b685a116767d62df824fd285fPin Ting Resources res = getResources(); 123af83b02b1d78576b685a116767d62df824fd285fPin Ting DisplayMetrics dm = res.getDisplayMetrics(); 124af83b02b1d78576b685a116767d62df824fd285fPin Ting mTextPaint.density = dm.density; 125af83b02b1d78576b685a116767d62df824fd285fPin Ting mThumbDrawable = res.getDrawable(R.drawable.switch_inner_holo_dark); 126af83b02b1d78576b685a116767d62df824fd285fPin Ting mTrackDrawable = res.getDrawable(R.drawable.switch_track_holo_dark); 127af83b02b1d78576b685a116767d62df824fd285fPin Ting mTextOn = res.getString(R.string.capital_on); 128af83b02b1d78576b685a116767d62df824fd285fPin Ting mTextOff = res.getString(R.string.capital_off); 129af83b02b1d78576b685a116767d62df824fd285fPin Ting mThumbTextPadding = res.getDimensionPixelSize(R.dimen.thumb_text_padding); 130af83b02b1d78576b685a116767d62df824fd285fPin Ting mSwitchMinWidth = res.getDimensionPixelSize(R.dimen.switch_min_width); 131623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk mSwitchTextMaxWidth = res.getDimensionPixelSize(R.dimen.switch_text_max_width); 132af83b02b1d78576b685a116767d62df824fd285fPin Ting mSwitchPadding = res.getDimensionPixelSize(R.dimen.switch_padding); 133af83b02b1d78576b685a116767d62df824fd285fPin Ting setSwitchTextAppearance(context, android.R.style.TextAppearance_Holo_Small); 134af83b02b1d78576b685a116767d62df824fd285fPin Ting 135af83b02b1d78576b685a116767d62df824fd285fPin Ting ViewConfiguration config = ViewConfiguration.get(context); 136af83b02b1d78576b685a116767d62df824fd285fPin Ting mTouchSlop = config.getScaledTouchSlop(); 137af83b02b1d78576b685a116767d62df824fd285fPin Ting mMinFlingVelocity = config.getScaledMinimumFlingVelocity(); 138af83b02b1d78576b685a116767d62df824fd285fPin Ting 139af83b02b1d78576b685a116767d62df824fd285fPin Ting // Refresh display with current params 140af83b02b1d78576b685a116767d62df824fd285fPin Ting refreshDrawableState(); 141af83b02b1d78576b685a116767d62df824fd285fPin Ting setChecked(isChecked()); 142af83b02b1d78576b685a116767d62df824fd285fPin Ting } 143af83b02b1d78576b685a116767d62df824fd285fPin Ting 144af83b02b1d78576b685a116767d62df824fd285fPin Ting /** 145af83b02b1d78576b685a116767d62df824fd285fPin Ting * Sets the switch text color, size, style, hint color, and highlight color 146af83b02b1d78576b685a116767d62df824fd285fPin Ting * from the specified TextAppearance resource. 147af83b02b1d78576b685a116767d62df824fd285fPin Ting */ 148af83b02b1d78576b685a116767d62df824fd285fPin Ting public void setSwitchTextAppearance(Context context, int resid) { 149af83b02b1d78576b685a116767d62df824fd285fPin Ting Resources res = getResources(); 150af83b02b1d78576b685a116767d62df824fd285fPin Ting mTextColors = getTextColors(); 151af83b02b1d78576b685a116767d62df824fd285fPin Ting int ts = res.getDimensionPixelSize(R.dimen.thumb_text_size); 152af83b02b1d78576b685a116767d62df824fd285fPin Ting if (ts != mTextPaint.getTextSize()) { 153af83b02b1d78576b685a116767d62df824fd285fPin Ting mTextPaint.setTextSize(ts); 154af83b02b1d78576b685a116767d62df824fd285fPin Ting requestLayout(); 155af83b02b1d78576b685a116767d62df824fd285fPin Ting } 156af83b02b1d78576b685a116767d62df824fd285fPin Ting } 157af83b02b1d78576b685a116767d62df824fd285fPin Ting 158af83b02b1d78576b685a116767d62df824fd285fPin Ting @Override 159af83b02b1d78576b685a116767d62df824fd285fPin Ting public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 160623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk int widthMode = MeasureSpec.getMode(widthMeasureSpec); 161623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk int widthSize = MeasureSpec.getSize(widthMeasureSpec); 162af83b02b1d78576b685a116767d62df824fd285fPin Ting if (mOnLayout == null) { 163623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk mOnLayout = makeLayout(mTextOn, mSwitchTextMaxWidth); 164af83b02b1d78576b685a116767d62df824fd285fPin Ting } 165af83b02b1d78576b685a116767d62df824fd285fPin Ting if (mOffLayout == null) { 166623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk mOffLayout = makeLayout(mTextOff, mSwitchTextMaxWidth); 167af83b02b1d78576b685a116767d62df824fd285fPin Ting } 168af83b02b1d78576b685a116767d62df824fd285fPin Ting 169af83b02b1d78576b685a116767d62df824fd285fPin Ting mTrackDrawable.getPadding(mTempRect); 170623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk final int maxTextWidth = Math.min(mSwitchTextMaxWidth, 171623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk Math.max(mOnLayout.getWidth(), mOffLayout.getWidth())); 172af83b02b1d78576b685a116767d62df824fd285fPin Ting final int switchWidth = Math.max(mSwitchMinWidth, 173af83b02b1d78576b685a116767d62df824fd285fPin Ting maxTextWidth * 2 + mThumbTextPadding * 4 + mTempRect.left + mTempRect.right); 174af83b02b1d78576b685a116767d62df824fd285fPin Ting final int switchHeight = mTrackDrawable.getIntrinsicHeight(); 175af83b02b1d78576b685a116767d62df824fd285fPin Ting 176af83b02b1d78576b685a116767d62df824fd285fPin Ting mThumbWidth = maxTextWidth + mThumbTextPadding * 2; 177af83b02b1d78576b685a116767d62df824fd285fPin Ting 178af83b02b1d78576b685a116767d62df824fd285fPin Ting mSwitchWidth = switchWidth; 179af83b02b1d78576b685a116767d62df824fd285fPin Ting mSwitchHeight = switchHeight; 180af83b02b1d78576b685a116767d62df824fd285fPin Ting 181af83b02b1d78576b685a116767d62df824fd285fPin Ting super.onMeasure(widthMeasureSpec, heightMeasureSpec); 182af83b02b1d78576b685a116767d62df824fd285fPin Ting final int measuredHeight = getMeasuredHeight(); 183623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk final int measuredWidth = getMeasuredWidth(); 184af83b02b1d78576b685a116767d62df824fd285fPin Ting if (measuredHeight < switchHeight) { 185623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk setMeasuredDimension(measuredWidth, switchHeight); 186af83b02b1d78576b685a116767d62df824fd285fPin Ting } 187af83b02b1d78576b685a116767d62df824fd285fPin Ting } 188af83b02b1d78576b685a116767d62df824fd285fPin Ting 1892e6df147d54efb9c076647cb0fa3728322bdd16aPin Ting @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH) 190af83b02b1d78576b685a116767d62df824fd285fPin Ting @Override 191af83b02b1d78576b685a116767d62df824fd285fPin Ting public void onPopulateAccessibilityEvent(AccessibilityEvent event) { 192af83b02b1d78576b685a116767d62df824fd285fPin Ting super.onPopulateAccessibilityEvent(event); 193af83b02b1d78576b685a116767d62df824fd285fPin Ting CharSequence text = isChecked() ? mOnLayout.getText() : mOffLayout.getText(); 194af83b02b1d78576b685a116767d62df824fd285fPin Ting if (!TextUtils.isEmpty(text)) { 195af83b02b1d78576b685a116767d62df824fd285fPin Ting event.getText().add(text); 196af83b02b1d78576b685a116767d62df824fd285fPin Ting } 197af83b02b1d78576b685a116767d62df824fd285fPin Ting } 198af83b02b1d78576b685a116767d62df824fd285fPin Ting 199623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk private Layout makeLayout(CharSequence text, int maxWidth) { 200623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk int actual_width = (int) Math.ceil(Layout.getDesiredWidth(text, mTextPaint)); 201623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk StaticLayout l = new StaticLayout(text, 0, text.length(), mTextPaint, 202623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk actual_width, 203623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk Layout.Alignment.ALIGN_NORMAL, 1.f, 0, true, 204623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk TextUtils.TruncateAt.END, 205623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk (int) Math.min(actual_width, maxWidth)); 206623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk return l; 207af83b02b1d78576b685a116767d62df824fd285fPin Ting } 208af83b02b1d78576b685a116767d62df824fd285fPin Ting 209af83b02b1d78576b685a116767d62df824fd285fPin Ting /** 210af83b02b1d78576b685a116767d62df824fd285fPin Ting * @return true if (x, y) is within the target area of the switch thumb 211af83b02b1d78576b685a116767d62df824fd285fPin Ting */ 212af83b02b1d78576b685a116767d62df824fd285fPin Ting private boolean hitThumb(float x, float y) { 213af83b02b1d78576b685a116767d62df824fd285fPin Ting mThumbDrawable.getPadding(mTempRect); 214af83b02b1d78576b685a116767d62df824fd285fPin Ting final int thumbTop = mSwitchTop - mTouchSlop; 215af83b02b1d78576b685a116767d62df824fd285fPin Ting final int thumbLeft = mSwitchLeft + (int) (mThumbPosition + 0.5f) - mTouchSlop; 216af83b02b1d78576b685a116767d62df824fd285fPin Ting final int thumbRight = thumbLeft + mThumbWidth + 217af83b02b1d78576b685a116767d62df824fd285fPin Ting mTempRect.left + mTempRect.right + mTouchSlop; 218af83b02b1d78576b685a116767d62df824fd285fPin Ting final int thumbBottom = mSwitchBottom + mTouchSlop; 219af83b02b1d78576b685a116767d62df824fd285fPin Ting return x > thumbLeft && x < thumbRight && y > thumbTop && y < thumbBottom; 220af83b02b1d78576b685a116767d62df824fd285fPin Ting } 221af83b02b1d78576b685a116767d62df824fd285fPin Ting 222af83b02b1d78576b685a116767d62df824fd285fPin Ting @Override 223af83b02b1d78576b685a116767d62df824fd285fPin Ting public boolean onTouchEvent(MotionEvent ev) { 224af83b02b1d78576b685a116767d62df824fd285fPin Ting mVelocityTracker.addMovement(ev); 225af83b02b1d78576b685a116767d62df824fd285fPin Ting final int action = ev.getActionMasked(); 226af83b02b1d78576b685a116767d62df824fd285fPin Ting switch (action) { 227af83b02b1d78576b685a116767d62df824fd285fPin Ting case MotionEvent.ACTION_DOWN: { 228af83b02b1d78576b685a116767d62df824fd285fPin Ting final float x = ev.getX(); 229af83b02b1d78576b685a116767d62df824fd285fPin Ting final float y = ev.getY(); 230af83b02b1d78576b685a116767d62df824fd285fPin Ting if (isEnabled() && hitThumb(x, y)) { 231af83b02b1d78576b685a116767d62df824fd285fPin Ting mTouchMode = TOUCH_MODE_DOWN; 232af83b02b1d78576b685a116767d62df824fd285fPin Ting mTouchX = x; 233af83b02b1d78576b685a116767d62df824fd285fPin Ting mTouchY = y; 234af83b02b1d78576b685a116767d62df824fd285fPin Ting } 235af83b02b1d78576b685a116767d62df824fd285fPin Ting break; 236af83b02b1d78576b685a116767d62df824fd285fPin Ting } 237af83b02b1d78576b685a116767d62df824fd285fPin Ting 238af83b02b1d78576b685a116767d62df824fd285fPin Ting case MotionEvent.ACTION_MOVE: { 239af83b02b1d78576b685a116767d62df824fd285fPin Ting switch (mTouchMode) { 240af83b02b1d78576b685a116767d62df824fd285fPin Ting case TOUCH_MODE_IDLE: 241af83b02b1d78576b685a116767d62df824fd285fPin Ting // Didn't target the thumb, treat normally. 242af83b02b1d78576b685a116767d62df824fd285fPin Ting break; 243af83b02b1d78576b685a116767d62df824fd285fPin Ting 244af83b02b1d78576b685a116767d62df824fd285fPin Ting case TOUCH_MODE_DOWN: { 245af83b02b1d78576b685a116767d62df824fd285fPin Ting final float x = ev.getX(); 246af83b02b1d78576b685a116767d62df824fd285fPin Ting final float y = ev.getY(); 247af83b02b1d78576b685a116767d62df824fd285fPin Ting if (Math.abs(x - mTouchX) > mTouchSlop || 248af83b02b1d78576b685a116767d62df824fd285fPin Ting Math.abs(y - mTouchY) > mTouchSlop) { 249af83b02b1d78576b685a116767d62df824fd285fPin Ting mTouchMode = TOUCH_MODE_DRAGGING; 250af83b02b1d78576b685a116767d62df824fd285fPin Ting getParent().requestDisallowInterceptTouchEvent(true); 251af83b02b1d78576b685a116767d62df824fd285fPin Ting mTouchX = x; 252af83b02b1d78576b685a116767d62df824fd285fPin Ting mTouchY = y; 253af83b02b1d78576b685a116767d62df824fd285fPin Ting return true; 254af83b02b1d78576b685a116767d62df824fd285fPin Ting } 255af83b02b1d78576b685a116767d62df824fd285fPin Ting break; 256af83b02b1d78576b685a116767d62df824fd285fPin Ting } 257af83b02b1d78576b685a116767d62df824fd285fPin Ting 258af83b02b1d78576b685a116767d62df824fd285fPin Ting case TOUCH_MODE_DRAGGING: { 259af83b02b1d78576b685a116767d62df824fd285fPin Ting final float x = ev.getX(); 260af83b02b1d78576b685a116767d62df824fd285fPin Ting final float dx = x - mTouchX; 261af83b02b1d78576b685a116767d62df824fd285fPin Ting float newPos = Math.max(0, 262af83b02b1d78576b685a116767d62df824fd285fPin Ting Math.min(mThumbPosition + dx, getThumbScrollRange())); 263af83b02b1d78576b685a116767d62df824fd285fPin Ting if (newPos != mThumbPosition) { 264af83b02b1d78576b685a116767d62df824fd285fPin Ting mThumbPosition = newPos; 265af83b02b1d78576b685a116767d62df824fd285fPin Ting mTouchX = x; 266af83b02b1d78576b685a116767d62df824fd285fPin Ting invalidate(); 267af83b02b1d78576b685a116767d62df824fd285fPin Ting } 268af83b02b1d78576b685a116767d62df824fd285fPin Ting return true; 269af83b02b1d78576b685a116767d62df824fd285fPin Ting } 270af83b02b1d78576b685a116767d62df824fd285fPin Ting } 271af83b02b1d78576b685a116767d62df824fd285fPin Ting break; 272af83b02b1d78576b685a116767d62df824fd285fPin Ting } 273af83b02b1d78576b685a116767d62df824fd285fPin Ting 274af83b02b1d78576b685a116767d62df824fd285fPin Ting case MotionEvent.ACTION_UP: 275af83b02b1d78576b685a116767d62df824fd285fPin Ting case MotionEvent.ACTION_CANCEL: { 276af83b02b1d78576b685a116767d62df824fd285fPin Ting if (mTouchMode == TOUCH_MODE_DRAGGING) { 277af83b02b1d78576b685a116767d62df824fd285fPin Ting stopDrag(ev); 278af83b02b1d78576b685a116767d62df824fd285fPin Ting return true; 279af83b02b1d78576b685a116767d62df824fd285fPin Ting } 280af83b02b1d78576b685a116767d62df824fd285fPin Ting mTouchMode = TOUCH_MODE_IDLE; 281af83b02b1d78576b685a116767d62df824fd285fPin Ting mVelocityTracker.clear(); 282af83b02b1d78576b685a116767d62df824fd285fPin Ting break; 283af83b02b1d78576b685a116767d62df824fd285fPin Ting } 284af83b02b1d78576b685a116767d62df824fd285fPin Ting } 285af83b02b1d78576b685a116767d62df824fd285fPin Ting 286af83b02b1d78576b685a116767d62df824fd285fPin Ting return super.onTouchEvent(ev); 287af83b02b1d78576b685a116767d62df824fd285fPin Ting } 288af83b02b1d78576b685a116767d62df824fd285fPin Ting 289af83b02b1d78576b685a116767d62df824fd285fPin Ting private void cancelSuperTouch(MotionEvent ev) { 290af83b02b1d78576b685a116767d62df824fd285fPin Ting MotionEvent cancel = MotionEvent.obtain(ev); 291af83b02b1d78576b685a116767d62df824fd285fPin Ting cancel.setAction(MotionEvent.ACTION_CANCEL); 292af83b02b1d78576b685a116767d62df824fd285fPin Ting super.onTouchEvent(cancel); 293af83b02b1d78576b685a116767d62df824fd285fPin Ting cancel.recycle(); 294af83b02b1d78576b685a116767d62df824fd285fPin Ting } 295af83b02b1d78576b685a116767d62df824fd285fPin Ting 296af83b02b1d78576b685a116767d62df824fd285fPin Ting /** 297af83b02b1d78576b685a116767d62df824fd285fPin Ting * Called from onTouchEvent to end a drag operation. 298af83b02b1d78576b685a116767d62df824fd285fPin Ting * 299af83b02b1d78576b685a116767d62df824fd285fPin Ting * @param ev Event that triggered the end of drag mode - ACTION_UP or ACTION_CANCEL 300af83b02b1d78576b685a116767d62df824fd285fPin Ting */ 301af83b02b1d78576b685a116767d62df824fd285fPin Ting private void stopDrag(MotionEvent ev) { 302af83b02b1d78576b685a116767d62df824fd285fPin Ting mTouchMode = TOUCH_MODE_IDLE; 303af83b02b1d78576b685a116767d62df824fd285fPin Ting // Up and not canceled, also checks the switch has not been disabled during the drag 304af83b02b1d78576b685a116767d62df824fd285fPin Ting boolean commitChange = ev.getAction() == MotionEvent.ACTION_UP && isEnabled(); 305af83b02b1d78576b685a116767d62df824fd285fPin Ting 306af83b02b1d78576b685a116767d62df824fd285fPin Ting cancelSuperTouch(ev); 307af83b02b1d78576b685a116767d62df824fd285fPin Ting 308af83b02b1d78576b685a116767d62df824fd285fPin Ting if (commitChange) { 309af83b02b1d78576b685a116767d62df824fd285fPin Ting boolean newState; 310af83b02b1d78576b685a116767d62df824fd285fPin Ting mVelocityTracker.computeCurrentVelocity(1000); 311af83b02b1d78576b685a116767d62df824fd285fPin Ting float xvel = mVelocityTracker.getXVelocity(); 312af83b02b1d78576b685a116767d62df824fd285fPin Ting if (Math.abs(xvel) > mMinFlingVelocity) { 313af83b02b1d78576b685a116767d62df824fd285fPin Ting newState = xvel > 0; 314af83b02b1d78576b685a116767d62df824fd285fPin Ting } else { 315af83b02b1d78576b685a116767d62df824fd285fPin Ting newState = getTargetCheckedState(); 316af83b02b1d78576b685a116767d62df824fd285fPin Ting } 317af83b02b1d78576b685a116767d62df824fd285fPin Ting animateThumbToCheckedState(newState); 318af83b02b1d78576b685a116767d62df824fd285fPin Ting } else { 319af83b02b1d78576b685a116767d62df824fd285fPin Ting animateThumbToCheckedState(isChecked()); 320af83b02b1d78576b685a116767d62df824fd285fPin Ting } 321af83b02b1d78576b685a116767d62df824fd285fPin Ting } 322af83b02b1d78576b685a116767d62df824fd285fPin Ting 323af83b02b1d78576b685a116767d62df824fd285fPin Ting private void animateThumbToCheckedState(boolean newCheckedState) { 324af83b02b1d78576b685a116767d62df824fd285fPin Ting setChecked(newCheckedState); 325af83b02b1d78576b685a116767d62df824fd285fPin Ting } 326af83b02b1d78576b685a116767d62df824fd285fPin Ting 327af83b02b1d78576b685a116767d62df824fd285fPin Ting private boolean getTargetCheckedState() { 328af83b02b1d78576b685a116767d62df824fd285fPin Ting return mThumbPosition >= getThumbScrollRange() / 2; 329af83b02b1d78576b685a116767d62df824fd285fPin Ting } 330af83b02b1d78576b685a116767d62df824fd285fPin Ting 331af83b02b1d78576b685a116767d62df824fd285fPin Ting private void setThumbPosition(boolean checked) { 332af83b02b1d78576b685a116767d62df824fd285fPin Ting mThumbPosition = checked ? getThumbScrollRange() : 0; 333af83b02b1d78576b685a116767d62df824fd285fPin Ting } 334af83b02b1d78576b685a116767d62df824fd285fPin Ting 335af83b02b1d78576b685a116767d62df824fd285fPin Ting @Override 336af83b02b1d78576b685a116767d62df824fd285fPin Ting public void setChecked(boolean checked) { 337af83b02b1d78576b685a116767d62df824fd285fPin Ting super.setChecked(checked); 338af83b02b1d78576b685a116767d62df824fd285fPin Ting setThumbPosition(checked); 339af83b02b1d78576b685a116767d62df824fd285fPin Ting invalidate(); 340af83b02b1d78576b685a116767d62df824fd285fPin Ting } 341af83b02b1d78576b685a116767d62df824fd285fPin Ting 342af83b02b1d78576b685a116767d62df824fd285fPin Ting @Override 343af83b02b1d78576b685a116767d62df824fd285fPin Ting protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 344af83b02b1d78576b685a116767d62df824fd285fPin Ting super.onLayout(changed, left, top, right, bottom); 345af83b02b1d78576b685a116767d62df824fd285fPin Ting 346af83b02b1d78576b685a116767d62df824fd285fPin Ting setThumbPosition(isChecked()); 347af83b02b1d78576b685a116767d62df824fd285fPin Ting 348af83b02b1d78576b685a116767d62df824fd285fPin Ting int switchRight; 349af83b02b1d78576b685a116767d62df824fd285fPin Ting int switchLeft; 350af83b02b1d78576b685a116767d62df824fd285fPin Ting 351af83b02b1d78576b685a116767d62df824fd285fPin Ting switchRight = getWidth() - getPaddingRight(); 352af83b02b1d78576b685a116767d62df824fd285fPin Ting switchLeft = switchRight - mSwitchWidth; 353af83b02b1d78576b685a116767d62df824fd285fPin Ting 354af83b02b1d78576b685a116767d62df824fd285fPin Ting int switchTop = 0; 355af83b02b1d78576b685a116767d62df824fd285fPin Ting int switchBottom = 0; 356af83b02b1d78576b685a116767d62df824fd285fPin Ting switch (getGravity() & Gravity.VERTICAL_GRAVITY_MASK) { 357af83b02b1d78576b685a116767d62df824fd285fPin Ting default: 358af83b02b1d78576b685a116767d62df824fd285fPin Ting case Gravity.TOP: 359af83b02b1d78576b685a116767d62df824fd285fPin Ting switchTop = getPaddingTop(); 360af83b02b1d78576b685a116767d62df824fd285fPin Ting switchBottom = switchTop + mSwitchHeight; 361af83b02b1d78576b685a116767d62df824fd285fPin Ting break; 362af83b02b1d78576b685a116767d62df824fd285fPin Ting 363af83b02b1d78576b685a116767d62df824fd285fPin Ting case Gravity.CENTER_VERTICAL: 364af83b02b1d78576b685a116767d62df824fd285fPin Ting switchTop = (getPaddingTop() + getHeight() - getPaddingBottom()) / 2 - 365af83b02b1d78576b685a116767d62df824fd285fPin Ting mSwitchHeight / 2; 366af83b02b1d78576b685a116767d62df824fd285fPin Ting switchBottom = switchTop + mSwitchHeight; 367af83b02b1d78576b685a116767d62df824fd285fPin Ting break; 368af83b02b1d78576b685a116767d62df824fd285fPin Ting 369af83b02b1d78576b685a116767d62df824fd285fPin Ting case Gravity.BOTTOM: 370af83b02b1d78576b685a116767d62df824fd285fPin Ting switchBottom = getHeight() - getPaddingBottom(); 371af83b02b1d78576b685a116767d62df824fd285fPin Ting switchTop = switchBottom - mSwitchHeight; 372af83b02b1d78576b685a116767d62df824fd285fPin Ting break; 373af83b02b1d78576b685a116767d62df824fd285fPin Ting } 374af83b02b1d78576b685a116767d62df824fd285fPin Ting 375af83b02b1d78576b685a116767d62df824fd285fPin Ting mSwitchLeft = switchLeft; 376af83b02b1d78576b685a116767d62df824fd285fPin Ting mSwitchTop = switchTop; 377af83b02b1d78576b685a116767d62df824fd285fPin Ting mSwitchBottom = switchBottom; 378af83b02b1d78576b685a116767d62df824fd285fPin Ting mSwitchRight = switchRight; 379af83b02b1d78576b685a116767d62df824fd285fPin Ting } 380af83b02b1d78576b685a116767d62df824fd285fPin Ting 381af83b02b1d78576b685a116767d62df824fd285fPin Ting @Override 382af83b02b1d78576b685a116767d62df824fd285fPin Ting protected void onDraw(Canvas canvas) { 383af83b02b1d78576b685a116767d62df824fd285fPin Ting super.onDraw(canvas); 384af83b02b1d78576b685a116767d62df824fd285fPin Ting 385af83b02b1d78576b685a116767d62df824fd285fPin Ting // Draw the switch 386af83b02b1d78576b685a116767d62df824fd285fPin Ting int switchLeft = mSwitchLeft; 387af83b02b1d78576b685a116767d62df824fd285fPin Ting int switchTop = mSwitchTop; 388af83b02b1d78576b685a116767d62df824fd285fPin Ting int switchRight = mSwitchRight; 389af83b02b1d78576b685a116767d62df824fd285fPin Ting int switchBottom = mSwitchBottom; 390af83b02b1d78576b685a116767d62df824fd285fPin Ting 391af83b02b1d78576b685a116767d62df824fd285fPin Ting mTrackDrawable.setBounds(switchLeft, switchTop, switchRight, switchBottom); 392af83b02b1d78576b685a116767d62df824fd285fPin Ting mTrackDrawable.draw(canvas); 393af83b02b1d78576b685a116767d62df824fd285fPin Ting 394af83b02b1d78576b685a116767d62df824fd285fPin Ting canvas.save(); 395af83b02b1d78576b685a116767d62df824fd285fPin Ting 396af83b02b1d78576b685a116767d62df824fd285fPin Ting mTrackDrawable.getPadding(mTempRect); 397af83b02b1d78576b685a116767d62df824fd285fPin Ting int switchInnerLeft = switchLeft + mTempRect.left; 398af83b02b1d78576b685a116767d62df824fd285fPin Ting int switchInnerTop = switchTop + mTempRect.top; 399af83b02b1d78576b685a116767d62df824fd285fPin Ting int switchInnerRight = switchRight - mTempRect.right; 400af83b02b1d78576b685a116767d62df824fd285fPin Ting int switchInnerBottom = switchBottom - mTempRect.bottom; 401af83b02b1d78576b685a116767d62df824fd285fPin Ting canvas.clipRect(switchInnerLeft, switchTop, switchInnerRight, switchBottom); 402af83b02b1d78576b685a116767d62df824fd285fPin Ting 403af83b02b1d78576b685a116767d62df824fd285fPin Ting mThumbDrawable.getPadding(mTempRect); 404af83b02b1d78576b685a116767d62df824fd285fPin Ting final int thumbPos = (int) (mThumbPosition + 0.5f); 405af83b02b1d78576b685a116767d62df824fd285fPin Ting int thumbLeft = switchInnerLeft - mTempRect.left + thumbPos; 406af83b02b1d78576b685a116767d62df824fd285fPin Ting int thumbRight = switchInnerLeft + thumbPos + mThumbWidth + mTempRect.right; 407af83b02b1d78576b685a116767d62df824fd285fPin Ting 408af83b02b1d78576b685a116767d62df824fd285fPin Ting mThumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom); 409af83b02b1d78576b685a116767d62df824fd285fPin Ting mThumbDrawable.draw(canvas); 410af83b02b1d78576b685a116767d62df824fd285fPin Ting 411af83b02b1d78576b685a116767d62df824fd285fPin Ting // mTextColors should not be null, but just in case 412af83b02b1d78576b685a116767d62df824fd285fPin Ting if (mTextColors != null) { 413af83b02b1d78576b685a116767d62df824fd285fPin Ting mTextPaint.setColor(mTextColors.getColorForState(getDrawableState(), 414af83b02b1d78576b685a116767d62df824fd285fPin Ting mTextColors.getDefaultColor())); 415af83b02b1d78576b685a116767d62df824fd285fPin Ting } 416af83b02b1d78576b685a116767d62df824fd285fPin Ting mTextPaint.drawableState = getDrawableState(); 417af83b02b1d78576b685a116767d62df824fd285fPin Ting 418af83b02b1d78576b685a116767d62df824fd285fPin Ting Layout switchText = getTargetCheckedState() ? mOnLayout : mOffLayout; 419af83b02b1d78576b685a116767d62df824fd285fPin Ting 420623cb339185cbab100fb05c5d9ab3c8c795e5339Ruben Brunk canvas.translate((thumbLeft + thumbRight) / 2 - switchText.getEllipsizedWidth() / 2, 421af83b02b1d78576b685a116767d62df824fd285fPin Ting (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2); 422af83b02b1d78576b685a116767d62df824fd285fPin Ting switchText.draw(canvas); 423af83b02b1d78576b685a116767d62df824fd285fPin Ting 424af83b02b1d78576b685a116767d62df824fd285fPin Ting canvas.restore(); 425af83b02b1d78576b685a116767d62df824fd285fPin Ting } 426af83b02b1d78576b685a116767d62df824fd285fPin Ting 427af83b02b1d78576b685a116767d62df824fd285fPin Ting @Override 428af83b02b1d78576b685a116767d62df824fd285fPin Ting public int getCompoundPaddingRight() { 429af83b02b1d78576b685a116767d62df824fd285fPin Ting int padding = super.getCompoundPaddingRight() + mSwitchWidth; 430af83b02b1d78576b685a116767d62df824fd285fPin Ting if (!TextUtils.isEmpty(getText())) { 431af83b02b1d78576b685a116767d62df824fd285fPin Ting padding += mSwitchPadding; 432af83b02b1d78576b685a116767d62df824fd285fPin Ting } 433af83b02b1d78576b685a116767d62df824fd285fPin Ting return padding; 434af83b02b1d78576b685a116767d62df824fd285fPin Ting } 435af83b02b1d78576b685a116767d62df824fd285fPin Ting 436af83b02b1d78576b685a116767d62df824fd285fPin Ting private int getThumbScrollRange() { 437af83b02b1d78576b685a116767d62df824fd285fPin Ting if (mTrackDrawable == null) { 438af83b02b1d78576b685a116767d62df824fd285fPin Ting return 0; 439af83b02b1d78576b685a116767d62df824fd285fPin Ting } 440af83b02b1d78576b685a116767d62df824fd285fPin Ting mTrackDrawable.getPadding(mTempRect); 441af83b02b1d78576b685a116767d62df824fd285fPin Ting return mSwitchWidth - mThumbWidth - mTempRect.left - mTempRect.right; 442af83b02b1d78576b685a116767d62df824fd285fPin Ting } 443af83b02b1d78576b685a116767d62df824fd285fPin Ting 444af83b02b1d78576b685a116767d62df824fd285fPin Ting @Override 445af83b02b1d78576b685a116767d62df824fd285fPin Ting protected int[] onCreateDrawableState(int extraSpace) { 446af83b02b1d78576b685a116767d62df824fd285fPin Ting final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 447af83b02b1d78576b685a116767d62df824fd285fPin Ting 448af83b02b1d78576b685a116767d62df824fd285fPin Ting if (isChecked()) { 449af83b02b1d78576b685a116767d62df824fd285fPin Ting mergeDrawableStates(drawableState, CHECKED_STATE_SET); 450af83b02b1d78576b685a116767d62df824fd285fPin Ting } 451af83b02b1d78576b685a116767d62df824fd285fPin Ting return drawableState; 452af83b02b1d78576b685a116767d62df824fd285fPin Ting } 453af83b02b1d78576b685a116767d62df824fd285fPin Ting 454af83b02b1d78576b685a116767d62df824fd285fPin Ting @Override 455af83b02b1d78576b685a116767d62df824fd285fPin Ting protected void drawableStateChanged() { 456af83b02b1d78576b685a116767d62df824fd285fPin Ting super.drawableStateChanged(); 457af83b02b1d78576b685a116767d62df824fd285fPin Ting 458af83b02b1d78576b685a116767d62df824fd285fPin Ting int[] myDrawableState = getDrawableState(); 459af83b02b1d78576b685a116767d62df824fd285fPin Ting 460af83b02b1d78576b685a116767d62df824fd285fPin Ting // Set the state of the Drawable 461af83b02b1d78576b685a116767d62df824fd285fPin Ting // Drawable may be null when checked state is set from XML, from super constructor 462af83b02b1d78576b685a116767d62df824fd285fPin Ting if (mThumbDrawable != null) mThumbDrawable.setState(myDrawableState); 463af83b02b1d78576b685a116767d62df824fd285fPin Ting if (mTrackDrawable != null) mTrackDrawable.setState(myDrawableState); 464af83b02b1d78576b685a116767d62df824fd285fPin Ting 465af83b02b1d78576b685a116767d62df824fd285fPin Ting invalidate(); 466af83b02b1d78576b685a116767d62df824fd285fPin Ting } 467af83b02b1d78576b685a116767d62df824fd285fPin Ting 468af83b02b1d78576b685a116767d62df824fd285fPin Ting @Override 469af83b02b1d78576b685a116767d62df824fd285fPin Ting protected boolean verifyDrawable(Drawable who) { 470af83b02b1d78576b685a116767d62df824fd285fPin Ting return super.verifyDrawable(who) || who == mThumbDrawable || who == mTrackDrawable; 471af83b02b1d78576b685a116767d62df824fd285fPin Ting } 472af83b02b1d78576b685a116767d62df824fd285fPin Ting 4732e6df147d54efb9c076647cb0fa3728322bdd16aPin Ting @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB) 474af83b02b1d78576b685a116767d62df824fd285fPin Ting @Override 475af83b02b1d78576b685a116767d62df824fd285fPin Ting public void jumpDrawablesToCurrentState() { 476af83b02b1d78576b685a116767d62df824fd285fPin Ting super.jumpDrawablesToCurrentState(); 477af83b02b1d78576b685a116767d62df824fd285fPin Ting mThumbDrawable.jumpToCurrentState(); 478af83b02b1d78576b685a116767d62df824fd285fPin Ting mTrackDrawable.jumpToCurrentState(); 479af83b02b1d78576b685a116767d62df824fd285fPin Ting } 480af83b02b1d78576b685a116767d62df824fd285fPin Ting 4812e6df147d54efb9c076647cb0fa3728322bdd16aPin Ting @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH) 482af83b02b1d78576b685a116767d62df824fd285fPin Ting @Override 483af83b02b1d78576b685a116767d62df824fd285fPin Ting public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 484af83b02b1d78576b685a116767d62df824fd285fPin Ting super.onInitializeAccessibilityEvent(event); 485af83b02b1d78576b685a116767d62df824fd285fPin Ting event.setClassName(Switch.class.getName()); 486af83b02b1d78576b685a116767d62df824fd285fPin Ting } 487af83b02b1d78576b685a116767d62df824fd285fPin Ting 4882e6df147d54efb9c076647cb0fa3728322bdd16aPin Ting @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH) 489af83b02b1d78576b685a116767d62df824fd285fPin Ting @Override 490af83b02b1d78576b685a116767d62df824fd285fPin Ting public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 491af83b02b1d78576b685a116767d62df824fd285fPin Ting super.onInitializeAccessibilityNodeInfo(info); 492af83b02b1d78576b685a116767d62df824fd285fPin Ting info.setClassName(Switch.class.getName()); 493af83b02b1d78576b685a116767d62df824fd285fPin Ting CharSequence switchText = isChecked() ? mTextOn : mTextOff; 494af83b02b1d78576b685a116767d62df824fd285fPin Ting if (!TextUtils.isEmpty(switchText)) { 495af83b02b1d78576b685a116767d62df824fd285fPin Ting CharSequence oldText = info.getText(); 496af83b02b1d78576b685a116767d62df824fd285fPin Ting if (TextUtils.isEmpty(oldText)) { 497af83b02b1d78576b685a116767d62df824fd285fPin Ting info.setText(switchText); 498af83b02b1d78576b685a116767d62df824fd285fPin Ting } else { 499af83b02b1d78576b685a116767d62df824fd285fPin Ting StringBuilder newText = new StringBuilder(); 500af83b02b1d78576b685a116767d62df824fd285fPin Ting newText.append(oldText).append(' ').append(switchText); 501af83b02b1d78576b685a116767d62df824fd285fPin Ting info.setText(newText); 502af83b02b1d78576b685a116767d62df824fd285fPin Ting } 503af83b02b1d78576b685a116767d62df824fd285fPin Ting } 504af83b02b1d78576b685a116767d62df824fd285fPin Ting } 505af83b02b1d78576b685a116767d62df824fd285fPin Ting} 506