第一接触公司项目就让我画页面,而且还涉及到我最讨厌的自定义view  但是没办法,讨厌也必须要做啊,经过百度上资源的查找,终于写出了一个滑动控件。废话不多说,上代码。

package com.etong.cpms.widget;

import com.etong.cpms.activity.R;

import android.content.Context;  
import android.graphics.Bitmap;  
import android.graphics.BitmapFactory;  
import android.graphics.Canvas;  
import android.graphics.Color;
import android.graphics.Matrix;  
import android.graphics.Paint;  
import android.util.AttributeSet;  
import android.view.MotionEvent;  
import android.view.View;  
import android.view.View.OnTouchListener;

public class WiperSwitch extends View implements OnTouchListener{  
    private Bitmap bg_on, bg_off, slipper_btn;  
    private String mOnText = "打开";
    private String mOffText = "关闭";
    /**
     * 按下时的x和当前的x
     */  
    private float downX, nowX;  
      
    /**
     * 记录用户是否在滑动
     */  
    private boolean onSlip = false;  
      
    /**
     * 当前的状态
     */  
    private boolean nowStatus = false;  
      
    /**
     * 监听接口
     */  
    private OnChangedListener listener;  
      
      
    public WiperSwitch(Context context) {  
        super(context);  
        init();  
    }  
 
    public WiperSwitch(Context context, AttributeSet attrs) {  
        super(context, attrs);  
        init();  
    }  
      
    public void init(){  
        //载入图片资源  
        bg_on = BitmapFactory.decodeResource(getResources(), R.drawable.switch_bkg_switch1);  
        bg_off = BitmapFactory.decodeResource(getResources(), R.drawable.switch_bkg_switch1);  
        slipper_btn = BitmapFactory.decodeResource(getResources(), R.drawable.switch_btn_slip1);  
        setOnTouchListener(this);  
    }  
      
    protected void onDraw(Canvas canvas) {  
        super.onDraw(canvas);  
        Matrix matrix = new Matrix();  
        Paint paint = new Paint();  
        float x = 0;  
          
        //根据nowX设置背景,开或者关状态  
        if (nowX < (bg_on.getWidth()/2)){  
              canvas.drawBitmap(bg_off, matrix, paint);//画出关闭时的背景
              paint.setColor(Color.WHITE);
              paint.setFakeBoldText(true);
              paint.setTextSize(40);
              canvas.drawText(mOffText, (bg_off.getWidth()-slipper_btn.getWidth())/2, (bg_off.getHeight()+30)/2, paint);
        }else{  
            canvas.drawBitmap(bg_on, matrix, paint);//画出打开时的背景   
            canvas.drawBitmap(bg_on, matrix, paint);//画出打开时的背景   
            paint.setColor(Color.WHITE);
            paint.setFakeBoldText(true);
            paint.setTextSize(40);
            canvas.drawText(mOnText,(bg_on.getWidth()-slipper_btn.getWidth())/2, (bg_on.getHeight()+30)/2, paint);
        }  
          
        if (onSlip) {//是否是在滑动状态,    
            if(nowX >= bg_on.getWidth())//是否划出指定范围,不能让滑块跑到外头,必须做这个判断  
                x = bg_on.getWidth() - slipper_btn.getWidth()/2;//减去滑块1/2的长度  
            else  
                x = nowX - slipper_btn.getWidth()/2;  
        }else {  
            if(nowStatus){//根据当前的状态设置滑块的x值  
                x = bg_on.getWidth() - slipper_btn.getWidth();  
            }else{  
                x = 0;  
            }  
        }  
          
        //对滑块滑动进行异常处理,不能让滑块出界  
        if (x < 0 ){  
            x = 0;  
        }  
        else if(x > bg_on.getWidth() - slipper_btn.getWidth()){  
            x = bg_on.getWidth() - slipper_btn.getWidth();  
        }  
          
        //画出滑块  
        canvas.drawBitmap(slipper_btn, x , 0, paint);   
    }  
 
    @Override  
    public boolean onTouch(View v, MotionEvent event) {  
        switch(event.getAction()){  
        case MotionEvent.ACTION_DOWN:{  
            if (event.getX() > bg_off.getWidth() || event.getY() > bg_off.getHeight()){  
                return false;  
            }else{  
                onSlip = true;  
                downX = event.getX();  
                nowX = downX;  
            }  
            break;  
        }  
        case MotionEvent.ACTION_MOVE:{  
            nowX = event.getX();  
            break;  
        }  
        case MotionEvent.ACTION_UP:{  
            onSlip = false;  
            if(event.getX() >= (bg_on.getWidth()/2)){  
                nowStatus = true;  
                nowX = bg_on.getWidth() - slipper_btn.getWidth();  
            }else{  
                nowStatus = false;  
                nowX = 0;  
            }  
              
            if(listener != null){  
                listener.OnChanged(WiperSwitch.this, nowStatus);  
            }  
            break;  
        }  
        }  
        //刷新界面  
        invalidate();  
        return true;  
    }  
      
      
      
    /**
     * 为WiperSwitch设置一个监听,供外部调用的方法
     * @param listener
     */  
    public void setOnChangedListener(OnChangedListener listener){  
        this.listener = listener;  
    }  
      
    /**
     * 设置滑动开关的初始状态,供外部调用
     * @param checked
     */  
    public void setChecked(boolean checked){  
        if(checked){  
            nowX = bg_off.getWidth();  
        }else{  
            nowX = 0;
        }  
        nowStatus = checked;  
    }  
    /**
     * 回调接口
     * @author len
     *
     */  
    public interface OnChangedListener {  
        public void OnChanged(WiperSwitch wiperSwitch, boolean checkState);  
    }  
 
 
}

android 自定义滑动按钮的更多相关文章

  1. Android 自定义Button按钮显示样式(正常、按下、获取焦点)

    现在的用户对APP的外观看得很重要,如果APP内所有元件都用Android默认样式写,估计下面评论里就有一堆在骂UI丑的.今天学习自定义Button按钮样式.Button样式修改的是Button的背景 ...

  2. Android自定义滑动显示隐藏布局

    方式一:上下左右滑动显示隐藏布局 总结代码地址: http://git.oschina.net/anan9303/customView参考例子: http://www.jianshu.com/p/fc ...

  3. Android自定义Button按钮显示样式

    关于listview和button都要改变android原来控件的背景,在网上查找了一些资料不是很全,所以现在总结一下android的selector的用法. 首先android的selector是在 ...

  4. android 自定义adapter和线程结合 + ListView中按钮滑动后状态丢失解决办法

    adapter+线程 1.很多时候自定义adapter的数据都是来源于服务器的,所以在获取服务器的时候就需要异步获取,这里就需要开线程了(线程池)去获取服务器的数据了.但这样有的时候adapter的中 ...

  5. Android自定义Seekbar滑动条,Pop提示跟随滑动按钮一起滑动

    由于项目需要做出此效果,自定义写了一个. 效果图 思路: 原始的seekbar只有滑动条并没有下方的提示文字,所以我们必须要继承Seekbar重写这个控件. 代码: 在values文件夹下新建attr ...

  6. android自定义控件(3)-自定义当前按钮属性

    那么还是针对我们之前写的自定义控件:开关按钮为例来说,在之前的基础上,我们来看看有哪些属性是可以自定义的:按钮的背景图片,按钮的滑块图片,和按钮的状态(是开还是关),实际上都应该是可以在xml文件中直 ...

  7. iOS 自定义返回按钮,保留系统滑动返回

    原文链接 自定义返回按钮保留系统滑动返回手势.gif 1.简介 使用苹果手机,最喜欢的就是用它的滑动返回.作为一个开发者,我们在编写很多页面的时候,总是会因为这样那样的原因使得系统的滑动返回不可用.使 ...

  8. Android 自定义ScrollView ListView 体验各种纵向滑动的需求

      分类: [android 进阶之路]2014-08-31 12:59 6190人阅读 评论(10) 收藏 举报 Android自定义ScrollView纵向拖动     转载请标明出处:http: ...

  9. android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检索

    我们的手机通讯录一般都有这样的效果,如下图: OK,这种效果大家都见得多了,基本上所有的android手机通讯录都有这样的效果.那我们今天就来看看这个效果该怎么实现. 一.概述 1.页面功能分析 整体 ...

随机推荐

  1. 01_Quartz基础结构

    [各种任务调度的使用场景] 论坛每天凌晨统计论坛用户的积分排名. 论坛每半个小时生成精华文章. 每隔30分钟对锁定过期的用户解锁. 每月1号统计上个月各部门的业务数据. [Quartz 简介] Qua ...

  2. sql server性能分析--执行sql次数和逻辑次数

    目前在做一个项目优化时,想通过数据库层分析sql server系统性能,查了一下网上代码,修改了一下标题和DMVs代码,以下代码可以用来分析系统运行一段时间后,那些语句是系统忙的sql语句.做为参考. ...

  3. 把IDENTITY_INSERT 设置为 ON ,还不能插入数据问题

    IDENTITY_INSERT 为 ON 时 , 必须把需要插入的列名列出来 不然报错 正确例子: SET IDENTITY_INSERT  table(表名) ONinsert into table ...

  4. visual studio 调试 不进断点 断点失效 提示当前不会命中该断点等问题解决

    1.首先看一下  当前调试模式是否为debug 2. 点击[调试]>[选项和设置] 将[要求源文件与原始文件完全匹配]勾选掉 3.点击调试的最后一个选项 点击[web] 将调试器内部勾选上需要测 ...

  5. 记录项目代码迁移后,UI测试框架的搭建(配置文件的修改、测试脚本试运行)

    前文:记录一次项目代码迁移过程 上文代码迁移的目的就是为了新增vue脚手架自带的UI测试框架,工具有了,就需要实践运行在项目中了(修改配置文件.编写测试脚本等). 一.单元测试 测试框架 karma ...

  6. 再学UML-深入浅出UML类图(五)

    实例分析3——售票机控制程序 某运输公司决定为新的售票机开发车票销售的控制软件.图I给出了售票机的面板示意图以及相关的控制部件. 图I   售票机面板示意图 售票机相关部件的作用如下所述: (1) 目 ...

  7. Windows平台,Oracle Database和Client并存方式

    由于某些特定需求,生产环境需要在同一台机器上同时安装Database Server和Client,因为plsql没有64位客户端,无法读取64位database的oci.dll文件,所以需要一个32位 ...

  8. 站在巨人肩膀上的牛顿:Kubernetes和SAP Kyma

    这周Jerry在SAP上海研究院参加了一个为期4天的Kubernetes培训,度过了忙碌而又充实的4天.Jason,Benny和Peng三位大神的培训干货满满,借此机会,Jerry和过去的两位老领导P ...

  9. Android(java)学习笔记15:匿名内部类实现多线程

    1. 使用匿名内部类实现多线程 二话不说,首先利用代码体现出来,给大家直观的感觉: package cn.itcast_11; /* 4 * 匿名内部类的格式: 5 * new 类名或者接口名() { ...

  10. ShellSort uva

    ShellSort He made each turtle stand on another one's back And he piled them all up in a nine-turtle ...