自定义Switch控件二

来源:互联网 发布:程序员技能树 编辑:程序博客网 时间:2024/06/05 03:19

这是一个自定义控件,出来的效果跟ToggleButton差不多,主要是项目中用着很好用

public class UISwitchButton extends CheckBox {private Paint mPaint;private RectF mSaveLayerRectF;private float mFirstDownY;private float mFirstDownX;private int mClickTimeout;private int mTouchSlop;private final int MAX_ALPHA = 255;private int mAlpha = MAX_ALPHA;private boolean mChecked = false; private boolean mBroadcasting;// 标示是否正在执行监听事件�?private boolean mTurningOn;// 标示位置是否达到�?启状�?private PerformClick mPerformClick;private OnCheckedChangeListener mOnCheckedChangeListener;private OnCheckedChangeListener mOnCheckedChangeWidgetListener;private boolean mAnimating;// 标示是否继续执行移动动画private final float VELOCITY = 350;// 定义按钮动画移动的最大长�?private float mVelocity;// 按钮动画移动的最大像素长�?private float mAnimationPosition;// 按钮动画移动的当前位�?private float mAnimatedVelocity;// 按钮动画移动的实际位�?(+mVelocity/-mVelocity)private Bitmap bmBgGreen;// 绿色背景private Bitmap bmBgWhite;// 白色背景private Bitmap bmBtnNormal;// 未按下时按钮private Bitmap bmBtnPressed;// 按下时按�?private Bitmap bmCurBtnPic;// 当前显示的按钮图�?private Bitmap bmCurBgPic;// 当前背景图片private float bgWidth;// 背景宽度private float bgHeight;// 背景宽度private float btnWidth;// 按钮宽度private float offBtnPos;// 按钮关闭时位�?private float onBtnPos;// 按钮�?启时位置private float curBtnPos;// 按钮当前位置private float startBtnPos;// �?始按钮位�?private final int COMMON_WIDTH_IN_PIXEL = 90;// 默认宽度private final int COMMON_HEIGHT_IN_PIXEL = 50;// 默认高度public UISwitchButton(Context context, AttributeSet attrs) {this(context, attrs, android.R.attr.checkboxStyle);}public UISwitchButton(Context context) {this(context, null);}public UISwitchButton(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(context, attrs);}private void init(Context context, AttributeSet attrs) {mPaint = new Paint();mPaint.setColor(Color.WHITE);Resources resources = context.getResources();// get attrConfigurationTypedArray array = context.obtainStyledAttributes(attrs,R.styleable.SwitchButton);int width = (int) array.getDimensionPixelSize(R.styleable.SwitchButton_bmWidth, 0);int height = (int) array.getDimensionPixelSize(R.styleable.SwitchButton_bmHeight, 0);array.recycle();// size width or heightif (width <= 0 || height <= 0) {width = COMMON_WIDTH_IN_PIXEL;height = COMMON_HEIGHT_IN_PIXEL;} else {float scale = (float) COMMON_WIDTH_IN_PIXEL/ COMMON_HEIGHT_IN_PIXEL;if ((float) width / height > scale) {width = (int) (height * scale);} else if ((float) width / height < scale) {height = (int) (width / scale);}}// get viewConfigurationmClickTimeout = ViewConfiguration.getPressedStateDuration()+ ViewConfiguration.getTapTimeout();mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();// get BitmapbmBgGreen = BitmapFactory.decodeResource(resources,R.drawable.switch_btn_bg_green);bmBgWhite = BitmapFactory.decodeResource(resources,R.drawable.switch_btn_bg_white);bmBtnNormal = BitmapFactory.decodeResource(resources,R.drawable.switch_btn_normal);bmBtnPressed = BitmapFactory.decodeResource(resources,R.drawable.switch_btn_pressed);// size BitmapbmBgGreen = Bitmap.createScaledBitmap(bmBgGreen, width, height, true);bmBgWhite = Bitmap.createScaledBitmap(bmBgWhite, width, height, true);bmBtnNormal = Bitmap.createScaledBitmap(bmBtnNormal, height, height,true);bmBtnPressed = Bitmap.createScaledBitmap(bmBtnPressed, height, height,true);bmCurBtnPic = bmBtnNormal;// 初始按钮图片bmCurBgPic = mChecked ? bmBgGreen : bmBgWhite;// 初始背景图片bgWidth = bmBgGreen.getWidth();// 背景宽度bgHeight = bmBgGreen.getHeight();// 背景高度btnWidth = bmBtnNormal.getWidth();// 按钮宽度offBtnPos = 0;// 关闭时在�?左边onBtnPos = bgWidth - btnWidth;// �?始时在右�?curBtnPos = mChecked ? onBtnPos : offBtnPos;// 按钮当前为初始位�?// get densityfloat density = resources.getDisplayMetrics().density;mVelocity = (int) (VELOCITY * density + 0.5f);// 动画距离mSaveLayerRectF = new RectF(0, 0, bgWidth, bgHeight);}@Overridepublic void setEnabled(boolean enabled) {mAlpha = enabled ? MAX_ALPHA : MAX_ALPHA / 3;super.setEnabled(enabled);}public boolean isChecked() {return mChecked;}public void toggle() {setChecked(!mChecked);}private void setCheckedDelayed(final boolean checked) {postDelayed(new Runnable() {@Overridepublic void run() {setChecked(checked);}}, 10);}public void setChecked(boolean checked) {if (mChecked != checked) {mChecked = checked;// 初始化按钮位�?curBtnPos = checked ? onBtnPos : offBtnPos;// 改变背景图片bmCurBgPic = checked ? bmBgGreen : bmBgWhite;invalidate();if (mBroadcasting) {// NO-OPreturn;}// 正在执行监听事件mBroadcasting = true;if (mOnCheckedChangeListener != null) {mOnCheckedChangeListener.onCheckedChanged(UISwitchButton.this,mChecked);}if (mOnCheckedChangeWidgetListener != null) {mOnCheckedChangeWidgetListener.onCheckedChanged(UISwitchButton.this, mChecked);}// 监听事件结束mBroadcasting = false;}}public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {mOnCheckedChangeListener = listener;}void setOnCheckedChangeWidgetListener(OnCheckedChangeListener listener) {mOnCheckedChangeWidgetListener = listener;}@Overridepublic boolean onTouchEvent(MotionEvent event) {int action = event.getAction();float x = event.getX();float y = event.getY();float deltaX = Math.abs(x - mFirstDownX);float deltaY = Math.abs(y - mFirstDownY);switch (action) {case MotionEvent.ACTION_DOWN:ViewParent mParent = getParent();if (mParent != null) {// 通知父控件不要拦截本view的触摸事�?mParent.requestDisallowInterceptTouchEvent(true);}mFirstDownX = x;mFirstDownY = y;bmCurBtnPic = bmBtnPressed;startBtnPos = mChecked ? onBtnPos : offBtnPos;break;case MotionEvent.ACTION_MOVE:float time = event.getEventTime() - event.getDownTime();curBtnPos = startBtnPos + event.getX() - mFirstDownX;if (curBtnPos >= onBtnPos) {curBtnPos = onBtnPos;}if (curBtnPos <= offBtnPos) {curBtnPos = offBtnPos;}mTurningOn = curBtnPos > bgWidth / 2 - btnWidth / 2;break;case MotionEvent.ACTION_UP:bmCurBtnPic = bmBtnNormal;time = event.getEventTime() - event.getDownTime();if (deltaY < mTouchSlop && deltaX < mTouchSlop&& time < mClickTimeout) {if (mPerformClick == null) {mPerformClick = new PerformClick();}if (!post(mPerformClick)) {performClick();}} else {startAnimation(mTurningOn);}break;}invalidate();return isEnabled();}private class PerformClick implements Runnable {public void run() {performClick();}}@Overridepublic boolean performClick() {startAnimation(!mChecked);return true;}@Overrideprotected void onDraw(Canvas canvas) {canvas.saveLayerAlpha(mSaveLayerRectF, mAlpha, 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(bmCurBgPic, 0, 0, mPaint);// 绘制按钮canvas.drawBitmap(bmCurBtnPic, curBtnPos, 0, mPaint);canvas.restore();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension((int) bgWidth, (int) bgHeight);}private void startAnimation(boolean turnOn) {mAnimating = true;mAnimatedVelocity = turnOn ? mVelocity : -mVelocity;mAnimationPosition = curBtnPos;new SwitchAnimation().run();}private void stopAnimation() {mAnimating = false;}private final class SwitchAnimation implements Runnable {@Overridepublic void run() {if (!mAnimating) {return;}doAnimation();requestAnimationFrame(this);}}private void doAnimation() {mAnimationPosition += mAnimatedVelocity * ANIMATION_FRAME_DURATION/ 1000;if (mAnimationPosition <= offBtnPos) {stopAnimation();mAnimationPosition = offBtnPos;setCheckedDelayed(false);} else if (mAnimationPosition >= onBtnPos) {stopAnimation();mAnimationPosition = onBtnPos;setCheckedDelayed(true);}curBtnPos = mAnimationPosition;invalidate();}private static final int MSG_ANIMATE = 1000;public static final int ANIMATION_FRAME_DURATION = 1000 / 60;public void requestAnimationFrame(Runnable runnable) {Message message = new Message();message.what = MSG_ANIMATE;message.obj = runnable;mHandler.sendMessageDelayed(message, ANIMATION_FRAME_DURATION);}private Handler mHandler = new Handler() {public void handleMessage(Message m) {switch (m.what) {case MSG_ANIMATE:if (m.obj != null) {((Runnable) m.obj).run();}break;}}};}



switchBnt.setOnCheckedChangeListener(new OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {// TODO Auto-generated method stubif (!NetUtils.isConnected(AppApplication.geContext())) {switchBnt.setChecked(false);Toast.makeText(SettingActivity.this, "请打开网络!", Toast.LENGTH_SHORT).show();return;}if (isChecked) {SpUtils.put(SettingActivity.this, "pushflag", true);PushService.startIntent(SettingActivity.this);} else {SpUtils.put(SettingActivity.this, "pushflag", false);PushService.stopIntent(SettingActivity.this);}}});}



0 0
原创粉丝点击