快速实现自定义控件开关按钮

今天给大家简单的讲一下自定义控件是如何实现开关按钮的,也是最近学了一点的收获,给大家分享一下。如有什么不同的意见,还望不要吝啬,多多指教。
首先,我们谈谈什么是自定义控件,为什么要有自定义控件?
答:自定义控件,顾名思义就是我们自己定义的控件就是自定义控件咯,有点流氓,但就是这么解释的。那我们为什么要使用自定义控件呢?也就是谷歌给我们封装了很多是API提供我们使用,但有时候为了满足客户的需求,也使我们的产品更加看着牛X,所以在我们的开发中会大量的接触到自定义控件。重要性就不和大家赘述了,开始我们的表演。
其次:自定义控件是怎么样?
答:大家都知道,我们不论什么控件都是extends View或者是ViewGroup。ViewGroup就是View的一个容器。
现在咱们就一起来实现一下,给大家介绍几个方法,也是我们自定控件时必要的方法。onMeaSure()、onLayout()、onDraw()我们就是通过重写这三个方法来实现自定义控件的。我们先看第一个onMeaSure()测量:测量我们自定义控件的宽高。onLayout()这个呢是摆放,也就是我们控件需要摆放的位置。最后一个onDraw()是绘制控件的方法。可能大家刚刚接触这个比较懵,那么,我们通过一个例子来给大家更加直接明了的深入一下。比如,我们买了一张床要摆到卧室里,那我们会怎么做呢?什么样的流程,什么步骤。那么我们肯定会测量一下房子的宽高,我们够买床的宽高,看看是否合适,肯定是不能买大于房子的床吧。所以,这一步尤为关键,也是我们自定义控件的第一步onMeaSure(指定该控件的宽高)。第二步,就是摆放问题了onLayout(摆放所有子VIew),我们买了自己心仪的床之后,那就会想我们把床和床头柜摆到哪里?哪里比较好这里就设计到一个摆放问题,我们具体怎么摆放,进行一个控件的摆放。第三步也到了我们最后一步,就是绘制步骤,也是我们自定义控件中尤为关键的一步onDrow(绘制自己的内容).
接下来我们上代码:
1.创建一个类,继承一个View。重写View中的构造方法,有一个参数,俩个参数,三个参数,四个参数。我们只需要重写前三个就够了,因为第四个构造方法可能会因为API版本问题而导致我们的代码报错。
2.定义方法:
   设置背景图片的方法、设置按钮背景图的方法、设置状态的方法。
   // 设置滑块的背景资源
public void setWyqBackgroundResource(int switchBackground) {
    wyqBackgroupBitmap = BitmapFactory.decodeResource(getResources(),
            switchBackground);
}

// 设置按钮的背景
public void setWyqButtonResource(int slideButton) {
    wyqButtonBitmap = BitmapFactory.decodeResource(getResources(),
            slideButton);
}

// 设置按钮状态
public void setWyqState(boolean wyqState) {
    this.wyqState = wyqState;
}

通过以上的方法,当我们在MianActivity中调用这些方法是时候,我们就可以把图片资源设置到自定义控件上。
3.初始化重写onMeasure()、onDraw()、方法。
绘制的第一步,那就是测量了,所以我们要在onMeasure方法中获取资源的宽高,也是我们自定义控件的宽高。
代码如下:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// 设置宽高
setMeasuredDimension(wyqBackgroupBitmap.getWidth(),
wyqBackgroupBitmap.getHeight());
}
绘制第二步,因为我们这里暂时还用不到onLayout,所以我们直接介绍如何使用onDraw(),当大家实现该方的法的时候,会发现paint这样的一个字样,这个呢就是我们绘制所使用的画笔。那么我们的画笔怎么来的?需要我们实例化一个Paint对象。然后在构造方法中都调用这个初始化Paint的方法。初始化画板的时候呢,我们可以设置颜色,设置非锯齿,设置画笔粗细等等,代码就不赘述了,我们看下面的。canvas.drawBitmap(wyqBackgroupBitmap, 0, 0, paint);
通过调用这个方法,实现我们在主页面中设置的图片
绘制滑块:
if (isTouchMode) {
// 根据用户当前触摸到的位置
float newLeft = currentX - wyqButtonBitmap.getWidth() / 2.0f;
int maxLeft = wyqBackgroupBitmap.getWidth()
- wyqButtonBitmap.getWidth();
// 解决滑动左右超出背景的
if (newLeft < 0) {
newLeft = 0;
} else if (newLeft > maxLeft) {
newLeft = maxLeft;
}
canvas.drawBitmap(wyqButtonBitmap, newLeft, 0, paint);

    } else {
        // 2.2:判断当前按钮的状态,如果是true的话,
        if (wyqState) {
            int newLeft = wyqBackgroupBitmap.getWidth()
                    - wyqButtonBitmap.getWidth();
            canvas.drawBitmap(wyqButtonBitmap, newLeft, 0, paint);
        } else {
            //绘制滑块的图片
            canvas.drawBitmap(wyqButtonBitmap, 0, 0, paint);
        }
    }

}

//2.3:实现用户的触摸事件
boolean isTouchMode = false;
private OnSwitchStateUpdateListener onSwitchStateUpdateListener;

// private OnSwitchStateUpdateListener onSwitchStateUpdateListener;
// 重写用户触摸事件

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        isTouchMode = true;
        currentX = event.getX();
        break;
    case MotionEvent.ACTION_MOVE:
        currentX = event.getX();
        break;
    case MotionEvent.ACTION_UP:
        isTouchMode = false;
        currentX = event.getX();
        float center = wyqBackgroupBitmap.getWidth() / 2.0f;
        boolean state = currentX > center;
        if (state != wyqState && onSwitchStateUpdateListener != null) {
            onSwitchStateUpdateListener.onStateUpdate(state);
        }
        wyqState = state;
        break;
    default:
        break;
    }
    invalidate();// 会引发onDraw被调用,里面的 遍历会重新生效,界面更新
    return true;// 消费了用户的触摸事件,才可以收到其他的事件
}

接口回调,实现点击事件
boolean isTouchMode = false;
private OnSwitchStateUpdateListener onSwitchStateUpdateListener;
public interface OnSwitchStateUpdateListener {
// 状态回调, 把当前状态传出去
void onStateUpdate(boolean state);
}

public void setOnSwitchStateUpdateListener(
        OnSwitchStateUpdateListener onSwitchStateUpdateListener) {
    this.onSwitchStateUpdateListener = onSwitchStateUpdateListener;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值