android仿ios开关按钮

简介: <p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px"> 前一段时间在做项目的时候遇到了一个问题,美工在设计的时候设计的是一个iPhone中的开关,但是都知道Android中的Switch开关和IOS中的不同,这样就需要通过动画来实现一个iPhone开关了。</p> <p s

前一段时间在做项目的时候遇到了一个问题,美工在设计的时候设计的是一个iPhone中的开关,但是都知道Android中的Switch开关和IOS中的不同,这样就需要通过动画来实现一个iPhone开关了。

通常我们设置界面采用的是PreferenceActivity

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package me.imid.movablecheckbox;  
  2.   
  3. import android.os.Bundle;  
  4. import android.preference.PreferenceActivity;  
  5.   
  6. public class MovableCheckboxActivity extends PreferenceActivity {  
  7.       
  8.     @Override  
  9.     public void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);     
  11.         addPreferencesFromResource(R.xml.testpreference);  
  12.     }  
  13. }  

有关PreferenceActivity请看:http://blog.csdn.net/dawanganban/article/details/19082949

我们的基本思路是将CheckBox自定义成我们想要的样子,然后再重写CheckBoxPreference将自定义的CheckBox载入。

1、重写CheckBox

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package me.imid.view;  
  2.   
  3. import me.imid.movablecheckbox.R;  
  4.   
  5. import android.content.Context;  
  6. import android.content.res.Resources;  
  7. import android.graphics.Bitmap;  
  8. import android.graphics.BitmapFactory;  
  9. import android.graphics.Canvas;  
  10. import android.graphics.Color;  
  11. import android.graphics.Paint;  
  12. import android.graphics.PorterDuff;  
  13. import android.graphics.PorterDuffXfermode;  
  14. import android.graphics.RectF;  
  15. import android.util.AttributeSet;  
  16. import android.view.MotionEvent;  
  17. import android.view.ViewConfiguration;  
  18. import android.view.ViewParent;  
  19. import android.widget.CheckBox;  
  20.   
  21. public class SwitchButton extends CheckBox {  
  22.     private Paint mPaint;  
  23.   
  24.     private ViewParent mParent;  
  25.   
  26.     private Bitmap mBottom;  
  27.   
  28.     private Bitmap mCurBtnPic;  
  29.   
  30.     private Bitmap mBtnPressed;  
  31.   
  32.     private Bitmap mBtnNormal;  
  33.   
  34.     private Bitmap mFrame;  
  35.   
  36.     private Bitmap mMask;  
  37.   
  38.     private RectF mSaveLayerRectF;  
  39.   
  40.     private PorterDuffXfermode mXfermode;  
  41.   
  42.     private float mFirstDownY; // 首次按下的Y  
  43.   
  44.     private float mFirstDownX; // 首次按下的X  
  45.   
  46.     private float mRealPos; // 图片的绘制位置  
  47.   
  48.     private float mBtnPos; // 按钮的位置  
  49.   
  50.     private float mBtnOnPos; // 开关打开的位置  
  51.   
  52.     private float mBtnOffPos; // 开关关闭的位置  
  53.   
  54.     private float mMaskWidth;  
  55.   
  56.     private float mMaskHeight;  
  57.   
  58.     private float mBtnWidth;  
  59.   
  60.     private float mBtnInitPos;  
  61.   
  62.     private int mClickTimeout;  
  63.   
  64.     private int mTouchSlop;  
  65.   
  66.     private final int MAX_ALPHA = 255;  
  67.   
  68.     private int mAlpha = MAX_ALPHA;  
  69.   
  70.     private boolean mChecked = false;  
  71.   
  72.     private boolean mBroadcasting;  
  73.   
  74.     private boolean mTurningOn;  
  75.   
  76.     private PerformClick mPerformClick;  
  77.   
  78.     private OnCheckedChangeListener mOnCheckedChangeListener;  
  79.   
  80.     private OnCheckedChangeListener mOnCheckedChangeWidgetListener;  
  81.   
  82.     private boolean mAnimating;  
  83.   
  84.     private final float VELOCITY = 350;  
  85.   
  86.     private float mVelocity;  
  87.   
  88.     private final float EXTENDED_OFFSET_Y = 15;  
  89.   
  90.     private float mExtendOffsetY; // Y轴方向扩大的区域,增大点击区域  
  91.   
  92.     private float mAnimationPosition;  
  93.   
  94.     private float mAnimatedVelocity;  
  95.   
  96.     public SwitchButton(Context context, AttributeSet attrs) {  
  97.         this(context, attrs, android.R.attr.checkboxStyle);  
  98.     }  
  99.   
  100.     public SwitchButton(Context context) {  
  101.         this(context, null);  
  102.     }  
  103.   
  104.     public SwitchButton(Context context, AttributeSet attrs, int defStyle) {  
  105.         super(context, attrs, defStyle);  
  106.         initView(context);  
  107.     }  
  108.   
  109.     private void initView(Context context) {  
  110.         mPaint = new Paint();  
  111.         mPaint.setColor(Color.WHITE);  
  112.         Resources resources = context.getResources();  
  113.   
  114.         // get viewConfiguration  
  115.         mClickTimeout = ViewConfiguration.getPressedStateDuration()  
  116.                 + ViewConfiguration.getTapTimeout();  
  117.         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();  
  118.   
  119.         // get Bitmap  
  120.         mBottom = BitmapFactory.decodeResource(resources, R.drawable.bottom);  
  121.         mBtnPressed = BitmapFactory.decodeResource(resources, R.drawable.btn_pressed);  
  122.         mBtnNormal = BitmapFactory.decodeResource(resources, R.drawable.btn_unpressed);  
  123.         mFrame = BitmapFactory.decodeResource(resources, R.drawable.frame);  
  124.         mMask = BitmapFactory.decodeResource(resources, R.drawable.mask);  
  125.         mCurBtnPic = mBtnNormal;  
  126.   
  127.         mBtnWidth = mBtnPressed.getWidth();  
  128.         mMaskWidth = mMask.getWidth();  
  129.         mMaskHeight = mMask.getHeight();  
  130.   
  131.         mBtnOffPos = mBtnWidth / 2;  
  132.         mBtnOnPos = mMaskWidth - mBtnWidth / 2;  
  133.   
  134.         mBtnPos = mChecked ? mBtnOnPos : mBtnOffPos;  
  135.         mRealPos = getRealPos(mBtnPos);  
  136.   
  137.         final float density = getResources().getDisplayMetrics().density;  
  138.         mVelocity = (int) (VELOCITY * density + 0.5f);  
  139.         mExtendOffsetY = (int) (EXTENDED_OFFSET_Y * density + 0.5f);  
  140.   
  141.         mSaveLayerRectF = new RectF(0, mExtendOffsetY, mMask.getWidth(), mMask.getHeight()  
  142.                 + mExtendOffsetY);  
  143.         mXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);  
  144.     }  
  145.   
  146.     @Override  
  147.     public void setEnabled(boolean enabled) {  
  148.         mAlpha = enabled ? MAX_ALPHA : MAX_ALPHA / 2;  
  149.         super.setEnabled(enabled);  
  150.     }  
  151.   
  152.     public boolean isChecked() {  
  153.         return mChecked;  
  154.     }  
  155.   
  156.     public void toggle() {  
  157.         setChecked(!mChecked);  
  158.     }  
  159.   
  160.     /** 
  161.      * 内部调用此方法设置checked状态,此方法会延迟执行各种回调函数,保证动画的流畅度 
  162.      *  
  163.      * @param checked 
  164.      */  
  165.     private void setCheckedDelayed(final boolean checked) {  
  166.         this.postDelayed(new Runnable() {  
  167.   
  168.             @Override  
  169.             public void run() {  
  170.                 setChecked(checked);  
  171.             }  
  172.         }, 10);  
  173.     }  
  174.   
  175.     /** 
  176.      * <p> 
  177.      * Changes the checked state of this button. 
  178.      * </p> 
  179.      *  
  180.      * @param checked true to check the button, false to uncheck it 
  181.      */  
  182.     public void setChecked(boolean checked) {  
  183.   
  184.         if (mChecked != checked) {  
  185.             mChecked = checked;  
  186.   
  187.             mBtnPos = checked ? mBtnOnPos : mBtnOffPos;  
  188.             mRealPos = getRealPos(mBtnPos);  
  189.             invalidate();  
  190.   
  191.             // Avoid infinite recursions if setChecked() is called from a  
  192.             // listener  
  193.             if (mBroadcasting) {  
  194.                 return;  
  195.             }  
  196.   
  197.             mBroadcasting = true;  
  198.             if (mOnCheckedChangeListener != null) {  
  199.                 mOnCheckedChangeListener.onCheckedChanged(SwitchButton.this, mChecked);  
  200.             }  
  201.             if (mOnCheckedChangeWidgetListener != null) {  
  202.                 mOnCheckedChangeWidgetListener.onCheckedChanged(SwitchButton.this, mChecked);  
  203.             }  
  204.   
  205.             mBroadcasting = false;  
  206.         }  
  207.     }  
  208.   
  209.     /** 
  210.      * Register a callback to be invoked when the checked state of this button 
  211.      * changes. 
  212.      *  
  213.      * @param listener the callback to call on checked state change 
  214.      */  
  215.     public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {  
  216.         mOnCheckedChangeListener = listener;  
  217.     }  
  218.   
  219.     /** 
  220.      * Register a callback to be invoked when the checked state of this button 
  221.      * changes. This callback is used for internal purpose only. 
  222.      *  
  223.      * @param listener the callback to call on checked state change 
  224.      * @hide 
  225.      */  
  226.     void setOnCheckedChangeWidgetListener(OnCheckedChangeListener listener) {  
  227.         mOnCheckedChangeWidgetListener = listener;  
  228.     }  
  229.   
  230.     @Override  
  231.     public boolean onTouchEvent(MotionEvent event) {  
  232.         int action = event.getAction();  
  233.         float x = event.getX();  
  234.         float y = event.getY();  
  235.         float deltaX = Math.abs(x - mFirstDownX);  
  236.         float deltaY = Math.abs(y - mFirstDownY);  
  237.         switch (action) {  
  238.             case MotionEvent.ACTION_DOWN:  
  239.                 attemptClaimDrag();  
  240.                 mFirstDownX = x;  
  241.                 mFirstDownY = y;  
  242.                 mCurBtnPic = mBtnPressed;  
  243.                 mBtnInitPos = mChecked ? mBtnOnPos : mBtnOffPos;  
  244.                 break;  
  245.             case MotionEvent.ACTION_MOVE:  
  246.                 float time = event.getEventTime() - event.getDownTime();  
  247.                 mBtnPos = mBtnInitPos + event.getX() - mFirstDownX;  
  248.                 if (mBtnPos >= mBtnOffPos) {  
  249.                     mBtnPos = mBtnOffPos;  
  250.                 }  
  251.                 if (mBtnPos <= mBtnOnPos) {  
  252.                     mBtnPos = mBtnOnPos;  
  253.                 }  
  254.                 mTurningOn = mBtnPos > (mBtnOffPos - mBtnOnPos) / 2 + mBtnOnPos;  
  255.   
  256.                 mRealPos = getRealPos(mBtnPos);  
  257.                 break;  
  258.             case MotionEvent.ACTION_UP:  
  259.                 mCurBtnPic = mBtnNormal;  
  260.                 time = event.getEventTime() - event.getDownTime();  
  261.                 if (deltaY < mTouchSlop && deltaX < mTouchSlop && time < mClickTimeout) {  
  262.                     if (mPerformClick == null) {  
  263.                         mPerformClick = new PerformClick();  
  264.                     }  
  265.                     if (!post(mPerformClick)) {  
  266.                         performClick();  
  267.                     }  
  268.                 } else {  
  269.                     startAnimation(!mTurningOn);  
  270.                 }  
  271.                 break;  
  272.         }  
  273.   
  274.         invalidate();  
  275.         return isEnabled();  
  276.     }  
  277.   
  278.     private final class PerformClick implements Runnable {  
  279.         public void run() {  
  280.             performClick();  
  281.         }  
  282.     }  
  283.   
  284.     @Override  
  285.     public boolean performClick() {  
  286.         startAnimation(!mChecked);  
  287.         return true;  
  288.     }  
  289.   
  290.     /** 
  291.      * Tries to claim the user's drag motion, and requests disallowing any 
  292.      * ancestors from stealing events in the drag. 
  293.      */  
  294.     private void attemptClaimDrag() {  
  295.         mParent = getParent();  
  296.         if (mParent != null) {  
  297.             mParent.requestDisallowInterceptTouchEvent(true);  
  298.         }  
  299.     }  
  300.   
  301.     /** 
  302.      * 将btnPos转换成RealPos 
  303.      *  
  304.      * @param btnPos 
  305.      * @return 
  306.      */  
  307.     private float getRealPos(float btnPos) {  
  308.         return btnPos - mBtnWidth / 2;  
  309.     }  
  310.   
  311.     @Override  
  312.     protected void onDraw(Canvas canvas) {  
  313.         canvas.saveLayerAlpha(mSaveLayerRectF, mAlpha, Canvas.MATRIX_SAVE_FLAG  
  314.                 | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG  
  315.                 | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);  
  316.         // 绘制蒙板  
  317.         canvas.drawBitmap(mMask, 0, mExtendOffsetY, mPaint);  
  318.         mPaint.setXfermode(mXfermode);  
  319.   
  320.         // 绘制底部图片  
  321.         canvas.drawBitmap(mBottom, mRealPos, mExtendOffsetY, mPaint);  
  322.         mPaint.setXfermode(null);  
  323.         // 绘制边框  
  324.         canvas.drawBitmap(mFrame, 0, mExtendOffsetY, mPaint);  
  325.   
  326.         // 绘制按钮  
  327.         canvas.drawBitmap(mCurBtnPic, mRealPos, mExtendOffsetY, mPaint);  
  328.         canvas.restore();  
  329.     }  
  330.   
  331.     @Override  
  332.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  333.         setMeasuredDimension((int) mMaskWidth, (int) (mMaskHeight + 2 * mExtendOffsetY));  
  334.     }  
  335.   
  336.     private void startAnimation(boolean turnOn) {  
  337.         mAnimating = true;  
  338.         mAnimatedVelocity = turnOn ? -mVelocity : mVelocity;  
  339.         mAnimationPosition = mBtnPos;  
  340.   
  341.         new SwitchAnimation().run();  
  342.     }  
  343.   
  344.     private void stopAnimation() {  
  345.         mAnimating = false;  
  346.     }  
  347.   
  348.     private final class SwitchAnimation implements Runnable {  
  349.   
  350.         @Override  
  351.         public void run() {  
  352.             if (!mAnimating) {  
  353.                 return;  
  354.             }  
  355.             doAnimation();  
  356.             FrameAnimationController.requestAnimationFrame(this);  
  357.         }  
  358.     }  
  359.   
  360.     private void doAnimation() {  
  361.         mAnimationPosition += mAnimatedVelocity * FrameAnimationController.ANIMATION_FRAME_DURATION  
  362.                 / 1000;  
  363.         if (mAnimationPosition <= mBtnOnPos) {  
  364.             stopAnimation();  
  365.             mAnimationPosition = mBtnOnPos;  
  366.             setCheckedDelayed(true);  
  367.         } else if (mAnimationPosition >= mBtnOffPos) {  
  368.             stopAnimation();  
  369.             mAnimationPosition = mBtnOffPos;  
  370.             setCheckedDelayed(false);  
  371.         }  
  372.         moveView(mAnimationPosition);  
  373.     }  
  374.   
  375.     private void moveView(float position) {  
  376.         mBtnPos = position;  
  377.         mRealPos = getRealPos(mBtnPos);  
  378.         invalidate();  
  379.     }  
  380. }  
2、新建一个布局文件preference_widget_checkbox.xml

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <me.imid.view.SwitchButton xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/checkbox"  
  4.     android:layout_width="wrap_content"  
  5.     android:layout_height="wrap_content"  
  6.     android:layout_gravity="right|center" />  
3、重写CheckBoxPreference并通过Inflater加载布局文件,同时屏蔽原有点击事件

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package me.imid.preference;  
  2.   
  3. import me.imid.movablecheckbox.R;  
  4. import me.imid.view.SwitchButton;  
  5.   
  6. import android.app.Service;  
  7. import android.content.Context;  
  8. import android.preference.PreferenceActivity;  
  9. import android.text.TextUtils;  
  10. import android.util.AttributeSet;  
  11. import android.view.LayoutInflater;  
  12. import android.view.View;  
  13. import android.view.ViewGroup;  
  14. import android.view.accessibility.AccessibilityEvent;  
  15. import android.view.accessibility.AccessibilityManager;  
  16. import android.widget.Checkable;  
  17. import android.widget.CompoundButton;  
  18. import android.widget.CompoundButton.OnCheckedChangeListener;  
  19. import android.widget.TextView;  
  20.   
  21. public class CheckBoxPreference extends android.preference.CheckBoxPreference {  
  22.     private Context mContext;  
  23.     private int mLayoutResId = R.layout.preference;  
  24.     private int mWidgetLayoutResId = R.layout.preference_widget_checkbox;  
  25.   
  26.     private boolean mShouldDisableView = true;  
  27.   
  28.     private CharSequence mSummaryOn;  
  29.     private CharSequence mSummaryOff;  
  30.   
  31.     private boolean mSendAccessibilityEventViewClickedType;  
  32.   
  33.     private AccessibilityManager mAccessibilityManager;  
  34.   
  35.     public CheckBoxPreference(Context context, AttributeSet attrset,  
  36.             int defStyle) {  
  37.         super(context, attrset);  
  38.         mContext = context;  
  39.         mSummaryOn = getSummaryOn();  
  40.         mSummaryOff = getSummaryOff();  
  41.         mAccessibilityManager = (AccessibilityManager) mContext  
  42.                 .getSystemService(Service.ACCESSIBILITY_SERVICE);  
  43.     }  
  44.   
  45.     public CheckBoxPreference(Context context, AttributeSet attrs) {  
  46.         this(context, attrs, android.R.attr.checkBoxPreferenceStyle);  
  47.     }  
  48.   
  49.     public CheckBoxPreference(Context context) {  
  50.         this(context, null);  
  51.     }  
  52.   
  53.     /** 
  54.      * Creates the View to be shown for this Preference in the 
  55.      * {@link PreferenceActivity}. The default behavior is to inflate the main 
  56.      * layout of this Preference (see {@link #setLayoutResource(int)}. If 
  57.      * changing this behavior, please specify a {@link ViewGroup} with ID 
  58.      * {@link android.R.id#widget_frame}. 
  59.      * <p> 
  60.      * Make sure to call through to the superclass's implementation. 
  61.      *  
  62.      * @param parent 
  63.      *            The parent that this View will eventually be attached to. 
  64.      * @return The View that displays this Preference. 
  65.      * @see #onBindView(View) 
  66.      */  
  67.     protected View onCreateView(ViewGroup parent) {  
  68.         final LayoutInflater layoutInflater = (LayoutInflater) mContext  
  69.                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  70.   
  71.         final View layout = layoutInflater.inflate(mLayoutResId, parent, false);  
  72.   
  73.         if (mWidgetLayoutResId != 0) {  
  74.             final ViewGroup widgetFrame = (ViewGroup) layout  
  75.                     .findViewById(R.id.widget_frame);  
  76.             layoutInflater.inflate(mWidgetLayoutResId, widgetFrame);  
  77.         }  
  78.         return layout;  
  79.     }  
  80.   
  81.     @Override  
  82.     protected void onBindView(View view) {  
  83.         // 屏蔽item点击事件  
  84.         view.setClickable(false);  
  85.   
  86.         TextView textView = (TextView) view.findViewById(R.id.title);  
  87.         if (textView != null) {  
  88.             textView.setText(getTitle());  
  89.         }  
  90.   
  91.         textView = (TextView) view.findViewById(R.id.summary);  
  92.         if (textView != null) {  
  93.             final CharSequence summary = getSummary();  
  94.             if (!TextUtils.isEmpty(summary)) {  
  95.                 if (textView.getVisibility() != View.VISIBLE) {  
  96.                     textView.setVisibility(View.VISIBLE);  
  97.                 }  
  98.   
  99.                 textView.setText(getSummary());  
  100.             } else {  
  101.                 if (textView.getVisibility() != View.GONE) {  
  102.                     textView.setVisibility(View.GONE);  
  103.                 }  
  104.             }  
  105.         }  
  106.   
  107.         if (mShouldDisableView) {  
  108.             setEnabledStateOnViews(view, isEnabled());  
  109.         }  
  110.   
  111.         View checkboxView = view.findViewById(R.id.checkbox);  
  112.         if (checkboxView != null && checkboxView instanceof Checkable) {  
  113.             ((Checkable) checkboxView).setChecked(isChecked());  
  114.             SwitchButton switchButton = (SwitchButton) checkboxView;  
  115.             switchButton  
  116.                     .setOnCheckedChangeListener(new OnCheckedChangeListener() {  
  117.   
  118.                         public void onCheckedChanged(CompoundButton buttonView,  
  119.                                 boolean isChecked) {  
  120.                             // TODO Auto-generated method stub  
  121.                             mSendAccessibilityEventViewClickedType = true;  
  122.                             if (!callChangeListener(isChecked)) {  
  123.                                 return;  
  124.                             }  
  125.                             setChecked(isChecked);  
  126.                         }  
  127.                     });  
  128.             // send an event to announce the value change of the CheckBox and is  
  129.             // done here  
  130.             // because clicking a preference does not immediately change the  
  131.             // checked state  
  132.             // for example when enabling the WiFi  
  133.             if (mSendAccessibilityEventViewClickedType  
  134.                     && mAccessibilityManager.isEnabled()  
  135.                     && checkboxView.isEnabled()) {  
  136.                 mSendAccessibilityEventViewClickedType = false;  
  137.   
  138.                 int eventType = AccessibilityEvent.TYPE_VIEW_CLICKED;  
  139.                 checkboxView.sendAccessibilityEventUnchecked(AccessibilityEvent  
  140.                         .obtain(eventType));  
  141.             }  
  142.         }  
  143.   
  144.         // Sync the summary view  
  145.         TextView summaryView = (TextView) view.findViewById(R.id.summary);  
  146.         if (summaryView != null) {  
  147.             boolean useDefaultSummary = true;  
  148.             if (isChecked() && mSummaryOn != null) {  
  149.                 summaryView.setText(mSummaryOn);  
  150.                 useDefaultSummary = false;  
  151.             } else if (!isChecked() && mSummaryOff != null) {  
  152.                 summaryView.setText(mSummaryOff);  
  153.                 useDefaultSummary = false;  
  154.             }  
  155.   
  156.             if (useDefaultSummary) {  
  157.                 final CharSequence summary = getSummary();  
  158.                 if (summary != null) {  
  159.                     summaryView.setText(summary);  
  160.                     useDefaultSummary = false;  
  161.                 }  
  162.             }  
  163.   
  164.             int newVisibility = View.GONE;  
  165.             if (!useDefaultSummary) {  
  166.                 // Someone has written to it  
  167.                 newVisibility = View.VISIBLE;  
  168.             }  
  169.             if (newVisibility != summaryView.getVisibility()) {  
  170.                 summaryView.setVisibility(newVisibility);  
  171.             }  
  172.         }  
  173.     }  
  174.   
  175.     /** 
  176.      * Makes sure the view (and any children) get the enabled state changed. 
  177.      */  
  178.     private void setEnabledStateOnViews(View v, boolean enabled) {  
  179.         v.setEnabled(enabled);  
  180.   
  181.         if (v instanceof ViewGroup) {  
  182.             final ViewGroup vg = (ViewGroup) v;  
  183.             for (int i = vg.getChildCount() - 1; i >= 0; i--) {  
  184.                 setEnabledStateOnViews(vg.getChildAt(i), enabled);  
  185.             }  
  186.         }  
  187.     }  
  188.   
  189. }  
4、在res/xml下新建选项设置布局文件

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >  
  3.   
  4.     <me.imid.preference.CheckBoxPreference  
  5.         android:defaultValue="true"  
  6.         android:enabled="false"  
  7.         android:summary="summary"  
  8.         android:title="MyCheckbox(disabled)" />  
  9.     <me.imid.preference.CheckBoxPreference  
  10.         android:defaultValue="true"  
  11.         android:dependency="checkbox"  
  12.         android:summaryOff="off"  
  13.         android:summaryOn="on"  
  14.         android:title="MyCheckbox(enabled)" />  
  15.     <me.imid.preference.CheckBoxPreference  
  16.         android:defaultValue="false"  
  17.         android:key="checkbox"  
  18.         android:summaryOff="off"  
  19.         android:summaryOn="on"  
  20.         android:title="MyCheckbox(enabled)" />  
  21.   
  22.     <CheckBoxPreference  
  23.         android:defaultValue="true"  
  24.         android:enabled="false"  
  25.         android:summaryOff="off"  
  26.         android:summaryOn="on"  
  27.         android:title="defalt checkbox(disabled)" />  
  28.     <CheckBoxPreference  
  29.         android:defaultValue="true"  
  30.         android:dependency="checkbox1"  
  31.         android:summaryOff="off"  
  32.         android:summaryOn="on"  
  33.         android:title="defalt checkbox(enabled)" />  
  34.     <CheckBoxPreference  
  35.         android:defaultValue="false"  
  36.         android:key="checkbox1"  
  37.         android:summaryOff="off"  
  38.         android:summaryOn="on"  
  39.         android:title="defalt checkbox(enabled)" />  
  40.   
  41. </PreferenceScreen>  
运行结果:

目录
相关文章
|
6天前
|
安全 Android开发 iOS开发
深入探索Android与iOS的差异:从系统架构到用户体验
在当今的智能手机市场中,Android和iOS无疑是最受欢迎的两大操作系统。本文旨在探讨这两个平台之间的主要差异,包括它们的系统架构、开发环境、安全性、以及用户体验等方面。通过对比分析,我们可以更好地理解为何不同的用户群体可能会偏好其中一个平台,以及这些偏好背后的技术原因。
|
13天前
|
存储 安全 Android开发
探索Android与iOS的隐私保护机制
在数字化时代,移动设备已成为我们生活的一部分,而隐私安全是用户最为关注的问题之一。本文将深入探讨Android和iOS两大主流操作系统在隐私保护方面的策略和实现方式,分析它们各自的优势和不足,以及如何更好地保护用户的隐私。
|
13天前
|
安全 数据安全/隐私保护 Android开发
探索Android与iOS的隐私保护策略
在数字时代,智能手机已成为我们生活中不可或缺的一部分,而随之而来的则是对个人隐私和数据安全的日益关注。本文将深入探讨Android与iOS两大操作系统在隐私保护方面的策略和实践,分析它们如何应对日益严峻的隐私挑战,以及用户应如何保护自己的数据安全。通过对比分析,我们将揭示两大系统在隐私保护方面的优势和不足,为用户提供有价值的见解和建议。
|
13天前
|
Android开发 Swift iOS开发
深入探索iOS与Android操作系统的架构差异及其对应用开发的影响
在当今数字化时代,移动设备已经成为我们日常生活和工作不可或缺的一部分。其中,iOS和Android作为全球最流行的两大移动操作系统,各自拥有独特的系统架构和设计理念。本文将深入探讨iOS与Android的系统架构差异,并分析这些差异如何影响应用开发者的开发策略和用户体验设计。通过对两者的比较,我们可以更好地理解它们各自的优势和局限性,从而为开发者提供有价值的见解,帮助他们在这两个平台上开发出更高效、更符合用户需求的应用。
|
8天前
|
安全 定位技术 Android开发
深入探索Android与iOS操作系统的安全性差异
【10月更文挑战第21天】 在当今数字化时代,智能手机已成为我们生活中不可或缺的一部分。其中,Android和iOS作为两大主流操作系统,各自拥有庞大的用户群体。然而,它们在安全性方面的表现却大相径庭。本文将深入探讨Android与iOS在安全机制、隐私保护以及应对恶意软件方面的差异,帮助读者更全面地了解这两个平台的安全特性。
|
14天前
|
前端开发 Android开发 开发者
探索Android与iOS的跨平台开发策略
在当今多元化的移动设备市场中,开发者面临着为不同操作系统设计应用的挑战。本文深入探讨了Android和iOS两大主流平台的跨平台开发策略。我们将分析使用Flutter、React Native等框架进行跨平台开发的优劣,并讨论如何克服各平台间的差异性,以实现高效、一致的用户体验。此外,文章还将提供一些实用的技巧和最佳实践,帮助开发者优化跨平台应用的性能和兼容性。
33 4
|
15天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异和挑战
【10月更文挑战第37天】在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统扮演着主角。它们各自拥有独特的特性、优势以及面临的开发挑战。本文将深入探讨这两个平台在开发过程中的主要差异,从编程语言到用户界面设计,再到市场分布的不同影响,旨在为开发者提供一个全面的视角,帮助他们更好地理解并应对在不同平台上进行应用开发时可能遇到的难题和机遇。
|
15天前
|
存储 安全 数据安全/隐私保护
深入探索Android与iOS的隐私保护机制:一场没有硝烟的较量####
本文深度剖析了Android与iOS两大移动操作系统在用户隐私保护方面的策略与实践,揭示两者在设计理念、技术实现及用户体验上的异同。通过对比分析,旨在为读者提供一个全面而深入的视角,理解两大平台如何在保障用户隐私的同时,实现功能的丰富与便捷。本文不涉及具体产品推荐或品牌偏好,仅从技术角度出发,探讨隐私保护的现状与挑战。 ####
|
14天前
|
安全 Android开发 iOS开发
深入探讨Android与iOS的系统架构差异
本文旨在通过对比分析Android和iOS两大移动操作系统的系统架构,揭示它们在设计理念、安全性、应用生态及开发环境等方面的显著差异。我们将从底层架构出发,逐步剖析至用户界面层面,为开发者和科技爱好者提供一份详尽的技术参考。
23 1
|
2天前
|
安全 Linux Android开发
深入探索Android与iOS的系统架构:一场技术较量
在当今数字化时代,智能手机操作系统的选择成为了用户和开发者关注的焦点。本文将深入探讨Android与iOS两大主流操作系统的系统架构,分析它们各自的优势与局限性,并对比两者在用户体验、开发生态和安全性方面的差异。通过本文的技术剖析,读者将对这两个平台的核心技术有更深入的理解。
下一篇
无影云桌面