android 纯粹自定义控件 滑动开关

滑动开关:

测量:设置自己显示在屏幕上的宽高  onMeasure

布局:设置自己显示在屏幕上的位置(只有在自定义的viewGroup中才用到)  onLayout

绘制:控制显示在屏幕上的样子(自定义viewGroup时不需要这个) onDraw


view和viewGroup的区别

相同点:都需要进行测量

不同点:viewGroup主要控制子view如何摆放,所以必须实现onLayout

view没有子view,所以不需要onLayout方法,但是必须实现onDraw



第一:xml文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <heimatogglebutton.ncs.yeyy.togglebutton.view.ToggleButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/toggleButton"
        android:layout_centerInParent="true"/>
</RelativeLayout>


第二:自定义Button

package heimatogglebutton.ncs.yeyy.togglebutton.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by yeyy on 2016/4/12.
 */
public class ToggleButton extends View {

    private ToggleState toggleState = ToggleState.Open; //开关的状态
    private Bitmap slideBg;//滑动块图片
    private Bitmap switchBg;//背景图片
    private int currentX;//当前触摸点X坐标
    private boolean isSliding = false;//正在滑动的状态

    /**
     * 如果你的view需要在java代码中动态new出来,走的是这个构造方法
     *
     * @param context
     */
    public ToggleButton(Context context) {
        super(context);
    }

    /**
     * 如果你的view只是在布局文件中使用,只需要重写这个方法
     *
     * @param context
     * @param attrs
     */
    public ToggleButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    //    枚举
    public enum ToggleState {
        Open, Close;
    }

    /**
     * 设置滑动块的背景图片
     *
     * @param slideBackgroundResource
     */
    public void setSlideBackgroundResource(int slideBackgroundResource) {
        slideBg = BitmapFactory.decodeResource(getResources(), slideBackgroundResource);
    }

    /**
     * 设置滑动开关的背景图片
     *
     * @param switchBackgroundResource
     */
    public void setSwitchBackgroundResource(int switchBackgroundResource) {
        switchBg = BitmapFactory.decodeResource(getResources(), switchBackgroundResource);

    }

    /**
     * 设置开关的状态
     *
     * @param state
     */
    public void setToggleState(ToggleState state) {
        toggleState = state;

    }

    /**
     * 设置当前控件在屏幕上显示的宽高
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(switchBg.getWidth(), switchBg.getHeight());
    }

    /**
     * 绘制自己显示在屏幕是的样子
     *
     * @param canvas
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//        绘制背景图片
//        left 第二个参数 图片的左边的x坐标
//        top 第三个参数 图片顶部的y坐标
        canvas.drawBitmap(switchBg, 0, 0, null);

        //        绘制滑动块的图片
//        滑动中的逻辑
        if (isSliding) {//如果正在滑动
//            限制滑动块左右滑动的边界
            int left = currentX - slideBg.getWidth() / 2;
            if (left < 0) left = 0;
            if (left > (switchBg.getWidth() - slideBg.getWidth())) {
//                设置右边的滑动界限
                left = switchBg.getWidth() - slideBg.getWidth();
            }
            canvas.drawBitmap(slideBg, left, 0, null);
        } else {//没有滑动的时候
//            此时抬起,根据state去绘制滑动块的位置
            if (toggleState == ToggleState.Open) {
                canvas.drawBitmap(slideBg, switchBg.getWidth() - slideBg.getWidth(), 0, null);
            } else {
                canvas.drawBitmap(slideBg, 0, 0, null);
            }
        }


    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        currentX = (int) event.getX();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                isSliding = true;
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                isSliding = false;
//                背景图片宽的一半
                int centerX = switchBg.getWidth() / 2;
//                判断当滑动块滑动的时候在左边右边滑动的位置来判断显示当前是开还是关
                if (currentX > centerX) {
//                    open 当点击一下但是没有滑动,比如已经滑动到开启,然后又原地点击了滑动块一次显示关闭了,需要判断
                    if (toggleState!=ToggleState.Open){//当原地点击了但是状态没有改变,不是open时
                        toggleState = ToggleState.Open;//仍然设置为open
                        if (listener!=null){
//                            调用接口
                            listener.onToggleStateChange(toggleState);
                        }
                    }
                } else {
//                    close
                    if (toggleState!=ToggleState.Close){//当原地点击了但是状态没有改变,不是close时
                        toggleState = ToggleState.Close;
                        if (listener!=null){
                            listener.onToggleStateChange(toggleState);
                        }
                    }
                }

                break;

        }
        invalidate();//当你需要调用onDraw方法的时候,就需要invalidate(),来进行重绘,不要直接调用onDraw方法
        return true;
    }

    private OnToggleStateChangeListener listener;
    public void setOnToggleStateChangeListener(OnToggleStateChangeListener listener){
        this.listener=listener;
    }
    public interface OnToggleStateChangeListener{
        void onToggleStateChange(ToggleState state);
    }
}


第三:mainActivity

package heimatogglebutton.ncs.yeyy.togglebutton;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

import heimatogglebutton.ncs.yeyy.togglebutton.view.ToggleButton;

public class MainActivity extends Activity {

    private ToggleButton toggleBut;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toggleBut = (ToggleButton) findViewById(R.id.toggleButton);
//        滑动块的背景图片
        toggleBut.setSlideBackgroundResource(R.drawable.switch_background);

//        设置滑动开关的背景图片
        toggleBut.setSwitchBackgroundResource(R.drawable.slide_button_background);

//        设置开关的状态
        toggleBut.setToggleState(ToggleButton.ToggleState.Open);

        toggleBut.setOnToggleStateChangeListener(new ToggleButton.OnToggleStateChangeListener() {
            @Override
            public void onToggleStateChange(ToggleButton.ToggleState state) {
                Toast.makeText(MainActivity.this,
                        state== ToggleButton.ToggleState.Close.Open?"开启":"关闭",
                        Toast.LENGTH_LONG).show();
            }
        });
    }
}

注意:

滑动块的滑动位置如何取坐标




源码地址:http://download.csdn.net/detail/csdnyuandaimaxuexi/9489948









  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值