自定义滑动开关

1.布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:health="http://schemas.android.com/apk/res/com.health.myswitch"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   
    android:orientation="vertical" >

    <com.health.myswitch.MySwith
        android:id="@+id/MySwith"       
        android:layout_centerInParent="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
         health:isOpen = "false"
         health:slideSrc = "@drawable/ic_launcher"
         />

</RelativeLayout>


2.写一个类继承 MySwith extends View

package com.health.myswitch;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MySwith extends View {

    private int bitmapHeight;
    private Bitmap bitmap;
    private Paint paint;

    private int bitmapWidth; // 开关的
    private Bitmap slideBitmap; // 滑块的宽度
    private int mMaxLeft; // 距离左边的最大距离 即为右滑的最大距离

    private int mCurrentLeft; // 距离左边的当前距离

    private boolean isOpen;
    private boolean isClick ;
    private float totaldx;
    
    private static final String namespace ="http://schemas.android.com/apk/res/com.health.myswitch";

    public MySwith(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initData();
        // 两种方式
        
         isOpen = attrs.getAttributeBooleanValue(namespace, "isOpen", false);
        slideSrc = attrs.getAttributeResourceValue(namespace, "slideSrc", 0);        
        System.out.println("isOpen=" + isOpen + ",slideSrc=" + slideSrc);
    }

    // 在布局文件中使用MySwitch,在系统加载布局文件的时候,会调用此方法生成一个MySwitch的对象
    // Attribute : 属性,特性
    public MySwith(Context context, AttributeSet attrs) {
        this(context, attrs, -1);

    }

    // 直接在java代码中new出这个控件的时候,会使用
    public MySwith(Context context) {
        this(context, null);

    }

    private void initData() {
        // 画笔
        paint = new Paint();
        // 将画笔的颜色设置为红色
        paint.setColor(Color.BLUE);
        // 初始化图片 decode : 翻译
        bitmap = BitmapFactory.decodeResource(getResources(),           //slideSrc);
                R.drawable.switch_background);

        bitmapWidth = bitmap.getWidth();
        bitmapHeight = bitmap.getHeight();

        slideBitmap = BitmapFactory.decodeResource(getResources(),
                R.drawable.slide_button);

        int slideBitmapWidth = slideBitmap.getWidth();
        // 滑块可以向右滑动的最大距离
        mMaxLeft = bitmapWidth - slideBitmapWidth;

        setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                if (isClick) {
                    System.out.println("MySwitch.onClick"+isClick);
                    if (isOpen) {
                        // 关闭
                        mCurrentLeft = 0;
                        isOpen = false;
                    } else {
                        // 打开
                        mCurrentLeft = mMaxLeft;
                        isOpen = true;
                    }

                // 刷新界面 促发onDraw方法的调用
                invalidate();
                // 接受 观察者的通知
                notifyStatus();

                    
                }

                
            }
        });

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 背景图片有多大,控件就有多大
        setMeasuredDimension(bitmapWidth, bitmapHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 绘制开关图片
        canvas.drawBitmap(bitmap, 0, 0, paint);
        // 绘制滑块的图片
        canvas.drawBitmap(slideBitmap, mCurrentLeft, 0, paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();

        switch (action) {
        case MotionEvent.ACTION_DOWN:
            
            startX = event.getX();
            totaldx = 0;
            break;

        case MotionEvent.ACTION_MOVE:

            float moveX = event.getX();
            float dx = moveX - startX;

            totaldx = totaldx + Math.abs(dx);
            mCurrentLeft = (int) (mCurrentLeft + dx);

            if (mCurrentLeft < 0) {
                mCurrentLeft = 0;
            } else if (mCurrentLeft > mMaxLeft) {
                mCurrentLeft = mMaxLeft;
            }

            invalidate(); // 刷新界面 必须刷新,否则没有效果
            startX = moveX;
            break;

        case MotionEvent.ACTION_UP:

            if (totaldx > 3) {
                isClick = false;
            } else {
                isClick = true;
            }

            if (!isClick) {

                if (mCurrentLeft > mMaxLeft / 2) {
                    // 自动打开
                    mCurrentLeft = mMaxLeft;
                    isOpen = true;
                } else {
                    mCurrentLeft = 0;
                    isOpen = false;
                }

                invalidate();
                notifyStatus();

            }

            break;

        }

        return super.onTouchEvent(event);// 消耗掉事件;
    }

    // 观察者模式 五步
    // 1. 找到被观察者 Myswith
    // 2.定义观察者,(定义接口)
    public interface OnStatusChangeLister {
        public void OnStatusChange(Boolean isOpen);
    }

    // 3.在被观察者中 保存观察者的对象
    private OnStatusChangeLister mLister;
    private float startX;
    private int slideSrc;

    public void setOnStatusChangeLister(OnStatusChangeLister Lister) {
        this.mLister = Lister;
    }

    // 4.通知观察者
    public void notifyStatus() {
        if (mLister != null) {
            mLister.OnStatusChange(isOpen);
            // System.out.println("开关的状态为:" + isOpen);
        }
    }

}

3.在MainActivity中引入

package com.health.myswitch;

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

import com.health.myswitch.MySwith.OnStatusChangeLister;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        MySwith mySwith = (MySwith) findViewById(R.id.MySwith);
        
        //设置背景  滑动开关
        mySwith.setBackgroundResource(R.drawable.switch_background);
        //设置开关默认状态
    

        
        mySwith.setOnStatusChangeLister(new OnStatusChangeLister() {
            
            @Override
            public void OnStatusChange(Boolean isOpen) {
                
                //  按压状态 的变化          监听不了触摸的状态
                Toast.makeText(MainActivity.this, "开关的状态为:"+isOpen, 0).show();
                
                //System.out.println("开关的状态为:"+isOpen);
                
                
            }
        });
    }

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值