Merge "Auto-show IME for dialogs on large screens."
diff --git a/Android.mk b/Android.mk
index efa7d69..4e286dbb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -395,6 +395,8 @@
resources/samples/AccessibilityService "Accessibility Service" \
-samplecode $(sample_dir)/ApiDemos \
resources/samples/ApiDemos "API Demos" \
+ -samplecode $(sample_dir)/AccelerometerPlay \
+ resources/samples/AccelerometerPlay "Accelerometer Play" \
-samplecode $(sample_dir)/BackupRestore \
resources/samples/BackupRestore "Backup and Restore" \
-samplecode $(sample_dir)/BluetoothChat \
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index 0925940..39a0c19 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -49,19 +49,23 @@
InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue) {
mSubtypeNameResId = nameId;
mSubtypeIconResId = iconId;
- mSubtypeLocale = locale;
- mSubtypeMode = mode;
- mSubtypeExtraValue = extraValue;
+ mSubtypeLocale = locale != null ? locale : "";
+ mSubtypeMode = mode != null ? mode : "";
+ mSubtypeExtraValue = extraValue != null ? extraValue : "";
mSubtypeHashCode = hashCodeInternal(mSubtypeNameResId, mSubtypeIconResId, mSubtypeLocale,
mSubtypeMode, mSubtypeExtraValue);
}
InputMethodSubtype(Parcel source) {
+ String s;
mSubtypeNameResId = source.readInt();
mSubtypeIconResId = source.readInt();
- mSubtypeLocale = source.readString();
- mSubtypeMode = source.readString();
- mSubtypeExtraValue = source.readString();
+ s = source.readString();
+ mSubtypeLocale = s != null ? s : "";
+ s = source.readString();
+ mSubtypeMode = s != null ? s : "";
+ s = source.readString();
+ mSubtypeExtraValue = s != null ? s : "";
mSubtypeHashCode = hashCodeInternal(mSubtypeNameResId, mSubtypeIconResId, mSubtypeLocale,
mSubtypeMode, mSubtypeExtraValue);
}
@@ -110,8 +114,9 @@
public boolean equals(Object o) {
if (o instanceof InputMethodSubtype) {
InputMethodSubtype subtype = (InputMethodSubtype) o;
- return (subtype.getNameResId() == getNameResId())
- && (subtype.getMode() == getMode())
+ return (subtype.hashCode() == hashCode())
+ && (subtype.getNameResId() == getNameResId())
+ && (subtype.getMode().equals(getMode()))
&& (subtype.getIconResId() == getIconResId())
&& (subtype.getLocale().equals(getLocale()))
&& (subtype.getExtraValue().equals(getExtraValue()));
@@ -146,4 +151,4 @@
String mode, String extraValue) {
return Arrays.hashCode(new Object[] {nameResId, iconResId, locale, mode, extraValue});
}
-}
\ No newline at end of file
+}
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
new file mode 100644
index 0000000..73a8c66
--- /dev/null
+++ b/core/java/android/widget/Switch.java
@@ -0,0 +1,631 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+import com.android.internal.R;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.text.Layout;
+import android.text.StaticLayout;
+import android.text.TextPaint;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.ViewConfiguration;
+
+/**
+ * A Switch is a two-state toggle switch widget that can select between two
+ * options. The user may drag the "thumb" back and forth to choose the selected option,
+ * or simply tap to toggle as if it were a checkbox.
+ *
+ * @hide
+ */
+public class Switch extends CompoundButton {
+ private static final int TOUCH_MODE_IDLE = 0;
+ private static final int TOUCH_MODE_DOWN = 1;
+ private static final int TOUCH_MODE_DRAGGING = 2;
+
+ // Enum for the "typeface" XML parameter.
+ private static final int SANS = 1;
+ private static final int SERIF = 2;
+ private static final int MONOSPACE = 3;
+
+ private Drawable mThumbDrawable;
+ private Drawable mTrackDrawable;
+ private int mThumbTextPadding;
+ private int mSwitchMinWidth;
+ private int mSwitchPadding;
+ private CharSequence mTextOn;
+ private CharSequence mTextOff;
+
+ private int mTouchMode;
+ private int mTouchSlop;
+ private float mTouchX;
+ private float mTouchY;
+ private VelocityTracker mVelocityTracker = VelocityTracker.obtain();
+ private int mMinFlingVelocity;
+
+ private float mThumbPosition;
+ private int mSwitchWidth;
+ private int mSwitchHeight;
+ private int mThumbWidth; // Does not include padding
+
+ private int mSwitchLeft;
+ private int mSwitchTop;
+ private int mSwitchRight;
+ private int mSwitchBottom;
+
+ private TextPaint mTextPaint;
+ private ColorStateList mTextColors;
+ private Layout mOnLayout;
+ private Layout mOffLayout;
+
+ private final Rect mTempRect = new Rect();
+
+ private static final int[] CHECKED_STATE_SET = {
+ R.attr.state_checked
+ };
+
+ /**
+ * Construct a new Switch with default styling.
+ *
+ * @param context The Context that will determine this widget's theming.
+ */
+ public Switch(Context context) {
+ this(context, null);
+ }
+
+ /**
+ * Construct a new Switch with default styling, overriding specific style
+ * attributes as requested.
+ *
+ * @param context The Context that will determine this widget's theming.
+ * @param attrs Specification of attributes that should deviate from default styling.
+ */
+ public Switch(Context context, AttributeSet attrs) {
+ this(context, attrs, com.android.internal.R.attr.switchStyle);
+ }
+
+ /**
+ * Construct a new Switch with a default style determined by the given theme attribute,
+ * overriding specific style attributes as requested.
+ *
+ * @param context The Context that will determine this widget's theming.
+ * @param attrs Specification of attributes that should deviate from the default styling.
+ * @param defStyle An attribute ID within the active theme containing a reference to the
+ * default style for this widget. e.g. android.R.attr.switchStyle.
+ */
+ public Switch(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
+ Resources res = getResources();
+ mTextPaint.density = res.getDisplayMetrics().density;
+ mTextPaint.setCompatibilityScaling(res.getCompatibilityInfo().applicationScale);
+
+ TypedArray a = context.obtainStyledAttributes(attrs,
+ com.android.internal.R.styleable.Switch, defStyle, 0);
+
+ mThumbDrawable = a.getDrawable(com.android.internal.R.styleable.Switch_switchThumb);
+ mTrackDrawable = a.getDrawable(com.android.internal.R.styleable.Switch_switchTrack);
+ mTextOn = a.getText(com.android.internal.R.styleable.Switch_textOn);
+ mTextOff = a.getText(com.android.internal.R.styleable.Switch_textOff);
+ mThumbTextPadding = a.getDimensionPixelSize(
+ com.android.internal.R.styleable.Switch_thumbTextPadding, 0);
+ mSwitchMinWidth = a.getDimensionPixelSize(
+ com.android.internal.R.styleable.Switch_switchMinWidth, 0);
+ mSwitchPadding = a.getDimensionPixelSize(
+ com.android.internal.R.styleable.Switch_switchPadding, 0);
+
+ int appearance = a.getResourceId(
+ com.android.internal.R.styleable.Switch_switchTextAppearance, 0);
+ if (appearance != 0) {
+ setSwitchTextAppearance(appearance);
+ }
+ a.recycle();
+
+ ViewConfiguration config = ViewConfiguration.get(context);
+ mTouchSlop = config.getScaledTouchSlop();
+ mMinFlingVelocity = config.getScaledMinimumFlingVelocity();
+
+ // Refresh display with current params
+ setChecked(isChecked());
+ }
+
+ /**
+ * Sets the switch text color, size, style, hint color, and highlight color
+ * from the specified TextAppearance resource.
+ */
+ public void setSwitchTextAppearance(int resid) {
+ TypedArray appearance =
+ getContext().obtainStyledAttributes(resid,
+ com.android.internal.R.styleable.TextAppearance);
+
+ ColorStateList colors;
+ int ts;
+
+ colors = appearance.getColorStateList(com.android.internal.R.styleable.
+ TextAppearance_textColor);
+ if (colors != null) {
+ mTextColors = colors;
+ }
+
+ ts = appearance.getDimensionPixelSize(com.android.internal.R.styleable.
+ TextAppearance_textSize, 0);
+ if (ts != 0) {
+ if (ts != mTextPaint.getTextSize()) {
+ mTextPaint.setTextSize(ts);
+ requestLayout();
+ }
+ }
+
+ int typefaceIndex, styleIndex;
+
+ typefaceIndex = appearance.getInt(com.android.internal.R.styleable.
+ TextAppearance_typeface, -1);
+ styleIndex = appearance.getInt(com.android.internal.R.styleable.
+ TextAppearance_textStyle, -1);
+
+ setSwitchTypefaceByIndex(typefaceIndex, styleIndex);
+
+ int lineHeight = appearance.getDimensionPixelSize(
+ com.android.internal.R.styleable.TextAppearance_textLineHeight, 0);
+ if (lineHeight != 0) {
+ setLineHeight(lineHeight);
+ }
+
+ appearance.recycle();
+ }
+
+ private void setSwitchTypefaceByIndex(int typefaceIndex, int styleIndex) {
+ Typeface tf = null;
+ switch (typefaceIndex) {
+ case SANS:
+ tf = Typeface.SANS_SERIF;
+ break;
+
+ case SERIF:
+ tf = Typeface.SERIF;
+ break;
+
+ case MONOSPACE:
+ tf = Typeface.MONOSPACE;
+ break;
+ }
+
+ setSwitchTypeface(tf, styleIndex);
+ }
+
+ /**
+ * Sets the typeface and style in which the text should be displayed on the
+ * switch, and turns on the fake bold and italic bits in the Paint if the
+ * Typeface that you provided does not have all the bits in the
+ * style that you specified.
+ */
+ public void setSwitchTypeface(Typeface tf, int style) {
+ if (style > 0) {
+ if (tf == null) {
+ tf = Typeface.defaultFromStyle(style);
+ } else {
+ tf = Typeface.create(tf, style);
+ }
+
+ setSwitchTypeface(tf);
+ // now compute what (if any) algorithmic styling is needed
+ int typefaceStyle = tf != null ? tf.getStyle() : 0;
+ int need = style & ~typefaceStyle;
+ mTextPaint.setFakeBoldText((need & Typeface.BOLD) != 0);
+ mTextPaint.setTextSkewX((need & Typeface.ITALIC) != 0 ? -0.25f : 0);
+ } else {
+ mTextPaint.setFakeBoldText(false);
+ mTextPaint.setTextSkewX(0);
+ setSwitchTypeface(tf);
+ }
+ }
+
+ /**
+ * Sets the typeface and style in which the text should be displayed on the switch.
+ * Note that not all Typeface families actually have bold and italic
+ * variants, so you may need to use
+ * {@link #setSwitchTypeface(Typeface, int)} to get the appearance
+ * that you actually want.
+ *
+ * @attr ref android.R.styleable#TextView_typeface
+ * @attr ref android.R.styleable#TextView_textStyle
+ */
+ public void setSwitchTypeface(Typeface tf) {
+ if (mTextPaint.getTypeface() != tf) {
+ mTextPaint.setTypeface(tf);
+
+ requestLayout();
+ invalidate();
+ }
+ }
+
+ /**
+ * Returns the text for when the button is in the checked state.
+ *
+ * @return The text.
+ */
+ public CharSequence getTextOn() {
+ return mTextOn;
+ }
+
+ /**
+ * Sets the text for when the button is in the checked state.
+ *
+ * @param textOn The text.
+ */
+ public void setTextOn(CharSequence textOn) {
+ mTextOn = textOn;
+ requestLayout();
+ }
+
+ /**
+ * Returns the text for when the button is not in the checked state.
+ *
+ * @return The text.
+ */
+ public CharSequence getTextOff() {
+ return mTextOff;
+ }
+
+ /**
+ * Sets the text for when the button is not in the checked state.
+ *
+ * @param textOff The text.
+ */
+ public void setTextOff(CharSequence textOff) {
+ mTextOff = textOff;
+ requestLayout();
+ }
+
+ @Override
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+ int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+
+
+ if (mOnLayout == null) {
+ mOnLayout = makeLayout(mTextOn);
+ }
+ if (mOffLayout == null) {
+ mOffLayout = makeLayout(mTextOff);
+ }
+
+ mTrackDrawable.getPadding(mTempRect);
+ final int maxTextWidth = Math.max(mOnLayout.getWidth(), mOffLayout.getWidth());
+ final int switchWidth = Math.max(mSwitchMinWidth,
+ maxTextWidth * 2 + mThumbTextPadding * 4 + mTempRect.left + mTempRect.right);
+ final int switchHeight = mTrackDrawable.getIntrinsicHeight();
+
+ mThumbWidth = maxTextWidth + mThumbTextPadding * 2;
+
+ switch (widthMode) {
+ case MeasureSpec.AT_MOST:
+ widthSize = Math.min(widthSize, switchWidth);
+ break;
+
+ case MeasureSpec.UNSPECIFIED:
+ widthSize = switchWidth;
+ break;
+
+ case MeasureSpec.EXACTLY:
+ // Just use what we were given
+ break;
+ }
+
+ switch (heightMode) {
+ case MeasureSpec.AT_MOST:
+ heightSize = Math.min(heightSize, switchHeight);
+ break;
+
+ case MeasureSpec.UNSPECIFIED:
+ heightSize = switchHeight;
+ break;
+
+ case MeasureSpec.EXACTLY:
+ // Just use what we were given
+ break;
+ }
+
+ mSwitchWidth = switchWidth;
+ mSwitchHeight = switchHeight;
+
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ final int measuredWidth = getMeasuredWidth();
+ final int measuredHeight = getMeasuredHeight();
+ if (measuredHeight < switchHeight) {
+ setMeasuredDimension(measuredWidth, switchHeight);
+ }
+ }
+
+ private Layout makeLayout(CharSequence text) {
+ return new StaticLayout(text, mTextPaint,
+ (int) Math.ceil(Layout.getDesiredWidth(text, mTextPaint)),
+ Layout.Alignment.ALIGN_NORMAL, 1.f, 0, true);
+ }
+
+ /**
+ * @return true if (x, y) is within the target area of the switch thumb
+ */
+ private boolean hitThumb(float x, float y) {
+ mThumbDrawable.getPadding(mTempRect);
+ final int thumbTop = mSwitchTop - mTouchSlop;
+ final int thumbLeft = mSwitchLeft + (int) (mThumbPosition + 0.5f) - mTouchSlop;
+ final int thumbRight = thumbLeft + mThumbWidth +
+ mTempRect.left + mTempRect.right + mTouchSlop;
+ final int thumbBottom = mSwitchBottom + mTouchSlop;
+ return x > thumbLeft && x < thumbRight && y > thumbTop && y < thumbBottom;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ mVelocityTracker.addMovement(ev);
+ final int action = ev.getActionMasked();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN: {
+ final float x = ev.getX();
+ final float y = ev.getY();
+ if (hitThumb(x, y)) {
+ mTouchMode = TOUCH_MODE_DOWN;
+ mTouchX = x;
+ mTouchY = y;
+ }
+ break;
+ }
+
+ case MotionEvent.ACTION_MOVE: {
+ switch (mTouchMode) {
+ case TOUCH_MODE_IDLE:
+ // Didn't target the thumb, treat normally.
+ break;
+
+ case TOUCH_MODE_DOWN: {
+ final float x = ev.getX();
+ final float y = ev.getY();
+ if (Math.abs(x - mTouchX) > mTouchSlop ||
+ Math.abs(y - mTouchY) > mTouchSlop) {
+ mTouchMode = TOUCH_MODE_DRAGGING;
+ getParent().requestDisallowInterceptTouchEvent(true);
+ mTouchX = x;
+ mTouchY = y;
+ return true;
+ }
+ break;
+ }
+
+ case TOUCH_MODE_DRAGGING: {
+ final float x = ev.getX();
+ final float dx = x - mTouchX;
+ float newPos = Math.max(0,
+ Math.min(mThumbPosition + dx, getThumbScrollRange()));
+ if (newPos != mThumbPosition) {
+ mThumbPosition = newPos;
+ mTouchX = x;
+ invalidate();
+ }
+ return true;
+ }
+ }
+ break;
+ }
+
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL: {
+ if (mTouchMode == TOUCH_MODE_DRAGGING) {
+ stopDrag(ev);
+ return true;
+ }
+ mTouchMode = TOUCH_MODE_IDLE;
+ mVelocityTracker.clear();
+ break;
+ }
+ }
+
+ return super.onTouchEvent(ev);
+ }
+
+ private void cancelSuperTouch(MotionEvent ev) {
+ MotionEvent cancel = MotionEvent.obtain(ev);
+ cancel.setAction(MotionEvent.ACTION_CANCEL);
+ super.onTouchEvent(cancel);
+ cancel.recycle();
+ }
+
+ /**
+ * Called from onTouchEvent to end a drag operation.
+ *
+ * @param ev Event that triggered the end of drag mode - ACTION_UP or ACTION_CANCEL
+ */
+ private void stopDrag(MotionEvent ev) {
+ mTouchMode = TOUCH_MODE_IDLE;
+ boolean commitChange = ev.getAction() == MotionEvent.ACTION_UP;
+
+ cancelSuperTouch(ev);
+
+ if (commitChange) {
+ boolean newState;
+ mVelocityTracker.computeCurrentVelocity(1000);
+ float xvel = mVelocityTracker.getXVelocity();
+ if (Math.abs(xvel) > mMinFlingVelocity) {
+ newState = xvel < 0;
+ } else {
+ newState = getTargetCheckedState();
+ }
+ animateThumbToCheckedState(newState);
+ } else {
+ animateThumbToCheckedState(isChecked());
+ }
+ }
+
+ private void animateThumbToCheckedState(boolean newCheckedState) {
+ float targetPos = newCheckedState ? 0 : getThumbScrollRange();
+ // TODO animate!
+ mThumbPosition = targetPos;
+ setChecked(newCheckedState);
+ }
+
+ private boolean getTargetCheckedState() {
+ return mThumbPosition <= getThumbScrollRange() / 2;
+ }
+
+ @Override
+ public void setChecked(boolean checked) {
+ super.setChecked(checked);
+ mThumbPosition = checked ? 0 : getThumbScrollRange();
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+
+ int switchRight = getWidth() - getPaddingRight();
+ int switchLeft = switchRight - mSwitchWidth;
+ int switchTop = 0;
+ int switchBottom = 0;
+ switch (getGravity() & Gravity.VERTICAL_GRAVITY_MASK) {
+ default:
+ case Gravity.TOP:
+ switchTop = getPaddingTop();
+ switchBottom = switchTop + mSwitchHeight;
+ break;
+
+ case Gravity.CENTER_VERTICAL:
+ switchTop = (getPaddingTop() + getHeight() - getPaddingBottom()) / 2 -
+ mSwitchHeight / 2;
+ switchBottom = switchTop + mSwitchHeight;
+ break;
+
+ case Gravity.BOTTOM:
+ switchBottom = getHeight() - getPaddingBottom();
+ switchTop = switchBottom - mSwitchHeight;
+ break;
+ }
+
+ mSwitchLeft = switchLeft;
+ mSwitchTop = switchTop;
+ mSwitchBottom = switchBottom;
+ mSwitchRight = switchRight;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ // Draw the switch
+ int switchLeft = mSwitchLeft;
+ int switchTop = mSwitchTop;
+ int switchRight = mSwitchRight;
+ int switchBottom = mSwitchBottom;
+
+ mTrackDrawable.setBounds(switchLeft, switchTop, switchRight, switchBottom);
+ mTrackDrawable.draw(canvas);
+
+ canvas.save();
+
+ mTrackDrawable.getPadding(mTempRect);
+ int switchInnerLeft = switchLeft + mTempRect.left;
+ int switchInnerTop = switchTop + mTempRect.top;
+ int switchInnerRight = switchRight - mTempRect.right;
+ int switchInnerBottom = switchBottom - mTempRect.bottom;
+ canvas.clipRect(switchInnerLeft, switchTop, switchInnerRight, switchBottom);
+
+ mThumbDrawable.getPadding(mTempRect);
+ final int thumbPos = (int) (mThumbPosition + 0.5f);
+ int thumbLeft = switchInnerLeft - mTempRect.left + thumbPos;
+ int thumbRight = switchInnerLeft + thumbPos + mThumbWidth + mTempRect.right;
+
+ mThumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);
+ mThumbDrawable.draw(canvas);
+
+ mTextPaint.setColor(mTextColors.getColorForState(getDrawableState(),
+ mTextColors.getDefaultColor()));
+ mTextPaint.drawableState = getDrawableState();
+
+ Layout switchText = getTargetCheckedState() ? mOnLayout : mOffLayout;
+
+ canvas.translate((thumbLeft + thumbRight) / 2 - switchText.getWidth() / 2,
+ (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2);
+ switchText.draw(canvas);
+
+ canvas.restore();
+ }
+
+ @Override
+ public int getCompoundPaddingRight() {
+ int padding = super.getCompoundPaddingRight() + mSwitchWidth;
+ if (!TextUtils.isEmpty(getText())) {
+ padding += mSwitchPadding;
+ }
+ return padding;
+ }
+
+ private int getThumbScrollRange() {
+ if (mTrackDrawable == null) {
+ return 0;
+ }
+ mTrackDrawable.getPadding(mTempRect);
+ return mSwitchWidth - mThumbWidth - mTempRect.left - mTempRect.right;
+ }
+
+ @Override
+ protected int[] onCreateDrawableState(int extraSpace) {
+ final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
+ if (isChecked()) {
+ mergeDrawableStates(drawableState, CHECKED_STATE_SET);
+ }
+ return drawableState;
+ }
+
+ @Override
+ protected void drawableStateChanged() {
+ super.drawableStateChanged();
+
+ int[] myDrawableState = getDrawableState();
+
+ // Set the state of the Drawable
+ mThumbDrawable.setState(myDrawableState);
+ mTrackDrawable.setState(myDrawableState);
+
+ invalidate();
+ }
+
+ @Override
+ protected boolean verifyDrawable(Drawable who) {
+ return super.verifyDrawable(who) || who == mThumbDrawable || who == mTrackDrawable;
+ }
+
+ @Override
+ public void jumpDrawablesToCurrentState() {
+ super.jumpDrawablesToCurrentState();
+ mThumbDrawable.jumpToCurrentState();
+ mTrackDrawable.jumpToCurrentState();
+ }
+}
diff --git a/core/res/res/drawable-hdpi/switch_bg_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_bg_disabled_holo_dark.9.png
new file mode 100644
index 0000000..df435e4
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_bg_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_bg_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/switch_bg_disabled_holo_light.9.png
new file mode 100644
index 0000000..4c8cc86
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_bg_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_bg_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_bg_focused_holo_dark.9.png
new file mode 100644
index 0000000..a4ec766
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_bg_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_bg_focused_holo_light.9.png b/core/res/res/drawable-hdpi/switch_bg_focused_holo_light.9.png
new file mode 100644
index 0000000..a571aa8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_bg_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_bg_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_bg_holo_dark.9.png
new file mode 100644
index 0000000..f86e7e4
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_bg_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_bg_holo_light.9.png b/core/res/res/drawable-hdpi/switch_bg_holo_light.9.png
new file mode 100644
index 0000000..b4584a7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_bg_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png
new file mode 100644
index 0000000..c01ad87
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png
new file mode 100644
index 0000000..b3e428d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png
new file mode 100644
index 0000000..4d3d5b7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png
new file mode 100644
index 0000000..16e11b6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png
new file mode 100644
index 0000000..3900997
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png
new file mode 100644
index 0000000..ab4fd8d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_bg_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_bg_disabled_holo_dark.9.png
new file mode 100644
index 0000000..c75612c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_bg_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_bg_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/switch_bg_disabled_holo_light.9.png
new file mode 100644
index 0000000..67adadc
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_bg_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_bg_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_bg_focused_holo_dark.9.png
new file mode 100644
index 0000000..9a05f84
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_bg_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_bg_focused_holo_light.9.png b/core/res/res/drawable-mdpi/switch_bg_focused_holo_light.9.png
new file mode 100644
index 0000000..58d65ad
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_bg_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_bg_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_bg_holo_dark.9.png
new file mode 100644
index 0000000..172030d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_bg_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_bg_holo_light.9.png b/core/res/res/drawable-mdpi/switch_bg_holo_light.9.png
new file mode 100644
index 0000000..4ae089b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_bg_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png
new file mode 100644
index 0000000..7e205ac
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png
new file mode 100644
index 0000000..b4e7cf5
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png
new file mode 100644
index 0000000..7003318a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png
new file mode 100644
index 0000000..97afcbf
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png
new file mode 100644
index 0000000..1adc9ee
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png
new file mode 100644
index 0000000..29c6328
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable/switch_inner_holo_dark.xml b/core/res/res/drawable/switch_inner_holo_dark.xml
new file mode 100644
index 0000000..3eb55ee
--- /dev/null
+++ b/core/res/res/drawable/switch_inner_holo_dark.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false" android:drawable="@drawable/switch_thumb_disabled_holo_dark" />
+ <item android:state_pressed="true" android:drawable="@drawable/switch_thumb_pressed_holo_dark" />
+ <item android:drawable="@drawable/switch_thumb_holo_dark" />
+</selector>
diff --git a/core/res/res/drawable/switch_inner_holo_light.xml b/core/res/res/drawable/switch_inner_holo_light.xml
new file mode 100644
index 0000000..9b287cf
--- /dev/null
+++ b/core/res/res/drawable/switch_inner_holo_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false" android:drawable="@drawable/switch_thumb_disabled_holo_light" />
+ <item android:state_pressed="true" android:drawable="@drawable/switch_thumb_pressed_holo_light" />
+ <item android:drawable="@drawable/switch_thumb_holo_light" />
+</selector>
diff --git a/core/res/res/drawable/switch_track_holo_dark.xml b/core/res/res/drawable/switch_track_holo_dark.xml
new file mode 100644
index 0000000..c9a940d
--- /dev/null
+++ b/core/res/res/drawable/switch_track_holo_dark.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false" android:drawable="@drawable/switch_bg_disabled_holo_dark" />
+ <item android:state_focused="true" android:drawable="@drawable/switch_bg_focused_holo_dark" />
+ <item android:drawable="@drawable/switch_bg_holo_dark" />
+</selector>
diff --git a/core/res/res/drawable/switch_track_holo_light.xml b/core/res/res/drawable/switch_track_holo_light.xml
new file mode 100644
index 0000000..98e53b5
--- /dev/null
+++ b/core/res/res/drawable/switch_track_holo_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false" android:drawable="@drawable/switch_bg_disabled_holo_light" />
+ <item android:state_focused="true" android:drawable="@drawable/switch_bg_focused_holo_light" />
+ <item android:drawable="@drawable/switch_bg_holo_light" />
+</selector>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 5d4fd4e..dfbcafc0a 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -634,6 +634,10 @@
<!-- Preference frame layout styles. -->
<attr name="preferenceFrameLayoutStyle" format="reference" />
+
+ <!-- Default style for the Switch widget. -->
+ <attr name="switchStyle" format="reference" />
+
</declare-styleable>
<!-- **************************************************************** -->
@@ -4512,4 +4516,23 @@
<declare-styleable name="ActionBar_LayoutParams">
<attr name="layout_gravity" />
</declare-styleable>
+
+ <declare-styleable name="Switch">
+ <!-- Drawable to use as the "thumb" that switches back and forth. -->
+ <attr name="switchThumb" format="reference" />
+ <!-- Drawable to use as the "track" that the switch thumb slides within. -->
+ <attr name="switchTrack" format="reference" />
+ <!-- Text to use when the switch is in the checked/"on" state. -->
+ <attr name="textOn" />
+ <!-- Text to use when the switch is in the unchecked/"off" state. -->
+ <attr name="textOff" />
+ <!-- Amount of padding on either side of text within the switch thumb. -->
+ <attr name="thumbTextPadding" format="dimension" />
+ <!-- TextAppearance style for text displayed on the switch thumb. -->
+ <attr name="switchTextAppearance" format="reference" />
+ <!-- Minimum width for the switch component -->
+ <attr name="switchMinWidth" format="dimension" />
+ <!-- Minimum space between the switch and caption text -->
+ <attr name="switchPadding" format="dimension" />
+ </declare-styleable>
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 60150a1..b3c3e0d 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1177,6 +1177,9 @@
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
+ <style name="TextAppearance.Holo.Widget.Switch" parent="TextAppearance.Holo.Small">
+ </style>
+
<style name="TextAppearance.Holo.WindowTitle">
<item name="android:textColor">#fff</item>
<item name="android:textSize">14sp</item>
@@ -1353,6 +1356,9 @@
<item name="android:popupBackground">@android:drawable/menu_dropdown_panel_holo_dark</item>
</style>
+ <style name="Widget.Holo.CompoundButton" parent="Widget.CompoundButton">
+ </style>
+
<style name="Widget.Holo.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox">
</style>
@@ -1610,6 +1616,17 @@
<item name="android:progressBarPadding">32dip</item>
</style>
+ <style name="Widget.Holo.CompoundButton.Switch">
+ <item name="android:switchTrack">@android:drawable/switch_track_holo_dark</item>
+ <item name="android:switchThumb">@android:drawable/switch_inner_holo_dark</item>
+ <item name="android:switchTextAppearance">@android:style/TextAppearance.Holo.Widget.Switch</item>
+ <item name="android:textOn">@android:string/capital_on</item>
+ <item name="android:textOff">@android:string/capital_off</item>
+ <item name="android:thumbTextPadding">12dip</item>
+ <item name="android:switchMinWidth">96dip</item>
+ <item name="android:switchPadding">16dip</item>
+ </style>
+
<!-- Light widget styles -->
<style name="Widget.Holo.Light">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 97df48a..e1040d9 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -719,6 +719,7 @@
<item name="buttonStyleInset">@android:style/Widget.Holo.Button.Inset</item>
<item name="buttonStyleToggle">@android:style/Widget.Holo.Button.Toggle</item>
+ <item name="switchStyle">@android:style/Widget.Holo.CompoundButton.Switch</item>
<item name="groupButtonBackground">@android:drawable/group_button_background_holo_dark</item>
<item name="selectableItemBackground">@android:drawable/item_background_holo_dark</item>