重写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. raspberry pi wifi

    vim /etc/network/interfaces 修改 wpa-ssid 和 wpa-psk

  2. spring cloud学习(六) 配置中心-自动更新

    上一篇学习了spring cloud config的基本使用,但发现有个问题,就是每次更改配置后,都需要重启服务才能更新配置,这样肯定是不行的.在上网查资料了解后,spring cloud支持通过AM ...

  3. C#6.0语言规范(十一) 结构

    结构与类类似,因为它们表示可以包含数据成员和函数成员的数据结构.但是,与类不同,结构是值类型,不需要堆分配.结构类型的变量直接包含结构的数据,而类类型的变量包含对数据的引用,后者称为对象. 结构对于具 ...

  4. Javascript如何避免连续调用中取到不存在的属性而导致报TypeError错?

    背景: 在最近的 NODEJS 项目中,涉及到数据库的查询,回调函数里返回了查询结果,我这样做处理然后返回给前端: return results.collect_coupon[0].count 但是这 ...

  5. Python文件与函数练习题

    练习题 文件处理相关 编码问题 请说明python2 与python3中的默认编码是什么? python2默认是ASCII码,python3默认是utf-8 为什么会出现中文乱码?你能列举出现乱码的情 ...

  6. 关于如何食用Xcode——用mac的小蒟蒻

    前言QwQ 对于一只用Mac的小蒟蒻,没有Dev_c++简直太难受了,用在线IDE写代码又没法保存,那么我们怎么办呢? 好在App Store里有这个好东西 所以我们今天来介绍一下 “如何使用Xcod ...

  7. String、StringBuffer与StringBuilder之间区别 (转载)

    最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,StringBuilder的东西,现在整理一下. 关于这三个类在字符串处理中的位置不言而喻,那 ...

  8. opencv实现正交匹配追踪算法OMP

    //dic: 字典矩阵: //signal :待重构信号(一次只能重构一个信号,即一个向量) //min_residual: 最小残差 //sparsity:稀疏度 //coe:重构系数 //atom ...

  9. 在matlab中实现梯度下降法

    梯度下降法的原理,本文不再描述,请参阅其它资料. 梯度下降法函数function [k ender]=steepest(f,x,e),需要三个参数f.x和e,其中f为目标函数,x为初始点,e为终止误差 ...

  10. MVC3学习:基于ObjectContext的数据增删改查操作

    数据库里面的表格,映射为对应的实体类.实体类的编写,可以自己手动编写,也可以使用工具或插件自动生成.在MVC3里面,我们可以使用VS的POCO插件自动生成实体类.如下图: 关于POCO插件的安装与使用 ...