自定义一个可以随着手指拖动的按钮

效果图:

       关状态                              中间拖动                   开开关

素材图片

关状态的背景图

开状态的背景图

拖动的按钮


下面就直接来看看代码吧:


一、自定义的一个控件:




一、自定义的一个控件:


package com.zhong.newswitch.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.zhong.newswitch.R;

public class SlideSwitch extends View {

    private Bitmap imgOn;
    private Bitmap imgOff;
    private Bitmap imgBtn;
    private float countX;
    private int viewWidth;
    private int viewHeight;
    private OnSwitchStateChangListener listener;
    private boolean switchState;
    private boolean lastStaete;
   //设置一个事件监听的方法
    public void setOnSwitchStateChangListener(OnSwitchStateChangListener listener) {
        this.listener = listener;
    }

    public SlideSwitch(Context context) {
        super(context);
        init(context, null, 0);
    }

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

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

    private void init(Context context, AttributeSet attrs, int defStyle) {
        //获取“开”的背景图片的BitMap对象
        imgOn = BitmapFactory.decodeResource(getResources(), R.drawable.slide_bg_on);
        //获取“关”的背景图片的BitMap对象
        imgOff = BitmapFactory.decodeResource(getResources(), R.drawable.slide_bg_off);
        //获取“按钮”的背景图片的BitMap对象
        imgBtn = BitmapFactory.decodeResource(getResources(), R.drawable.slide_btn);
        if (attrs!=null){
            //获取到自定义的xml中的已经声明的属性     此处要使用自定义的xml中的name
            TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.slide);
            //获取自定义的第一项的属性,获取属性值当找不到时返回默认值,
            boolean state = arr.getBoolean(0, false);
            //释放资源
            arr.recycle();
            //直接调用设置初始的状态
            setSwitchState(state);
        }

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //获取背景图片的高作为控件的高
        viewWidth = imgOff.getWidth();
        viewHeight = imgOff.getHeight();
        //设置控件的宽高
        setMeasuredDimension(viewWidth, viewHeight);


    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (countX < imgBtn.getWidth() / 2) {
            //判断不能移出外面
            countX = imgBtn.getWidth() / 2;
        }
        if (countX > (imgOff.getWidth() - imgBtn.getWidth() / 2)) {
            countX = imgOff.getWidth() - imgBtn.getWidth() / 2;
        }
        //当移动过了中间线左边时图片为关,在右边背景改为开的图片
        if (countX < imgOff.getWidth() / 2) {
            canvas.drawBitmap(imgOff, 0, 0, null);
        } else {
            canvas.drawBitmap(imgOn, 0, 0, null);
        }

        //绘制小按钮
        canvas.drawBitmap(imgBtn, countX - imgBtn.getWidth() / 2 - 2, 0, null);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        countX = event.getX();
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_UP:
                //当手离开地没有在边上,判断后直接跳到边去
                if (countX < viewWidth / 2) {
                    countX = imgBtn.getWidth() / 2;
                    switchState = false;
                } else {
                    countX = imgOff.getWidth() - imgBtn.getWidth() / 2;
                    switchState = true;
                }
                //判断是否有监听如果没有设置监听不调用,判断现在的状态原先的状态是否一样,如果一样不调用
                if (listener != null&&lastStaete!=switchState) {
                    listener.OnSwitchStateChang(switchState);
                }
                lastStaete = switchState;

                break;
            case MotionEvent.ACTION_DOWN:

                break;
            case MotionEvent.ACTION_MOVE:

                break;

        }

        invalidate();
        return true;
    }
   //添加一个可以设置选中状态的方法
    public void setSwitchState(boolean state) {
        lastStaete=state;
        if (state){
            countX = imgOff.getWidth() - imgBtn.getWidth() / 2;
        }else{
            countX = imgBtn.getWidth() / 2;

        }

    }

    //添加一个开关事件的监听接口
    public interface OnSwitchStateChangListener {
        void OnSwitchStateChang(boolean state);
    }
}



二、自定义一个第一在xml中用的属性

在res目录下键 res-values-slft_attrs.xml

<span style="color:#000000;"><?xml version="1.0" encoding="utf-8"?>
<!--自定义控件的属性-->
<resources>
    <!--声明属性name必须有-->
    <declare-styleable name="slide">
        <!--name="state"属性名,format="boolean"属性类型-->
        <attr name="state" format="boolean"></attr>
    </declare-styleable>
</resources></span>

三、main.xml中的代码

<span style="color:#000000;"><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:my="http://schemas.android.com/apk/res/com.zhong.newswitch"

              android:orientation="vertical"
              android:background="#FFF"
                android:gravity="center"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
        >
    <!--com.zhong.newswitch为应用的包名-->

    <com.zhong.newswitch.view.SlideSwitch
            my:state="true"
            android:id="@+id/switch_main"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
</RelativeLayout></span>


四 、MainActivity中的代码

<span style="color:#000000;">package com.zhong.newswitch;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import com.zhong.newswitch.view.SlideSwitch;

public class MainActivity extends Activity {
    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        SlideSwitch slideSwitch= (SlideSwitch) findViewById(R.id.switch_main);
        //设置初始的状态
        slideSwitch.setSwitchState(true);
       //监听状态
        slideSwitch.setOnSwitchStateChangListener(new SlideSwitch.OnSwitchStateChangListener() {
            @Override
            public void OnSwitchStateChang(boolean state) {
                Toast.makeText(MainActivity.this, state+"",Toast.LENGTH_SHORT).show();
            }
        });

    }
}</span>

ok了






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值