1. 程式人生 > >自定義Switch開關控制元件

自定義Switch開關控制元件

自定義Switch開關控制元件

*做安卓也有一年多了*,一直想去學習**自定義控制元件**這一塊(其實是自己懶–!),最近閒下來看了很多關於自定義控制元件方面的東西,雖然不是很熟練,但是基本上能去弄清楚它的實現方式有哪些。。也自己試著去模仿別人的程式碼做了一些自定義的控制元件,其中就有接下來我要寫的自定義Switch控制元件,做的不好請大家見諒–!(大神勿噴)

好了廢話不多說直接上效果圖!
[開起](https://img-blog.csdn.net/20170224133316287?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzQ4NzQwNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)![關閉](https://img-blog.csdn.net/20170224133352866?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzQ4NzQwNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
沒有動圖工具,懶得做了,效果很簡單。。開啟和關閉顏色可以自己去設定。。。做自定義控制元件有幾步去走,只要思路清晰了,剩下的就是實現的方法了。
1. 自定義控制元件的第一步
在arr檔案中去配置自己控制元件裡的所用到的屬性(你也可以定死–!,但是為了不重複造輪子,你懂得)
配置檔案程式碼如下

` <declare-styleable name="MySwitchButton">
        <attr name="themeColor2" format="color"/>
        <attr name="isOpen2" format="boolean"/>
    </declare-styleable>`<br/>
2. 自定義控制元件的第二步
在自定義view中獲取這些值
` */
    public MySwitchButton(Context context, AttributeSet attrs) {
        super(context, attrs);
paint = new Paint(); paint.setAntiAlias(true); TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.MySwitchButton); isOpen =typedArray.getBoolean(R.styleable.MySwitchButton_isOpen2,false); theme_color =typedArray.getColor(R.styleable.MySwitchButton
_themeColor2, Color.GREEN); typedArray.recycle(); }

3. 自定義控制元件第三步
在onMeasure()方法中去測量現在的控制元件大小` /**
     * 自定義控制元件第二步,在onMeasure方法中去計算控制元件的寬高
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = measureDimension(widthMeasureSpec,280);
        int height =measureDimension(heightMeasureSpec,140);
        if (width<height){
            width = height * 2;
        }
        setMeasuredDimension(width,height);
        initView();
    }

    /**
     * 封裝測量的程式碼 減少程式碼冗餘
     */
    private int measureDimension(int Measure,int defuldim){
        int result;
        int mode = MeasureSpec.getMode(Measure);
        int size = MeasureSpec.getSize(Measure);
        if (mode==MeasureSpec.EXACTLY){
            result =size;
        }else {
            result =defuldim;
            if (mode==MeasureSpec.AT_MOST){
                result=Math.min(result, size);
            }
        }
        return result;
    }
    /**
     * 在onMeasure方法中去初始化變數,畫筆等
     */
    public void initView(){
        int width =getMeasuredWidth();
        int height =getMeasuredHeight();
        backRect = new Rect();
        circleRect = new Rect();
        backRectF = new RectF();
        circleRectF = new RectF();
        backRect.set(0,0,width,height);
        min_left =MIN_SIZE;
        max_left =width -(height-2*MIN_SIZE)-MIN_SIZE;
        if (isOpen){
            circle_left =max_left;
            alpha=255;
        }else {
            alpha=0;
            circle_left=MIN_SIZE;
        }
        left_begin =circle_left;
    }`
4. 自定義控制元件第三步
在onDraw方法中把按鈕繪製出來
 '/**
     * 自定義控制元件第三步,在ondraw方法中繪製
     */
    @Override
    protected void onDraw(Canvas canvas) {

        int radius;
        radius = backRect.height() / 2;
        paint.setColor(Color.GRAY);
        backRectF.set(backRect);
        canvas.drawRoundRect(backRectF, radius, radius, paint);
        paint.setColor(theme_color);
        paint.setAlpha(alpha);
        canvas.drawRoundRect(backRectF, radius, radius, paint);
        circleRect.set(circle_left, MIN_SIZE, circle_left
                + backRect.height() - 2 * MIN_SIZE, backRect.height()
                - MIN_SIZE);
        circleRectF.set(circleRect);
        paint.setColor(Color.WHITE);
        canvas.drawRoundRect(circleRectF, radius, radius, paint);
    }
5. 第五步
在onThouch方法中監聽手勢
/**
     * 自定義控制元件第三步,在onThouch方法裡寫滑動事件
     */


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = MotionEventCompat.getActionMasked(event);
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                eventStartX = (int) event.getRawX();
                break;
            case MotionEvent.ACTION_MOVE:
                eventEndX = (int) event.getRawX();
                diffX = eventEndX - eventStartX;
                int tempX = diffX + left_begin;
                tempX = (tempX > max_left ? max_left : tempX);
                tempX = (tempX < min_left ? min_left : tempX);
                if (tempX >= min_left && tempX <= max_left) {
                    circle_left = tempX;
                    alpha = (int) (255 * (float) tempX / (float) max_left);
                    invalidateView();
                }
                break;
            case MotionEvent.ACTION_UP:
                int wholeX = (int) (event.getRawX() - eventStartX);
                left_begin = circle_left;
                boolean toRight;
                toRight = (left_begin > max_left / 2 ? true : false);
                if (Math.abs(wholeX) < 3) {
                    toRight = !toRight;
                }
                moveToDest(toRight);
                break;
            default:
                break;
        }
        return true;
    }
6. 第六步
寫對外暴露的介面
public void setOnChangeListener(OnChangeListener onChangeListener){
        this.onChangeListener =onChangeListener;
    }
    public interface OnChangeListener{
        void changelistener(boolean flag);
    }
然後大功告成 ,打完收工,具體的程式碼後面附上,雖然寫的很粗糙,但是寫完以後還是對自定義控制元件有了更深的理解,以後還會繼續去嘗試,誰讓我還是個菜雞呢···略略略–!
[戳這裡](http://download.csdn.net/detail/u013487404/9762913%20%E6%88%B3%E8%BF%99%E9%87%8C)