zoukankan      html  css  js  c++  java
  • 绘制 ToggleButton --重写view

    package com.example.compoundbuttonview.view;
    
    import com.example.compoundbuttonview.R;
    
    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.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    
    public class SlideSwitchView extends View{
        /** Switch底部样式图片 */
        private Bitmap mSwitchBottom;
        /** Switch 当前样式  */
        private Bitmap mSwitchThumb;
        /** Switch无操作情况下的样式  */
        private Bitmap mSwitchThumbNormal;
        /** Switch当前手指触摸式的样式  */
        private Bitmap mSwitchThumbPressed;
        /** Switch 框架  */
        private Bitmap mSwitchFrame;
        private Bitmap mSwitchMask;
        private float mCurrentX = 0;
        /** Switch 开关状态,默认是  开:true  */
        private boolean mSwitchOn = true;
        /** Switch 最大移动距离   */
        private int mMoveLength;
        /** 第一次按下的有效区域 */
        private float mLastX = 0;
        /** 绘制的目标区域大小  */
        private Rect mDest = null; 
        /** 截取源图片的大小  */
        private Rect mSrc = null;
        /** Switch 移动的偏移量  */
        private int mMoveDeltX = 0;
        /** 画笔工具  */
        private Paint mPaint = null;
        /** Switch 状态监听接口  */
        private OnSwitchChangedListener switchListener = null;
        private boolean mFlag = false;
        /** enabled 属性 为 true */
        private boolean mEnabled = true;
        /** 最大透明度,就是不透明 */
        private final int MAX_ALPHA = 255;
        /** 当前透明度,这里主要用于如果控件的enable属性为false时候设置半透明 ,即不可以点击 */
        private int mAlpha = MAX_ALPHA;
        /** Switch 判断是否在拖动 */
        private boolean mIsScrolled =false;
        
        public SlideSwitchView(Context context) {
            this(context, null);
        }
    
        public SlideSwitchView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public SlideSwitchView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }
    
        /**
         * 初始化相关资源
         */
        public void init() {
            mSwitchThumbPressed = BitmapFactory.decodeResource(getResources(),R.drawable.checkswitch_btn_pressed);
            mSwitchThumbNormal = BitmapFactory.decodeResource(getResources(),R.drawable.checkswitch_btn_unpressed);
            mSwitchBottom = BitmapFactory.decodeResource(getResources(),R.drawable.checkswitch_bottom);
            mSwitchFrame = BitmapFactory.decodeResource(getResources(),R.drawable.checkswitch_frame);
            mSwitchMask = BitmapFactory.decodeResource(getResources(),R.drawable.checkswitch_mask);
            mSwitchThumb = mSwitchThumbNormal;
            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));
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // TODO Auto-generated method stub
            setMeasuredDimension(mSwitchFrame.getWidth(), mSwitchFrame.getHeight());
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            // TODO Auto-generated method stub
            super.onDraw(canvas);
            if (mMoveDeltX > 0 || mMoveDeltX == 0 && mSwitchOn) {
                if (mSrc != null) {
                    mSrc.set(mMoveLength - mMoveDeltX, 0, mSwitchBottom.getWidth()
                            - mMoveDeltX, mSwitchFrame.getHeight());
                }
            } else if (mMoveDeltX < 0 || mMoveDeltX == 0 && !mSwitchOn) {
                if (mSrc != null) {
                    mSrc.set(-mMoveDeltX, 0, mSwitchFrame.getWidth() - mMoveDeltX,
                            mSwitchFrame.getHeight());
                }
            }
            Log.d("mAlpha", "mAlpha:" + mAlpha);
            //绘制一个不透明矩形 为白色 和黑色底衬 成灰色
            canvas.saveLayerAlpha(new RectF(mDest), 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(mSwitchBottom, mSrc, mDest, null);
            canvas.drawBitmap(mSwitchThumb, mSrc, mDest, null);
            canvas.drawBitmap(mSwitchFrame, 0, 0, null);
            canvas.drawBitmap(mSwitchMask, 0, 0, mPaint);
            canvas.restore();
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // TODO Auto-generated method stub
            //如果Enabled属性设定为true,触摸效果才有效
            if(!mEnabled){
                return true;
            }
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mSwitchThumb = mSwitchThumbPressed;
                mLastX = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                mCurrentX = event.getX();
                mMoveDeltX = (int) (mCurrentX - mLastX);
                if(mMoveDeltX > 10){
                    //设置了10这个误差距离,可以更好的实现点击效果
                    mIsScrolled = true;
                }
                // 如果开关开着向左滑动,或者开关关着向右滑动(这时候是不需要处理的)
                if ((mSwitchOn && mMoveDeltX < 0) || (!mSwitchOn && mMoveDeltX > 0)) {
                    mFlag = true;
                    mMoveDeltX = 0;
                }
    
                if (Math.abs(mMoveDeltX) > mMoveLength) {
                    mMoveDeltX = mMoveDeltX > 0 ? mMoveLength : -mMoveLength;
                }
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                mSwitchThumb = mSwitchThumbNormal;
                //如果没有滑动过,就看作一次点击事件
                if(!mIsScrolled){
                    mMoveDeltX = mSwitchOn ? mMoveLength : -mMoveLength;
                    mSwitchOn = !mSwitchOn;
                    if (switchListener != null) {
                        switchListener.onSwitchChange(this, mSwitchOn);
                    }
                    invalidate();
                    mMoveDeltX = 0;
                    break;
                }
                mIsScrolled = false;
                if (Math.abs(mMoveDeltX) > 0 && Math.abs(mMoveDeltX) < mMoveLength / 2) {
                    mMoveDeltX = 0;
                    invalidate();
                } else if (Math.abs(mMoveDeltX) > mMoveLength / 2
                        && Math.abs(mMoveDeltX) <= mMoveLength) {
                    mMoveDeltX = mMoveDeltX > 0 ? mMoveLength : -mMoveLength;
                    mSwitchOn = !mSwitchOn;
                    if (switchListener != null) {
                        switchListener.onSwitchChange(this, mSwitchOn);
                    }
                    invalidate();
                    mMoveDeltX = 0;
                } else if (mMoveDeltX == 0 && mFlag) {
                    // 这时候得到的是不需要进行处理的,因为已经move过了
                    mMoveDeltX = 0;
                    mFlag = false;
                }
            default:
                break;
            }
            invalidate();
            return true;
        }
        /** 
         * 设置 switch 状态监听 
         * */
        public void setOnChangeListener(OnSwitchChangedListener listener) {
            switchListener = listener;
        }
        /** 
         * switch 开关监听接口
         *  */
        public interface OnSwitchChangedListener{
            public void onSwitchChange(SlideSwitchView switchView, boolean isChecked);
        }
        
        @Override
        public void setEnabled(boolean enabled) {
            // TODO Auto-generated method stub
            mEnabled = enabled;
            mAlpha = enabled ? MAX_ALPHA : MAX_ALPHA/2;
            Log.d("enabled",enabled ? "true": "false");
            super.setEnabled(enabled);
            invalidate();
        }
        
        /** 自动判断切换至相反的属性 : true -->false ;false -->true */
        public void toggle() {
            setChecked(!mSwitchOn);
        }
        
        /** 设置选中的状态(选中:true   非选中: false) */
        public void setChecked(boolean checked) {
            mSwitchOn = checked;
            invalidate();
        }
    }
  • 相关阅读:
    Spring三大器
    SpringBoot启动过程
    linux常用命令
    Controller当中的参数与返回值
    Spring加载context的几种方法
    Spring基础(imooc)
    SpringMVC框架学习
    Spring MVC(imooc)
    springAOP基础
    《别傻了,你的中年危机真不是因为穷》
  • 原文地址:https://www.cnblogs.com/newsouls/p/4728256.html
Copyright © 2011-2022 走看看