首先上两张蹩脚的效果图:
效果:可以点击切换,也可以拖动切换
先上代码:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:orientation="vertical" >
- <com.example.slidingswitchview.slideswitch.SlidingSwitchView
- android:id="@+id/swithview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- </LinearLayout>
1,初始化部分:
- private Bitmap mSwitch_on, mSwitch_off, mTthumb;
- private Paint mPaint;
- private int viewWidth, viewHeigth, thumbWidthHalf, thumbWidth;
- //记录上一次点击的X坐标和当前的X坐标
- private int mLastX, mCurrentX;
- // 是否滑动
- private boolean isScrolling = false;
- // 开关所在的方向,左or右
- private boolean isSwitchLeft = false;
- // 是否是移动状态
- private boolean isMoving = false;
- //是否移动过,如果为false代表是单机时间
- private boolean hasMoving = false;
- private int mMoveDistance = 0;
- private int mMoveX = 0;
- private FontMetrics mFontMetrics;
- private float mTextX, mTextY;
- private String mOnText = "on";
- private String mOffText = "off";
- // 0:静止、1:向左、2:向右
- private int mScrollingStatus = 0;
- private static final float GESTURE_THRESHOLD_DIP = 10.0f;
- final float scale = getContext().getResources().getDisplayMetrics().density;
- private IOnSwitchChangerListener mChangerListener = null;
- public SlidingSwitchView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initBitmapResource();
- initConstant();
- initPaint();
- initFontMetrics();
- }
- private void initConstant() {
- viewWidth = mSwitch_on.getWidth() + getPaddingLeft() + getPaddingRight();
- viewHeigth = mSwitch_on.getHeight() + getPaddingTop() + getPaddingBottom();
- thumbWidth = mTthumb.getWidth();
- thumbWidthHalf = thumbWidth / 2;
- if (isSwitchLeft) {
- mMoveDistance = 0;
- } else {
- mMoveDistance = viewWidth - thumbWidthHalf;
- }
- mScrollingStatus = 0;
- }
- private void initBitmapResource() {
- mSwitch_on = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.on);
- mSwitch_off = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.off);
- mTthumb = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.thumb);
- }
- private void initPaint() {
- mPaint = new Paint();
- mPaint.setAntiAlias(true);
- }
- private void initFontMetrics() {
- // viewWidth: 155,
- // viewHeigth: 61
- // ascent: -11.1328125
- // top: -12.673828
- // bottom: 3.2519531 ,
- // descent: 2.9296875 ,
- // leading: 0.0 ,
- mPaint.setTextSize(getTextSize(GESTURE_THRESHOLD_DIP));
- mFontMetrics = mPaint.getFontMetrics();
- mTextX = (viewWidth >> 1) - (int) (mPaint.measureText(mOnText)) >> 1;
- // baseline位置字体下基准线位置
- // mTextY代表baseline的位置 字体高度为:(mFontMetrics.descent -
- // mFontMetrics.ascent) / 2
- // 字体上下居中的推到公式为:控件高度/2 + 字体高度/2 -
- // mFontMetrics.bottom(注:bottom的高度通常情况下比较小)
- mTextY = ((mFontMetrics.descent - mFontMetrics.ascent) / 2 - mFontMetrics.bottom) + viewHeigth / 2;
- }
注:initFontMetrics()方法是在是因为没有现成的图,就手动把文字写上去
2,绘制部分:
重写onDraw方法完成绘制,分3种情况:1、手指移动状态:isMoveing 2、控件处于滑动状态:isScrolling 3、初始化状态 。 其中isScrolling状态分为手指滑动过和未滑动过(也视为单击状态)两种情况。通过mMoveDistance和mCurrentX判断如何绘制。
重写onTouchEvent方法,ACTION_UP中hasMoving判断此次点击是不是单击事件。
- @Override
- protected void onDraw(Canvas canvas) {
- if (isMoving) {
- if (mMoveDistance <= 0) {
- drawbitmap(canvas, 0, 0);
- } else if (mMoveDistance >= viewWidth - thumbWidth) {
- drawbitmap(canvas, viewWidth - thumbWidthHalf, viewWidth - thumbWidth);
- } else {
- drawbitmap(canvas, mMoveDistance + thumbWidthHalf, mMoveDistance);
- }
- } else if (isScrolling) {
- drawbitmap(canvas, mMoveDistance + thumbWidthHalf, mMoveDistance);
- // 点击向右滑动
- if (mCurrentX > viewWidth / 2 && mScrollingStatus == 2) {
- mMoveDistance = mMoveDistance + SCROLLING_OFFSET;
- }
- // 点击向左滑动
- else if (mCurrentX <= viewWidth / 2 && mScrollingStatus == 1) {
- mMoveDistance = mMoveDistance - SCROLLING_OFFSET;
- } else
- // MOVE向右滑动
- if (mMoveDistance + thumbWidthHalf > viewWidth / 2) {
- mMoveDistance = mMoveDistance + SCROLLING_OFFSET;
- }
- // MOVE向左滑动
- else {
- mMoveDistance = mMoveDistance - SCROLLING_OFFSET;
- }
- refreshState();
- } else {
- // 初始化状态 这个应该跟外部关联
- drawbitmap(canvas, mMoveDistance, mMoveDistance == 0 ? 0 : viewWidth - thumbWidth);
- mLastX = 0;
- mCurrentX = 0;
- }
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (isScrolling) {
- return true;
- }
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mLastX = (int) event.getX();
- break;
- case MotionEvent.ACTION_MOVE:
- isMoving = true;
- hasMoving = true;
- mCurrentX = (int) event.getX();
- mMoveX = mCurrentX - mLastX;
- mLastX = mCurrentX;
- mMoveDistance = mMoveDistance + mMoveX;
- postInvalidate();
- break;
- case MotionEvent.ACTION_UP:
- isMoving = false;
- mCurrentX = (int) event.getX();
- if (!hasMoving) {
- if (mCurrentX < viewWidth / 2 && !isSwitchLeft) {
- mMoveDistance = viewWidth - thumbWidth - SCROLLING_OFFSET;
- mScrollingStatus = 1;
- } else if (mCurrentX >= viewWidth / 2 && isSwitchLeft) {
- mMoveDistance = mMoveDistance + SCROLLING_OFFSET;
- mScrollingStatus = 2;
- }
- hasMoving = false;
- }
- refreshState();
- break;
- default:
- break;
- }
- return true;
- }
- private void refreshState() {
- if (mScrollingStatus != 0 && (viewWidth - thumbWidth > mMoveDistance && mMoveDistance > 0)) {
- isScrolling = true;
- } else {
- if (mMoveDistance <= 0) {
- relaseConstant();
- mMoveDistance = 0;
- isSwitchLeft = true;
- if (mChangerListener != null) {
- mChangerListener.onSwitchChanger(this, isSwitchLeft);
- }
- } else if (mMoveDistance >= viewWidth - thumbWidth) {
- relaseConstant();
- mMoveDistance = viewWidth - thumbWidthHalf;
- isSwitchLeft = false;
- if (mChangerListener != null) {
- mChangerListener.onSwitchChanger(this, isSwitchLeft);
- }
- } else {
- isScrolling = true;
- }
- }
- postInvalidate();
- }
- private void relaseConstant() {
- isMoving = false;
- isScrolling = false;
- hasMoving = false;
- mScrollingStatus = 0;
- }
- /**
- * 绘制按钮
- *
- * @param canvas
- * @param mDistance
- * @param mTthumb_to_left
- */
- private void drawbitmap(Canvas canvas, int mDistance, int mTthumb_to_left) {
- canvas.drawBitmap(mSwitch_on, new Rect(0, 0, mDistance, viewHeigth), new Rect(0, 0, mDistance, viewHeigth), mPaint);
- mPaint.setColor(Color.WHITE);
- canvas.drawText(mOnText, getTextSize(GESTURE_THRESHOLD_DIP), mTextY, mPaint);
- canvas.drawBitmap(mSwitch_off, new Rect(mDistance, 0, viewWidth, viewHeigth), new Rect(mDistance, 0, viewWidth, viewHeigth), mPaint);
- mPaint.setColor(Color.GRAY);
- canvas.drawText(mOffText, viewWidth / 2 + getTextSize(12f), mTextY, mPaint);
- canvas.drawBitmap(mTthumb, mTthumb_to_left, 0, mPaint);
- }
demo戳这里:点击打开链接
写博客,更多的是对自己的一个积累,方便日后总结。最后贴出代码,代码不是很好,欢迎指正!