您的位置:首页 > 其它

自定义滑动开关

2016-08-16 23:02 183 查看
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);

                

                

            }

        });

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: