<com.example.test.SwitchButton          android:id="@+id/wiperSwitch1"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:layout_marginLeft="100dip" />  

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); SwitchButton sb = (SwitchButton) findViewById(R.id.wiperSwitch1);          sb.setOnChangeListener(new OnChangeListener() {                            @Override              public void onChange(SwitchButton sb, boolean state) {                  // TODO Auto-generated method stub                  Log.d("switchButton", state ? "开":"关");                  Toast.makeText(MainActivity.this, state ? "开":"关", Toast.LENGTH_SHORT).show();              }          });  }}

switch 自定义SwitchButton.java

package com.example.test;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.PorterDuff.Mode;import android.graphics.PorterDuffXfermode;import android.graphics.Rect;import android.graphics.RectF;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;public class SwitchButton extends View implements android.view.View.OnClickListener{private Bitmap mSwitchBottom, mSwitchThumb, mSwitchFrame, mSwitchMask;private float mCurrentX = 0;private boolean mSwitchOn = true;//开关默认是开着的private int mMoveLength;//最大移动距离private float mLastX = 0;//第一次按下的有效区域private Rect mDest = null;//绘制的目标区域大小private Rect mSrc = null;//截取源图片的大小private int mDeltX = 0;//移动的偏移量private Paint mPaint = null;private OnChangeListener mListener = null;private boolean mFlag = false;public SwitchButton(Context context) {this(context, null);// TODO Auto-generated constructor stub}public SwitchButton(Context context, AttributeSet attrs) {this(context, attrs, 0);// TODO Auto-generated constructor stub}public SwitchButton(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stubinit();}/** * 初始化相关资源 */public void init() {mSwitchBottom = BitmapFactory.decodeResource(getResources(),R.drawable.switch_bottom);mSwitchThumb = BitmapFactory.decodeResource(getResources(),R.drawable.switch_btn_pressed);mSwitchFrame = BitmapFactory.decodeResource(getResources(),R.drawable.switch_frame);mSwitchMask = BitmapFactory.decodeResource(getResources(),R.drawable.switch_mask);setOnClickListener(this);setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubreturn false;}});mMoveLength = mSwitchBottom.getWidth() - mSwitchFrame.getWidth();mDest = new Rect(0, 0, mSwitchFrame.getWidth(), mSwitchFrame.getHeight());mSrc = new Rect();mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setAlpha(255);mPaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubsetMeasuredDimension(mSwitchFrame.getWidth(), mSwitchFrame.getHeight());}@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubsuper.onDraw(canvas);if (mDeltX > 0 || mDeltX == 0 && mSwitchOn) {if(mSrc != null) {mSrc.set(mMoveLength - mDeltX, 0, mSwitchBottom.getWidth()- mDeltX, mSwitchFrame.getHeight());} } else if(mDeltX < 0 || mDeltX == 0 && !mSwitchOn){if(mSrc != null) {mSrc.set(-mDeltX, 0, mSwitchFrame.getWidth() - mDeltX,mSwitchFrame.getHeight());}}//这儿是离屏缓冲,自己感觉类似双缓冲机制吧int count = canvas.saveLayer(new RectF(mDest), null, Canvas.MATRIX_SAVE_FLAG| Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG| Canvas.FULL_COLOR_LAYER_SAVE_FLAG| Canvas.CLIP_TO_LAYER_SAVE_FLAG);canvas.drawBitmap(mSwitchBottom, mSrc, mDest, null);canvas.drawBitmap(mSwitchThumb, mSrc, mDest, null);canvas.drawBitmap(mSwitchFrame, 0, 0, null);canvas.drawBitmap(mSwitchMask, 0, 0, mPaint);canvas.restoreToCount(count);}@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubswitch (event.getAction()) {case MotionEvent.ACTION_DOWN:mLastX = event.getX();break;case MotionEvent.ACTION_MOVE:mCurrentX = event.getX();mDeltX = (int) (mCurrentX - mLastX);// 如果开关开着向左滑动,或者开关关着向右滑动(这时候是不需要处理的)if ((mSwitchOn && mDeltX < 0) || (!mSwitchOn && mDeltX > 0)) {mFlag = true;mDeltX = 0;}if (Math.abs(mDeltX) > mMoveLength) {mDeltX = mDeltX > 0 ? mMoveLength : - mMoveLength;}invalidate();return true;case MotionEvent.ACTION_UP:if (Math.abs(mDeltX) > 0 && Math.abs(mDeltX) < mMoveLength / 2) {mDeltX = 0;invalidate();return true;} else if (Math.abs(mDeltX) > mMoveLength / 2 && Math.abs(mDeltX) <= mMoveLength) {mDeltX = mDeltX > 0 ? mMoveLength : -mMoveLength;mSwitchOn = !mSwitchOn;if(mListener != null) {mListener.onChange(this, mSwitchOn);}invalidate();mDeltX = 0;return true;} else if(mDeltX == 0 && mFlag) {//这时候得到的是不需要进行处理的,因为已经move过了mDeltX = 0;mFlag = false;return true;}return super.onTouchEvent(event);default:break;}invalidate();return super.onTouchEvent(event);}public void setOnChangeListener(OnChangeListener listener) {mListener = listener;}public interface OnChangeListener {public void onChange(SwitchButton sb, boolean state);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubmDeltX = mSwitchOn ? mMoveLength : -mMoveLength;mSwitchOn = !mSwitchOn;if(mListener != null) {mListener.onChange(this, mSwitchOn);}invalidate();mDeltX = 0;}}

更多相关文章

  1. android 笔记-scrollview滑动阴影取消
  2. listview原生态属性
  3. Android滑动手势侦测方法介绍
  4. Touch in Android
  5. Android中各种ontouch事件
  6. android 屏幕监听滑动事件
  7. Android(安卓)实现开关灯效果
  8. Android(安卓)自定义控件打造史上最简单的侧滑菜单
  9. android 抽屉式滑动demo

随机推荐

  1. Python Django对接企业微信第三方服务回
  2. python 中的排序大法
  3. Python Flask WTForms:如何在视图中动态禁
  4. 从另一个Python脚本调用Python脚本的最佳
  5. python3如何打印进度条
  6. 基于fastai的分类网络
  7. 关于Python的编码注释# -*- coding:utf-8
  8. Python列表以及列表的处理方法
  9. AttributeError:“MatrixFactorizationMo
  10. 小白学Python---面向对象02