android 自定义开关按钮

MyToggleView.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.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * 自定义开关按钮 android绘制界面的流程:
 * onMeasure(测量:指定view的宽和高)--->onLayout(摆放view的位置)---->onDraw(绘制内容),
 * 如果要实现自定义控件,就要重写这些方法,这些方法在onResume方法之后执行
 * 
 * 如果是继承View,那么只需要重写onMeasure和onDraw方法
 * 如果是继承ViewGroup,那么需要重写onMeasure,onLayout,onDraw方法
 * 
 * @author Administrator
 * 
 */
public class MyToggleView extends View {

    private Bitmap switchBackgroundBitmap; // 开关的背景图片
    private Paint paint; // 画笔对象
    private Bitmap slideButtonBitmap; // 滑动开关的图片
    boolean mSwitchState; // 设置开关的状态
    float currentX;       //触摸滑动按钮时,获取滑动按钮的x坐标
    boolean isTouchingSlideButton = false; // 是否触摸滑动按钮
    private OnSwitchStateChangedListener onSwitchStateChangedListener;

    public MyToggleView(Context context) {
        super(context);
        init();
    }

    public MyToggleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MyToggleView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public void init() {
        paint = new Paint();//新建画笔对象
    }

    // 测量自定义开关的背景图片的宽度和高度
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(switchBackgroundBitmap.getWidth(),
                switchBackgroundBitmap.getHeight());
    }

    // 绘制自定义开关
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // 绘制开关的背景图片
        canvas.drawBitmap(switchBackgroundBitmap, 0, 0, paint);

        // 绘制滑动按钮的图片
        if (isTouchingSlideButton) {// 正在触摸滑动按钮

            // 让滑块向左移动自身一半大小的位置
            float newLeft = currentX - slideButtonBitmap.getWidth() / 2.0f;
            float maxLeft = switchBackgroundBitmap.getWidth()
                    - slideButtonBitmap.getWidth();

            // 限制滑动按钮的水平方向的范围
            if (newLeft < 0) {// 限制左边的范围
                newLeft = 0;
            }
            if (newLeft > maxLeft) {// 限制右边的范围
                newLeft = maxLeft;
            }
            canvas.drawBitmap(slideButtonBitmap, newLeft, 0, paint);
        } else {
            // //根据开关的状态来绘制滑动按钮图片
            if (mSwitchState) {// 如果开关为开的时候,距离左边的距离为=背景图片的宽度-滑动按钮的宽度
                int left = switchBackgroundBitmap.getWidth()
                        - slideButtonBitmap.getWidth();
                canvas.drawBitmap(slideButtonBitmap, left, 0, paint);
            } else {// 如果开关为关闭的时候,距离左边的距离就为0
                canvas.drawBitmap(slideButtonBitmap, 0, 0, paint);
            }
        }
    }

    // 设置开关背景资源
    public void setSwitchBackgroundResource(int id) {
        switchBackgroundBitmap = BitmapFactory.decodeResource(getResources(),
                id);
    }

    // 设置滑动按钮的资源
    public void setSlideButtonResource(int slideButtonId) {
        slideButtonBitmap = BitmapFactory.decodeResource(getResources(),
                slideButtonId);
    }

    // 设置自定义开关的状态
    public void setSwitchState(boolean mSwitchState) {
        this.mSwitchState = mSwitchState;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            isTouchingSlideButton = true;
            System.out.println("---ACTION_DOWN  :" + event.getX());
            currentX = event.getX();
            break;
        case MotionEvent.ACTION_MOVE:
            System.out.println("----ACTION_MOVE  :" + event.getX());
            currentX = event.getX();
            break;
        case MotionEvent.ACTION_UP:
            isTouchingSlideButton = false;
            System.out.println("----ACTION_UP  :" + event.getX());
            currentX = event.getX();

            float center = switchBackgroundBitmap.getWidth() / 2.0f;

            boolean currentSwitchState = currentX > center;
            if (currentSwitchState != mSwitchState
                    && onSwitchStateChangedListener != null) {
                onSwitchStateChangedListener.onStateChanged(currentSwitchState);
            }
            mSwitchState = currentSwitchState;
            break;
        }
        invalidate();// 重绘view,即重写调用onDraw方法

        return true;// 返回true,才响应触摸事件
    }

    public interface OnSwitchStateChangedListener {
        // 状态回调,将当前开关的状态传到UI界面上去
        public void onStateChanged(boolean state);
    }

    public void setOnSwitchStateChanged(
            OnSwitchStateChangedListener onSwitchStateChangedListener) {
        this.onSwitchStateChangedListener = onSwitchStateChangedListener;
    }
}

实验截图:
这里写图片描述

源码下载地址:
http://download.csdn.net/detail/u013209983/9740616

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值