博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义控件:滑动开关按钮
阅读量:6233 次
发布时间:2019-06-22

本文共 6025 字,大约阅读时间需要 20 分钟。

 

1 
6 7
13 14
1 package com.example.testdemo;  2   3 import android.content.Context;  4 import android.graphics.Bitmap;  5 import android.graphics.BitmapFactory;  6 import android.graphics.Canvas;  7 import android.graphics.Paint;  8 import android.util.AttributeSet;  9 import android.view.MotionEvent; 10 import android.view.View; 11 import android.view.View.OnClickListener; 12  13 public class MyToggleButton extends View implements OnClickListener { 14  15     // 做为背景的图片 16     private Bitmap backgroundBitmap; 17     // 可以滑动的图片 18     private Bitmap slideBtn; 19     private Paint paint; 20     // 滑动按钮的左边届 21     private float slideBtn_left; 22     // down 事件时的x值 23     private int firstX; 24     // touch 事件的上一个x值 25     private int lastX; 26     // 当前开关的状态 true 为开 27     private boolean currState = false; 28     // 判断是否发生拖动, 如果拖动了,就不再响应 onclick 事件 29     private boolean isDrag = false; 30  31     /** 32      * 在代码里面创建对象的时候,使用此构造方法 33      */ 34     public MyToggleButton(Context context) { 35         super(context); 36         // TODO Auto-generated constructor stub 37     } 38  39     /** 40      * 在布局文件中声名的view,创建时由系统自动调用。 41      *  42      * @param context 43      *            上下文对象 44      * @param attrs 45      *            属性集 46      */ 47     public MyToggleButton(Context context, AttributeSet attrs) { 48         super(context, attrs); 49  50         initView(); 51     } 52  53     /** 54      * 初始化 55      */ 56     private void initView() { 57  58         // 初始化图片 59         backgroundBitmap = BitmapFactory.decodeResource(getResources(), 60                 R.drawable.switch_background); 61         slideBtn = BitmapFactory.decodeResource(getResources(), 62                 R.drawable.slide_button); 63  64         // 初始化 画笔 65         paint = new Paint(); 66         paint.setAntiAlias(true); // 打开抗矩齿 67  68         // 添加onclick事件监听 69         setOnClickListener(this); 70     } 71  72     /* 73      * view 对象显示的屏幕上,有几个重要步骤:  74      * 1、构造方法 创建 对象。  75      * 2、测量view的大小。 onMeasure(int,int); 76      * 3、确定view的位置 ,view自身有一些建议权,决定权在 父view手中。 onLayout();  77      * 4、绘制 view 的内容 。 78      * onDraw(Canvas) 79      */ 80  81     @Override 82     /** 83      * 测量尺寸时的回调方法  84      */ 85     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 86         // super.onMeasure(widthMeasureSpec, heightMeasureSpec); 87         // 设置当前view的大小 width :view的宽度 height :view的高度 (单位:像素) 88         setMeasuredDimension(backgroundBitmap.getWidth(), 89                 backgroundBitmap.getHeight()); 90     } 91  92     // 确定位置的时候调用此方法 93     // 自定义view的时候,作用不大 94     // @Override 95     // protected void onLayout(boolean changed, int left, int top, int right, 96     // int bottom) { 97     // super.onLayout(changed, left, top, right, bottom); 98     // } 99 100     @Override101     /**102      * 绘制当前view的内容103      */104     protected void onDraw(Canvas canvas) {105         // super.onDraw(canvas);106 107         // 绘制 背景108         /*109          * backgroundBitmap 要绘制的图片 left 图片的左边届 top 图片的上边届 paint 绘制图片要使用的画笔110          */111         canvas.drawBitmap(backgroundBitmap, 0, 0, paint);112 113         // 绘制 可滑动的按钮114         canvas.drawBitmap(slideBtn, slideBtn_left, 0, paint);115     }116 117 118     @Override119     /**120      * onclick 事件在View.onTouchEvent 中被解析。121      * 系统对onclick 事件的解析,过于简陋,只要有down 事件  up 事件,122      * 系统即认为 发生了click 事件123      */124     public void onClick(View v) {125         // 如果没有拖动,才执行改变状态的动作126         if (!isDrag) {127             currState = !currState;128             flushState();129         }130     }131 132     @Override133     public boolean onTouchEvent(MotionEvent event) {134         super.onTouchEvent(event);135 136         switch (event.getAction()) {137         case MotionEvent.ACTION_DOWN:138             firstX = lastX = (int) event.getX();139             isDrag = false;140 141             break;142         case MotionEvent.ACTION_MOVE:143 144             // 判断是否发生拖动145             if (Math.abs(event.getX() - firstX) > 5) {146                 isDrag = true;147             }148 149             // 计算 手指在屏幕上移动的距离150             int dis = (int) (event.getX() - lastX);151 152             // 将本次的位置 设置给lastX153             lastX = (int) event.getX();154 155             // 根据手指移动的距离,改变slideBtn_left 的值156             slideBtn_left = slideBtn_left + dis;157             break;158         case MotionEvent.ACTION_UP:160             // 在发生拖动的情况下,根据最后的位置,判断当前开关的状态161             if (isDrag) {162                 // alideBtn 左边界最大值163                 int maxLeft = backgroundBitmap.getWidth() - slideBtn.getWidth();165                 /*166                  * 根据 slideBtn_left 判断,当前应是什么状态167                  */168                 if (slideBtn_left > maxLeft / 2) { // 此时应为 打开的状态169                     currState = true;170                 } else {171                     currState = false;172                 }174                 flushState();175             }176             break;177         }179         flushView();181         return true;182     }183 184     /**185      * 刷新当前状态186      */187     private void flushState() {188         if (currState) {189             slideBtn_left = backgroundBitmap.getWidth() - slideBtn.getWidth();190         } else {191             slideBtn_left = 0;192         }194         flushView();195     }196 197     /**198      * 刷新当前视力199      */200     private void flushView() {201         /*202          * 对 slideBtn_left 的值进行判断 ,确保其在合理的位置 即 0<=slideBtn_left <= maxLeft203          */205         int maxLeft = backgroundBitmap.getWidth() - slideBtn.getWidth(); 207 208         // 确保 slideBtn_left >= 0209         slideBtn_left = (slideBtn_left > 0) ? slideBtn_left : 0;210 211         // 确保 slideBtn_left <=maxLeft212         slideBtn_left = (slideBtn_left < maxLeft) ? slideBtn_left : maxLeft;213 214         /*215          * 刷新当前视图 导致 执行onDraw执行216          */217         invalidate();218     }219 220 }

 DEMO下载地址:http://pan.baidu.com/s/1qWjXEhQ

转载地址:http://xwhna.baihongyu.com/

你可能感兴趣的文章
小心 php fpm 的超时
查看>>
error LNK2001: 无法解析的外部符号 __CrtDbgReport
查看>>
2013年Android 学习计划
查看>>
按值传递和按引用传递
查看>>
捕获按钮点击事件
查看>>
认真,是成功的重要因素
查看>>
第3章 概述
查看>>
一张图看懂 Hadoop RPC 机制
查看>>
微信小程序picker和range-key的用法
查看>>
valgrind +gdb 调试
查看>>
USACO2.3 Money Systems(money)
查看>>
css3各浏览器圆角
查看>>
android 事件分发机制
查看>>
将语法从词法解析器中分离出来
查看>>
SpringBoot基础篇AOP之基本使用姿势小结
查看>>
Android中AsyncTask的简单用法
查看>>
Android 获取dimen值
查看>>
Camel In Action 读书笔记 (9)
查看>>
Gallery实现首页图片滑动源码
查看>>
ehlib 修改 使指示区背景色 和 数据区 背景色一致
查看>>