自定义ToggleButton
来源:互联网 发布:张无忌萧峰 知乎 编辑:程序博客网 时间:2024/06/16 22:36
很久之前就想写博客对自己的过去进行总结,由于个人比较懒这一原因而导致一直都未开始。现在鼓起勇气,克服这一懒惰心理开始写下第一篇博文。另外个人也是技术比较差,有什么写得不够好,不够详细的请各位同学多多指出,我将逐一改正。
好了,下面开始我们的自定义ToggleButton。那么我们先上图
首先ToggleButton这个view控件由一张可拖动,可点击的小圆点和背景图组成。
上代码: 那么我们开始代码实战,逐一解析
package com.example.togglebutton;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.View.OnClickListener;public class MyToggleButton extends View implements OnClickListener { // 背景图 private Bitmap backgroundBitmap; // 拖动的button private Bitmap slideBtn; private Paint paint; private float slideBtn_left; // slideBtn的状态 private boolean currState = false; // 是否为拖动状态 private boolean isDrag = false; public MyToggleButton(Context context) { super(context); } public MyToggleButton(Context context, AttributeSet attrs) { super(context, attrs); initView(); initData(); initListener(); } private void initView() { backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.radio_i); slideBtn = BitmapFactory.decodeResource(getResources(), R.drawable.radio_slider_big); } private void initData() { paint = new Paint(); paint.setAntiAlias(true); } private void initListener() { setOnClickListener(this); } @Override /** * 设置view的测量值 */ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(backgroundBitmap.getWidth(), backgroundBitmap.getHeight()); } @Override protected void onDraw(Canvas canvas) { // draw背景 canvas.drawBitmap(backgroundBitmap, 0, 0, paint); // draw拖动的按钮 canvas.drawBitmap(slideBtn, slideBtn_left, 2, paint); } @Override /** * 完整的一次down和up就是onclick事件 */ public void onClick(View v) { if (!isDrag) { currState = !currState; flushState(); } } private int firstX; private int lastX; @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: firstX = (int) event.getX(); isDrag = false; break; case MotionEvent.ACTION_MOVE: lastX = (int) event.getX(); int distance = (int) (lastX - firstX); if (Math.abs(distance) > 5) {// 如果移动距离超过5,则认为拖动了按钮 isDrag = true; } slideBtn_left = slideBtn_left + distance; firstX = lastX; break; case MotionEvent.ACTION_UP:// 不管是onclick还是拖动都会触发up事件,所以在这里设置view的最终状态即可 if (isDrag) { int maxLeft = backgroundBitmap.getWidth() - slideBtn.getWidth(); if (slideBtn_left > maxLeft / 2) {// 如果拖动的距离超过可拖动距离的一半 currState = true; } else { currState = false; } flushState(); } break; } // move与up事件时刷新view refreshView(); return true; } private void flushState() { if (currState) { slideBtn_left = backgroundBitmap.getWidth() - slideBtn.getWidth(); } else { slideBtn_left = 0; } refreshView(); switchChangedListener.currState(this, currState); } private void refreshView() { int maxLeft = backgroundBitmap.getWidth() - slideBtn.getWidth(); slideBtn_left = (slideBtn_left > 0) ? slideBtn_left : 0; slideBtn_left = (slideBtn_left < maxLeft) ? slideBtn_left : maxLeft; invalidate(); } private MySwitchChangedListener switchChangedListener; public interface MySwitchChangedListener { void currState(View view, boolean state); } // 注册回调 public void setOnSwitchChangedListener( MySwitchChangedListener switchChangedListener) { this.switchChangedListener = switchChangedListener; }}
ToggleButton使用时就是可点击,可拖动。
那么我们先在构造方法中初始化2张图,再初始化画笔paint,再对该view(ToggleButton)注册单击事件,仿照SDK原生的togglebutton,再复写onTouchEvent方法监听3种事件down,move,up。
首先draw背景图是不变的,我们只需要draw小圆点的位置
onclick时,比较简单,小圆点要么在整个view的最左边,要么在最右边。关键是这个draw图的距离 算好 即可。
捕捉移动事件:
down时,我们只需要记录初始时的X坐标,以及设置为非拖动状态。
move时,如果移动的距离超过5我们则认为拖动了小圆点,获取拖动的距离再从新绘制一遍view即可,设置为拖动状态。
up时,如果触发过move事件则不是onclick事件,注意:一次onclick就是完整的一次down和up组成,中间不包含move事件。onclick事件这个是比较好绘制的,如果触发过move时可能有点困难,这里可以取的distance其实是背景图的width减去小圆点的width这段距离,如上图。当拖动的距离超过这段距离的一半时,我们就在up这边直接设置小圆点到view的最左边或者最右边。
好了,其实就那么多东西了,还有就是在添加一个回调接口返回开关的状态。回调也即是设计模式中的观察者模式,在Android中很多地方都有用到,这个是必须要掌握的。
最后在xml布局文件中引用该view
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.togglebutton.MyToggleButton android:id="@+id/toggle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="开关状态" /></RelativeLayout>
还需要在Activity中注册togglebutton的切换监听
第一次写文章,文章写得很丑,很多功能都还不知道,以后再慢慢改进。今天就到这了!
源码点击下载
- 自定义togglebutton
- 自定义ToggleButton
- 自定义ToggleButton
- ToggleButton自定义
- 自定义ToggleButton
- WPF 自定义ToggleButton样式
- WPF ToggleButton自定义样式
- 自定义ToggleButton的样式
- ToggleButton自定义View学习
- Android 自定义ToggleButton
- 自定义滑动开关(ToggleButton)
- android-----自定义ToggleButton
- Android:自定义ToggleButton
- 自定义ToggleButton选择控件
- Android 自定义toggleButton
- Android 自定义ToggleButton
- android_94_自定义ToggleButton
- Android 自定义View---ToggleButton
- Linux内存占用过高?非也
- 【深度反思】:环境影响人的非常重要的因素
- C++作用域
- Android WebView - 全面总结(概述、捕获url、js交互、小技巧、内存泄漏、缓存机制)
- C++变量的可见性
- 自定义ToggleButton
- 机器学习路线
- 设计网页时IE6中10个不得不注意的问题
- centos 7 菜鸟第一天 双启动
- java单例模式就有6种,你知道哪几种?!
- 链表:女生节快乐
- 编程思想的演变
- 开发人员面对产品经理的“为难” 得淡定
- svn提交提示 目录 is already locked