先来张效果图

banner.gif

步骤思路

继承View

1、测量自己的宽高

2、绘制自己

3、处理触摸事件

1、继承View

public class MyToggleButton extends View {

public MyToggleButton(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

}

// 在布局文件中使用控件时 调用

public MyToggleButton(Context context, AttributeSet attrs) {

super(context, attrs);

}

// 在代码中new对象时 调用

public MyToggleButton(Context context) {

super(context);

}

2、在布局中使用MyToggleButton

android:id="@+id/toggle"

android:layout_width="wrap_content"

android:layout_height="wrap_content" />

3、测量宽高

// 测量自己的宽高,把背景图片的宽高设置为自己的宽高

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

// 把背景图片的宽高设置为自己的宽高

setMeasuredDimension(backgroundBitmap.getWidth(), backgroundBitmap.getHeight());

}

// 外界设置开关背景图片资源

public void setBackgroundRes(int backgroundRes){

// 把传进来的图片资源 转换成Bitmap对象

backgroundBitmap = BitmapFactory.decodeResource(getResources(), backgroundRes);

}

4、绘制

// 外界设置滑动块图片资源

public void setSlideButtonRes(int slideButtonRes){

// 把传进来的图片资源 转换成Bitmap对象

slideButtonBitmap = BitmapFactory.decodeResource(getResources(), slideButtonRes);

}

// 绘制自己

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

// 绘制背景

canvas.drawBitmap(backgroundBitmap, 0, 0, null);

// 绘制滑动块

canvas.drawBitmap(slideButtonBitmap, 0, 0, null);

}

5、根据状态绘制滑动块

// 外界设置开关状态

public void setState(boolean state){

this.currentState = state;

}

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

// 绘制背景

canvas.drawBitmap(backgroundBitmap, 0, 0, null);

// 绘制滑动块 根据外界的设置,展示开或关

if(!currentState){// 关状态

canvas.drawBitmap(slideButtonBitmap, 0, 0, null);

}else{// 开状态

canvas.drawBitmap(slideButtonBitmap, backgroundBitmap.getWidth()-slideButtonBitmap.getWidth(), 0, null);

}

}

6、处理事件,让滑动块随手指移动

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

isTouching = true;

// 获取手指触摸时相对于自己的x位置

currentX = (int) event.getX();

break;

case MotionEvent.ACTION_MOVE:

currentX = (int) event.getX();

break;

case MotionEvent.ACTION_UP:

isTouching = false;

currentX = (int) event.getX();

break;

default:

break;

}

// 重新绘制控件,重新调用onDraw

invalidate();

return true;// 消费掉事件

}

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

// 绘制背景

canvas.drawBitmap(backgroundBitmap, 0, 0, null);

// 根据手指触摸的位置绘制滑动块图片

if(isTouching){

canvas.drawBitmap(slideButtonBitmap, currentX, 0, null);

}else{

// 绘制滑动块 根据外界的设置,展示开或关

if(!currentState){// 关状态

canvas.drawBitmap(slideButtonBitmap, 0, 0, null);

}else{// 开状态

canvas.drawBitmap(slideButtonBitmap, backgroundBitmap.getWidth()-slideButtonBitmap.getWidth(), 0, null);

}

}

}

7、让用户感觉手指触摸到了滑动块中间

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

// 绘制背景

canvas.drawBitmap(backgroundBitmap, 0, 0, null);

// 根据手指触摸的位置绘制滑动块图片

if(isTouching){

int left = currentX-slideButtonBitmap.getWidth()/2;// 让滑动块画的中心画到手指触摸的位置

// 限制滑动块的滑动范围

if(left<0){// 如果超出左边,直接绘制到0位置

left = 0;

}else if(left>backgroundBitmap.getWidth()-slideButtonBitmap.getWidth()){

left = backgroundBitmap.getWidth()-slideButtonBitmap.getWidth();

}

canvas.drawBitmap(slideButtonBitmap, left, 0, null);

}else{

......

}

}

8、手指抬起时,通过改变当前状态,让滑动块根据状态绘制

case MotionEvent.ACTION_UP:

isTouching = false;

currentX = (int) event.getX();

// 手指抬起时,根据手指触摸的位置与背景图片一半比较,离哪边近,滑动块就滑动到哪

currentState = currentX>backgroundBitmap.getWidth()/2;

break;

default:

break;

}

9、对外暴露监听,让外界监听到开关的状态变化

* 1、暴露接口

// 对外暴露开关状态发生变化的接口

public interface OnToggleButtonStateChangeListener{

// 当开关状态发生变化时 调用

void onStateChanged(boolean state);

}

* 2、对外提供监听器

// 让外界设置状态变化的监听器

public void setOnToggleButtonStateChangeListener(OnToggleButtonStateChangeListener listener){

this.mListener = listener;

}

* 3、当状态发生变化时调用监听器的回调方法

case MotionEvent.ACTION_UP:

isTouching = false;

currentX = (int) event.getX();

// 手指抬起时,根据手指触摸的位置与背景图片一半比较,离哪边近,滑动块就滑动到哪

// 当状态发生变化时,调用外界传递进来的监听器的onStateChanged

boolean tempState = currentX>backgroundBitmap.getWidth()/2;

if(tempState!=currentState){// 状态发生变化

currentState = tempState;

if(mListener!=null){

mListener.onStateChanged(currentState);

}

}

break;

* 4、外界监听开关状态

OnToggleButtonStateChangeListener listener = new OnToggleButtonStateChangeListener() {

@Override

public void onStateChanged(boolean state) {

// 处理业务

Toast.makeText(getApplicationContext(), ""+state, 0).show();

}

};

toggle.setOnToggleButtonStateChangeListener(listener);

10、自定义属性

* 1、定义属性

/toggle94/res/values/attrs.xml

* 2、在布局中使用属性,要先声明命名空间

xmlns:itheima="http://schemas.android.com/apk/res/com.itheima.toggle94"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context=".MainActivity" >

android:id="@+id/toggle"

itheima:backgroundRes="@drawable/switch_background"

itheima:slideButtonRes="@drawable/slide_button_background"

itheima:state="false"

android:layout_width="wrap_content"

android:layout_height="wrap_content" />

* 3、代码中获取自定义属性值,设置给控件

// 在布局文件中使用控件时 调用

public MyToggleButton(Context context, AttributeSet attrs) {

super(context, attrs);

// 从布局文件中获取控件的自定义属性值

String namespace = "http://schemas.android.com/apk/res/com.itheima.toggle94";

int backgroundResValue = attrs.getAttributeResourceValue(namespace, "backgroundRes", 0);

setBackgroundRes(backgroundResValue);

int slideButtonResValue = attrs.getAttributeResourceValue(namespace, "slideButtonRes", 0);

setSlideButtonRes(slideButtonResValue);

currentState = attrs.getAttributeBooleanValue(namespace, "state", false);

}

android togglebutton 自定义,自定义控件之-----ToggleButton相关推荐

  1. Android 控件开发之ToggleButton

    ToggleButton有两种状态:选中和未选择状态,并且需要为不同的状态设置不同的显示文本 ToggleButton效果: 本程序main.xml源码   <?xml version=&quo ...

  2. android 实现自定义监听接口,Android在自定义类中实现自定义监听器方式

    Android在自定义类中实现自定义监听器方式 发布时间:2020-08-31 06:19:39 来源:脚本之家 阅读:203 作者:Simon_Qi 监听器可以说是Android开发中最常用的东西之 ...

  3. Android开发技巧——自定义控件之自定义属性

    Android开发技巧--自定义控件之自定义属性 掌握自定义控件是很重要的,因为通过自定义控件,能够:解决UI问题,优化布局性能,简化布局代码. 上一篇讲了如何通过xml把几个控件组织起来,并继承某个 ...

  4. android自定义省略号,Android开发自定义TextView省略号样式的方法

    本文实例讲述了Android开发自定义TextView省略号样式的方法.分享给大家供大家参考,具体如下: 在布局xml中设置textView的字段 android:maxLines="2&q ...

  5. Android开发技巧——自定义控件之组合控件

    Android开发技巧--自定义控件之组合控件 我准备在接下来一段时间,写一系列有关Android自定义控件的博客,包括如何进行各种自定义,并分享一下我所知道的其中的技巧,注意点等. 还是那句老话,尽 ...

  6. togglebutton用法 java_Android中ToggleButton开关状态按钮控件使用方法详解

    ToggleButton开关状态按钮控件使用方法,具体内容如下 一.简介 1. 2.ToggleButton类结构 父类是CompoundButton,引包的时候注意下 二.ToggleButton开 ...

  7. Android中自定义视图View

    标签: 前言 好长时间没写blog了,心里感觉有点空荡荡的,今天有时间就来写一个关于自定义视图的的blog吧.关于这篇blog,网上已经有很多案例了,其实没什么难度的.但是我们在开发的过程中有时候会用 ...

  8. Android中自定义视图View之---前奏篇

    前言 好长时间没写blog了,心里感觉有点空荡荡的,今天有时间就来写一个关于自定义视图的的blog吧.关于这篇blog,网上已经有很多案例了,其实没什么难度的.但是我们在开发的过程中有时候会用到一些自 ...

  9. Android进阶——自定义View之自己绘制彩虹圆环调色板

    引言 前面几篇文章都是关于通过继承系统View和组合现有View来实现自定义View的,刚好由于项目需要实现一个滑动切换LED彩灯颜色的功能,所以需要一个类似调色板的功能,随着手在调色板有效区域滑动, ...

最新文章

  1. android system window,Android控件的fitSystemWindows属性
  2. Linux内核模块编程系列1-极简内核模块编写
  3. 关于在64位系统上,使用APlayer,运行报错“找不到指定的模块”
  4. 【Python】用Pyecharts制作炫酷的可视化大屏
  5. OpenCASCADE:使用扩展数据交换 XDE之几何尺寸和公差 (GDT)
  6. Solr操作中新手常见问题
  7. U盘数据泄露,用不到30行的Python代码就能盗走
  8. html设置布局颜色设置,css布局中置背景颜色
  9. 【机器学习】集成学习--AdaBoost
  10. 产业链人士:LCD显示驱动芯片价格有望趋于稳定
  11. pytorch nn.Linear
  12. java 上界和下界,Java 泛型上下界(上下限)
  13. r语言结构方程模型可视化_R语言时间序列分析(二):ts对象及其可视化
  14. Nginx篇05-http长连接和keeplive
  15. 1449 后缀表达式
  16. 李沐动手学深度学习V2-基于注意力机制的seq2seq
  17. 用cocos实现的《我的世界》已经上线微信小游戏,分享一下主要技术
  18. win7下的cmd窗口可以全屏显示吗
  19. C++单链表学生管理系统(有登录界面)
  20. 【SpringBoot】3、SpringBoot中整合Thymeleaf模板引擎

热门文章

  1. NUC1931 Problem D 区间素数【素数筛选】
  2. 类型配置命名空间 —— XML schema
  3. sklearn.metrics —— 混淆矩阵及其绘制、Accuracy/Precision/Recall/F1-score
  4. 规律、逻辑规律与悖论
  5. Python 中的循环与 else
  6. 词汇的积累 —— 反义词、同义词
  7. 说不尽的 π —— π 的近似计算
  8. 盈不足术与老鼠打洞问题的近似解
  9. 机器学习基础(九)—— iterative optimization
  10. C++基础::文件流(二)