您的位置:首页 > 移动开发 > Android开发

android 自定义切换按钮

2016-04-01 14:00 302 查看
import java.util.Timer;

import java.util.TimerTask;

import android.app.Activity;

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.graphics.Paint.FontMetrics;

import android.graphics.Shader;

import android.os.Handler;

import android.support.v4.util.TimeUtils;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.View;

import android.view.View.OnClickListener;

public class MyToggleBtn2 extends View implements OnClickListener{

    

    /**

     * 最小高度

     */

    private float miniHeight;

    /**

     * 最小宽度

     */

    private float miniWidth;

    private Paint paint;

    /**

     * 选择开关左侧的文字信息

     */

    private static final String showTextLeft = "直播";

    /**

     * 选择开关右侧的文字信息

     */

    private static final String showTextRight = "分析师";

    //默认显示右侧

    private String showText ;

    /**

     * 在布局文件中声明该控件时,调用此方法

     * @param context

     * @param attrs

     */

    public MyToggleBtn2(Context context, AttributeSet attrs) {

        super(context, attrs);

        

        init(context);

    }

    private Context ctx;

    /**

     *  初始化

     */

    private void init(Context context) {

        ctx = context;

        showText = showTextRight;

        

        paint = new Paint();

        paint.setAntiAlias(true);// 抗矩齿

        paint.setTextSize(sp2px(context,14));

        FontMetrics fontMetrics = paint.getFontMetrics();

        miniHeight = fontMetrics.bottom - fontMetrics.top+getPaddingTop()+getBottom()+sp2px(context,10);

        float textWidth =0;

        if(showTextLeft.length()>showTextRight.length()){

            textWidth = paint.measureText(showTextLeft);

        }else{

            textWidth = paint.measureText(showTextRight);

        }

        paint.measureText(showTextLeft);

        paint.measureText(showTextRight);

        miniWidth = (float) (1.5*miniHeight+textWidth+getPaddingLeft()+getPaddingRight()+sp2px(context,10));

        //滑动图片,左边界的最大值

        slideLeftMax = (int) (miniWidth - miniHeight);

        paint.setColor(Color.WHITE);

        // 添加点击事件

        

        setOnClickListener(this);

        

    }

    /**

     * 设置为打开状态

     */

    public void setOpenChecked(){

        slideLeft = 0;

        flushView();

    }

    /**

     * 设置为关闭状态

     */

    public void setCloseChecked(){

        slideLeft = slideLeftMax;

        flushView();

    }

    /**

     * 当前的开关状态

     * true 为开

     * false 为关

     */

    private boolean currState = false;

    

    private int slideLeft = 0;

    

    @Override

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);

        // 绘制背景图

        //canvas.drawBitmap(bgBitmap, 0, 0, paint);

        paint.setStrokeWidth(1);

        paint.setStyle(paint.getStyle().FILL);

        

        paint.setColor(Color.GRAY);

        canvas.drawCircle((float)(miniHeight*0.5), (float)(miniHeight*0.5), (float)(miniHeight*0.5), paint);

        canvas.drawRect((float)(miniHeight*0.5), 0, (float)(slideLeft+miniHeight*0.5), miniHeight, paint);

        paint.setColor(Color.RED);

        canvas.drawRect((float)((float)(slideLeft+miniHeight*0.5)), 0, (float)(miniWidth-miniHeight*0.5), miniHeight, paint);

        canvas.drawCircle((float)(miniWidth-miniHeight*0.5+0.5), (float)(miniHeight*0.5), (float)(miniHeight*0.5), paint);

        float textWidth = paint.measureText(showText);

        

        FontMetrics fontMetrics = paint.getFontMetrics();

        float fontTotalHeight = fontMetrics.bottom - fontMetrics.top;

        

        float newY = getMeasuredHeight() / 2 - fontMetrics.descent+ (fontMetrics.descent - fontMetrics.ascent) / 2;

        float baseX = 0;

        paint.setColor(Color.WHITE);

        if(!currState){

            baseX = (float) ((getMeasuredWidth()-textWidth)-getPaddingRight()-miniHeight*0.5);

        }else{

            baseX = (float) (0+getPaddingLeft()+miniHeight*0.5);

        }

        //canvas.drawText(showText, baseX, newY, paint);

        

        // 绘制滑动图片

        //canvas.drawBitmap(slideBitmap, slideLeft, 0, paint);

        paint.setColor(Color.WHITE);

        canvas.drawCircle((float)(slideLeft+miniHeight*0.5+0.5), (float)(miniHeight*0.5), (float)(miniHeight*0.5+0.5), paint);

    }

    

    

    @Override

    /**

     * 指定view的大小

     */

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        //        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        

        // 当前view的宽度,就和背景图的大小一致

        int measuredWidth = (int) miniWidth;

        int measuredHeight = (int) miniHeight;

        

        //指定测量的宽高

        setMeasuredDimension(measuredWidth, measuredHeight);

    }

    Handler handler=new Handler();

    Runnable runnable=new Runnable() {

        @Override

        public void run() {

            // TODO Auto-generated method stub

            //要做的事情

            if(currState){

                if(slideLeft<slideLeftMax){

                    isScroll = true;

                    slideLeft+=20;

                    handler.postDelayed(this, 100);

                }else{

                        isScroll = false;

                }

            }else{

                if(slideLeft>0){

                    isScroll = true;

                    slideLeft-=15;

                    handler.postDelayed(this, 100);

                }else{

                        isScroll = false;

                }

            }

            ((Activity)(ctx)).runOnUiThread(new Runnable() {

                

                @Override

                public void run() {

                    // TODO Auto-generated method stub

                    if(currState){// 开状态

                        showText = showTextLeft;

                        if(onSwitchListener!=null){

                            onSwitchListener.OnRightClick();

                        }

                    }else{

                        showText = showTextRight;

                         if(onSwitchListener!=null){

                             onSwitchListener.OnLeftClick();

                         }

                    }

                    flushView();

                }

            });

        }

    };

    /**

     * 响应view的点击事件

     */

    private boolean isScroll = false;

    @Override

    public void onClick(View v) {

        // 如果发生了滑动的动作,就不执行以下代码

        if(isSliding){

            return ;

        }

        if(isScroll){

            return;

        }

        currState = !currState;

        //handler.postDelayed(runnable, 100);

        // 切换按钮的开关状态

        flushState();

    }

    /**

     * 刷新状态

     * 根据当前的状态,刷新页面

     */

    private void flushState() {

        if(currState){// 开状态

            showText = showTextLeft;

            slideLeft = slideLeftMax;

            

            if(onSwitchListener!=null){

                onSwitchListener.OnRightClick();

            }

        }else{

            showText = showTextRight;

            // 关状态

            slideLeft = 0;

             if(onSwitchListener!=null){

  
c242
              onSwitchListener.OnLeftClick();

             }

        }

        flushView();

    }

    

    /**

     * 上一个事件中的X坐标

     */

    private int lastX;

    /**

     * down事件中的X坐标

     */

    private int downX;

    private int slideLeftMax;

    

    /**

     * 判断触摸时,是否发生滑动事件

     */

    private boolean isSliding = false;

    

    @Override

    /**

     * 重写该方法,处理触摸事件

     * 如果该view消费了事件,那么,返回true

     */

    public boolean onTouchEvent(MotionEvent event) {

        // super 注释掉以后,onclick事件,就失效了,因为,点击这个动作,也是从onTouchEvent 方法中解析出来,符合一定的要求,就是一个点击事件

        // 系统中,如果发现,view产生了up事件,就认为,发生了onclick动作,就行执行listener.onClick方法

        super.onTouchEvent(event);

        /*

         * 点击切换开关,与触摸滑动切换开关,就会产生冲突

         * 我们自己规定,如果手指在屏幕上移动,超过15个象素,就按滑动来切换开关,同时禁用点击切换开关的动作

         */

        if(isScroll){

            return true;

        }

        switch (event.getAction()) {

        case MotionEvent.ACTION_DOWN:

            System.out.println("MotionEvent.ACTION_DOWN");

            

            downX = lastX = (int) event.getX(); // 获得相对于当前view的坐标

//            event.getRawX(); // 是相对于屏幕的坐标

            // down 事件发生时,肯定不是滑动的动作

            isSliding = false;

            break;

        case MotionEvent.ACTION_MOVE:

            System.out.println("MotionEvent.ACTION_MOVE");

            

            // 获得距离

            int disX = (int) (event.getX() - lastX);

            // 改变滑动图片的左边界

            slideLeft+=disX;

            flushView();

            

            // 为lastX重新赋值

            lastX = (int) event.getX();

            

            // 判断是否发生滑动事件

            if(Math.abs(event.getX()-downX)>15){ // 手指在屏幕上滑动的距离大于15象素

                isSliding = true;

            }

            

            break;

        case MotionEvent.ACTION_UP:

            System.out.println("MotionEvent.ACTION_UP");

            // 只有发生了滑动,才执行以下代码

            if (isSliding) {

                // 如果slideLeft > 最大值的一半 当前是开状态

                // 否则就是关的状态

                if (slideLeft > slideLeftMax / 2) { // 开状态

                    currState = true;

                } else {

                    currState = false;

                }

                flushState();

            }

            break;

        }

        return true;

    }

    /**

     * 刷新页面

     */

    private void flushView() {

        // 保证 slideLeft >=0  同时   <= slideLeftMax

        if(slideLeft<0){

            slideLeft = 0;

        }

        if(slideLeft>slideLeftMax){

            slideLeft = slideLeftMax;

        }

        invalidate();// 刷新页面

    }

    public float sp2px(Context ctx,float sp){

        return (float) (ctx.getResources().getDisplayMetrics().density*sp+0.5);

    }

    private IOnSwitchListener onSwitchListener;

    public interface IOnSwitchListener{

        public void OnLeftClick();

        public void OnRightClick();

    }

    public void setOnSwitchListener(IOnSwitchListener onSwitchListener){

        this.onSwitchListener = onSwitchListener;

    }
}

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