重写View的onTouchEvent()方法,传递进来MotionEvent对象

调用MotionEvent对象的getAction()方法,获取当前动作

switch判断一下当前动作

事件为MotionEvent.ACTION_DOWN是手指第一次触摸屏幕

事件为MotionEvent.ACTION_MOVE是手指在屏幕上移动

事件为MotionEvent.ACTION_UP是手指离开屏幕

当手指触摸到屏幕

定义手指最后的坐标lastX

调用MotionEvent对象的getX() 方法,得到lastX的值

当手指在屏幕上移动

定义手指横向移动的距离dis

调用getX()-lastX就是移动的距离

定义滑动按钮的左边就是这个移动的距离

判断slideBtnLeft位于合理的位置,0到背景图的宽度-滑动按钮的宽度

调用invalidate()方法,刷新视图

onClick事件和onTouchEvent是有冲突

定义一个标志isDrag变量,如果有拖动发生,就把这个变量赋值true

在onCllick()方法里面对这个变量进行判断

当手指抬起的时候

判断当前slideBtnLeft来确定当前按钮是开还是关的状态

slideBtnLeft比较 maxLeft的一半就能判断当前状态

package com.tsh.myswitchbtn;

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 MyToggleBtn extends View implements OnClickListener {
//背景图片
private Bitmap bitmapBackground;
//按钮图片
private Bitmap bitmapBtn;
private Paint paint;
/**
* 布局文件中使用
* @param context
* @param attrs
*/
public MyToggleBtn(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
/**
* 初始化view
*/
private void initView() {
bitmapBackground=BitmapFactory.decodeResource(getResources(), R.drawable.switch_background);
bitmapBtn=BitmapFactory.decodeResource(getResources(), R.drawable.slide_button);
paint=new Paint();
paint.setAntiAlias(true);
//点击事件
setOnClickListener(this);
}
/**
* 计算大小
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(bitmapBackground.getWidth(), bitmapBackground.getHeight());
}
//当前状态
private boolean currentState=false;
//滑动按钮的当前left
private float slideBtnLeft=0;
/**
* 绘制view
*/
@Override
protected void onDraw(Canvas canvas) {
//绘制背景
canvas.drawBitmap(bitmapBackground, 0, 0, paint);
//绘制滑动按钮
canvas.drawBitmap(bitmapBtn, slideBtnLeft, 0, paint);
}
private boolean isDrag=false;
/**
* 点击事件
*/
@Override
public void onClick(View v) {
//解决与移动事件的冲突
if(!isDrag){
currentState = !currentState;
flushState();
} } private int lastX;
/**
* 触摸事件
*/
private int firstX;
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
switch(event.getAction()){
//手指按下
case MotionEvent.ACTION_DOWN:
firstX=lastX=(int) event.getX();
isDrag=false;
break;
//手指移动
case MotionEvent.ACTION_MOVE:
//解决与点击事件冲突
if(Math.abs(event.getX()-firstX)>5){
isDrag=true;
} int dis=(int) event.getX()-lastX;
slideBtnLeft=slideBtnLeft+dis;
lastX=(int) event.getX();
break;
//手指抬起
case MotionEvent.ACTION_UP:
if(isDrag){
int maxLeft = bitmapBackground.getWidth()
- bitmapBtn.getWidth();
if (slideBtnLeft >= maxLeft / 2) {
currentState = true;
} else {
currentState = false;
}
flushState();
}
break;
}
flushView(); return true;
}
/**
* 刷新状态
*/
private void flushState() {
if (currentState == true) {
slideBtnLeft = bitmapBackground.getWidth()
- bitmapBtn.getWidth();
} else {
slideBtnLeft = 0;
}
invalidate();
}
/**
* 刷新视图
*/
private void flushView() {
int maxLeft=bitmapBackground.getWidth()-bitmapBtn.getWidth();
slideBtnLeft=(slideBtnLeft>0) ? slideBtnLeft : 0;
slideBtnLeft=(slideBtnLeft<maxLeft) ? slideBtnLeft:maxLeft;
invalidate();
}
}

[android] 切换按钮-自定义控件-拖动效果的更多相关文章

  1. [android] 切换按钮-自定义控件

    准备两张图片,按钮背景,上面的小开关 创建一个类MyToggleBtn,继承View 实现三个构造方法,传递上下文, 实现构造方法,传递Context对象,在java代码中实例化时主要使用这个 实现构 ...

  2. Android 浮动按钮的伸缩效果

    在做项目时想增加点动感,于是就有如下效果: 实现起来也很简单,通过属性动画和recyclerview 滑动结合就很好实现了. 通过给recycleview添加一个滑动监听:通过滚动的差值来处理动画 m ...

  3. Android实现按钮点击效果(第一次点击变色,第二次恢复)

    1.首先创建一个按钮 <Button android:id="@+id/click" android:layout_width="fill_parent" ...

  4. Android 仿 窗帘效果 和 登录界面拖动效果 (Scroller类的应用) 附 2个DEMO及源码

    在android学习中,动作交互是软件中重要的一部分,其中的Scroller就是提供了拖动效果的类,在网上,比如说一些Launcher实现滑屏都可以通过这个类去实现.下面要说的就是上次Scroller ...

  5. Android中使用ImageViewSwitcher实现图片切换轮播导航效果

    前面写过了使用ViewFlipper和ViewPager实现屏幕中视图切换的效果(ViewPager未实现轮播)附链接: Android中使用ViewFlipper实现屏幕切换 Android中使用V ...

  6. android 按钮点击效果实现

    在其他人的博客里看到其实实现按钮点击效果的方法有很多,这里提到的只是其中一个办法 图片素材(我自己用截图截的,可以自己搞) 放到mipmap目录下(studio是在这个目录下 , eclipse 直接 ...

  7. Android切换页面效果的实现二:WebView+ViewPager

    前言: 由于第一种切换页面的效果不能满足项目的要求,于是又找到另外一种更简单好用的方法来实现,顿时感觉,做项目开发,找到一种合适的方法能够减少很多时间,(刚开始自己弄的时候还想着自己写手势识别的方法呢 ...

  8. Android 仿 窗帘效果 和 登录界面拖动效果 (Scroller类的应用) 附 2个DEMO及源代码

    在android学习中,动作交互是软件中重要的一部分.当中的Scroller就是提供了拖动效果的类,在网上.比方说一些Launcher实现滑屏都能够通过这个类去实现.以下要说的就是上次Scroller ...

  9. Android长按及拖动事件探究

    Android中长按拖动还是比较常见的.比如Launcher中的图标拖动及屏幕切换,ListView中item顺序的改变,新闻类App中新闻类别的顺序改变等.下面就这个事件做一下分析. 就目前而言,A ...

随机推荐

  1. .net core中Quartz的使用

    原来工作中有用到定时任务Quartz,不过是在MVC项目中,现在net core项目中也要用到,就开始改版.中间发现在网上的教程只有执行定时计划的过程,却很少有人写注册的过程,觉得有点略坑.所以写此文 ...

  2. 自定义延时关闭弹窗,替代MesssageBox

    1,新建一个窗体MessageForm,在里面加一个label控件和timer 2,代码如下: public partial class MessageForm : Form { int t; str ...

  3. 201621123018《Java程序设计》第9周学习报告

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 泛型个人认为可以理解为一种模糊的类型,在里面写入各种方法,程序员可以根据需要再创建具体类型的对象,然后调用泛型 ...

  4. 如何执行超过一百兆(100MB)的sql脚本?

    最近遇到一个问题,在sqlserver的查询分析器里面执行一个超过100MB的数据库脚本,发现老是报“引发类型为“System.OutOfMemoryException”的异常”,上网查了一下,主要是 ...

  5. Windows 网卡超过序列

    以前连接过别的网络,现在重新装网已经排到"网络连接9"了,连以前起过的wifi名称(ssid)都变成"*** 3"了,怎么把以前的清空呢? 这是解决办法: wi ...

  6. CentOS7安装MYSQL。

    参考这个文章(网页已存到本地):http://www.cnblogs.com/starof/p/4680083.html 安装完成后,本地登录MYSQL没有问题. 现在主要是在windows下用ora ...

  7. Swift 里 Set(四)Testing for Membership

    即contains操作 /// - Parameter member: An element to look for in the set. /// - Returns: `true` if `mem ...

  8. Tools - 文本编辑器Notepad++

    00 - NotePad++ 官网 01 - Notepad++修改主题 依次点击设置---语言格式设置---选择主题,在显示界面中修改相关设置(背景色.前景色.字体等). 02 - Notepad+ ...

  9. [转载]windows下安装Python虚拟环境virtualenv,virtualenvwrapper-win

    1 前言 由于Python的版本众多,还有Python2和Python3的争论,因此有些软件包或第三方库就容易出现版本不兼容的问题. 通过 virtualenv 这个工具,就可以构建一系列 虚拟的Py ...

  10. python粘包分析与解决

    TCP与UDP协议 TCP(transport control protocol,传输控制协议)是面向连接的,面向流的,提供高可靠性服务.收发两端(客户端和服务器端)都要有一一成对的socket,因此 ...