ToggleButton自定义View学习

Android UI(ToggleButton)详解 目录:     1.应用场景     2.常用属性            3.事件监听与基本使用     4.自定义ToggleButton         4.1 java代码自定义可拖动ToggleButton         4.2 Selector自定义点击切换ToggleButton              5.设置统一风格      1.应用场景      To 阅读详情

1. ToggleButton项目地址

2. rebound项目地址

3. 本地下载

4. 相关参考

android中onMeasure初看,深入理解布局之一!

Android 自定义View onMeasure方法的实现

ANDROID自定义视图——onMeasure,MeasureSpec源码 流程 思路详解

Android视图绘制流程完全解析,带你一步步深入了解View(二)



昨天学习了ToggleButton,一个挺好看的开关。并且自己重新实现了一遍。感觉还是很不错的。今早又重新复习了自定义View的相关知识,包括绘制的流程及回调函数的作用。想到不知怎样才能达到一个高度,有些失落。

这个View的效果图是这样的(图来自这里):


看起来很舒服,但是是怎样实现的呢?实现起来还是需要思考的。结合项目的源码,可以把这个View分解为几部分。这也提供了一种思路,要实现一个复杂漂亮的控件,是一层一层效果叠加起来。第一层是最里边的RoundRect,它的效果是由灰色变成青色(手机里还没了解哪个制作gif软件好用)。但是这个变化的过程是如何产生的,这也是整个View最核心的部分。包括滑动过程的控制。作者使用了一个开源的库,是由Facebook团队开发维护的rebound。它的作用是模拟物理的弹簧力的效果,想象一下,一根弹簧固定立起来,把手压下去,当手放开时,弹簧的伸缩变化。即是rebound所实现的,这里涉及到两个系数,就是张力tension和摩擦力friction。rebound的使用可以参考项目的例子或者作者的写法。先是创建Spring实例:

		mBaseSpringSystem = SpringSystem.create();
		mSpring = mBaseSpringSystem.createSpring();
		mSpring.setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(50, 7));

然后在适当的位置进行监听和解除监听:

	@Override
	protected void onAttachedToWindow() {
		super.onAttachedToWindow();
		mSpring.addListener(mSpringListener);
	}
	@Override
	protected void onDetachedFromWindow() {
		super.onDetachedFromWindow();
		mSpring.removeListener(mSpringListener);
	}
	

其中,传入的mSpringListener监听对象继承了SimpleSpringListener,关键在于它的onSpringUdate(Spring spring)方法,我们要重写它的方法。并且进行映射。其中关键的函数是:

mWhileLTScale = (int) SpringUtil.mapValueFromRangeToRange(currentValue, 0, 1, 0, mWhileLTScaleWidth);

它传入了从spring中获取的currentValue,映射的起始范围,和映射的结束范围。返回的值是物理的弹簧力学模型。仔细观察上面开关中间的滑动圆形,可以看到它的伸缩性。我们应该去它的 文档说明网站,里边有介绍如何使用,和一个非常形象的演示系统。便于理解其中的效果。其中,我想到了之前没有深入学习的属性动画中的插值器,这个应该也是做同样的事情。等下要去学习弄懂。这样最重要的事情别人就帮我们做好了。而我们现在,只要在监听回调函数中,进行draw绘画所需属性的修改,就可以完成这个自定义View。但是其中,还是有一些涉及到计算的事情,不能搞错。这也是较为重要和繁琐的工作。比如,我们要计算长和宽、可以匹配的最大范围值,外RountRect的半径,内RountRect的半径等:

		int width = getWidth();
		int height = getHeight();
		
		mWhileLeftMargin = (int) mOffBorderWidth;
		mWhileTopMargin = (int) mOffBorderWidth;
		mWhileRightMargin = (int) (width - mOffBorderWidth);
		mWhileBottomMargin = (int) (height - mOffBorderWidth);
		
		mWhileLTScaleWidth = width - (width-(int)mOffBorderWidth*2)/3 - width/15;
		mWhileRBScaleWidth = (height-(int)mOffBorderWidth*2)/4;
		
		mRadius = (Math.min(width, height)  ) / 2;
		mRadius2 = mRadius - mOffBorderWidth;
		mRadius3 = mRadius2 - mOffBorderWidth;
		
		
		mRectMoveFillLeft = mOffBorderWidth;
		mRectMoveFillTop = mOffBorderWidth;
		mRectMoveFillRight = mRectMoveFillLeft + mRadius2 * 2;
		mRectMoveFillBottom = mOffBorderWidth + mRadius2 * 2;
		
		
		mRectMoveMax = width - mRadius2*2 - mOffBorderWidth;

还有,这段代码应该放在哪个地方。onMeasure和onLayout的作用。当然,这个在给出的参考地址中都有讲解。我们把它放在onLayout函数中,其中相关的只是要获取到getWidth()和getHeight(),其它的都只是纯计算。

现在,我们看第二层绘画,即是一个比第一层图像小一个BorderWidth的内RountRect,并且颜色为白色。打开开关时,它会同时移动到距右边的三分之一,并且缩小。它的移动、缩放的值也是在spring的监听回调函数中改变。第三层是一个圆形的RoundRect,它从左边移动到右边,并且颜色渐变。第四层动画是一个比第三层小一个BorderWidth的圆形RoundRect,颜色为固定的色值,这里为白色,并且同样从左边移动到右边。最后,如果把这四层效果一同绘制,就是上面ToggleButton的效果了。当实现完成后,发现并不是很难,给了自己信心。下面贴几段代码:

①获取自定义的参数值

		TypedArray typedArray = null;
		try {
			typedArray = context.obtainStyledAttributes(set, R.styleable.ToggleButton);
			mOnColor = typedArray.getColor(R.styleable.ToggleButton_onColor, mOnColor);
			mOffColor = typedArray.getColor(R.styleable.ToggleButton_offColor, mOffColor);
			mOffBorderWidth = typedArray.getDimension(R.styleable.ToggleButton_offBorderWidth, mOffBorderWidth);
			mOffBorderColor = typedArray.getColor(R.styleable.ToggleButton_offBorderColor, mOffBorderColor);
			mTension = typedArray.getInteger(R.styleable.ToggleButton_tension, mTension);
			mResistance = typedArray.getInteger(R.styleable.ToggleButton_resistance, mResistance);
			
		} finally {
			if (typedArray != null ) {
				typedArray.recycle();
			}
		}

②Spring中的监听回调:

	private class SpringListener extends SimpleSpringListener {

		@Override
		public void onSpringUpdate(Spring spring) {
			super.onSpringUpdate(spring);
			double currentValue = spring.getCurrentValue();
			
			changeEffect(currentValue );
			
			log("currentValue: " + currentValue );
			
		}

		private void changeEffect(double currentValue) {
			//得到变化的背景颜色值
			int or = Color.red(mOffColor);
			int og = Color.green(mOffColor);
			int ob = Color.blue(mOffColor);
			int dr = Color.red(mOnColor);
			int dg = Color.green(mOnColor);
			int db = Color.blue(mOnColor);
			int cr = (int) SpringUtil.mapValueFromRangeToRange(1-currentValue, 0, 1, dr, or);
			int cg = (int) SpringUtil.mapValueFromRangeToRange(1-currentValue, 0, 1, dg, og);
			int cb = (int) SpringUtil.mapValueFromRangeToRange(1-currentValue, 0, 1, db, ob);
			
			cr = modify(cr); 
			cg = modify(cg);
			cb = modify(cb);
			
			mCurrentColor = Color.rgb(cr, cg, cb);
			
			//改变第二层效果,即白色的内框移动缩小
			mWhileLTScale = (int) SpringUtil.mapValueFromRangeToRange(currentValue, 0, 1, 0, mWhileLTScaleWidth);
			mWhileRBScale = (int) SpringUtil.mapValueFromRangeToRange(currentValue, 0, 1, 0, mWhileRBScaleWidth);
			
			
			log("mWhileLTScale:" + mWhileLTScale + ", mWhileRBScale:" + mWhileRBScale );
			
			
			//移动的圆圈,第三层
			mCurRectMove = SpringUtil.mapValueFromRangeToRange(currentValue, 0, 1, 0, mRectMoveMax);
					
			
			if (Looper.myLooper() == Looper.getMainLooper() ) {
				invalidate();
			} else {
				postInvalidate();
			}
			
		}

		private int modify(int cr) {
			int t = cr > 0 ? cr : 0;
			t = t < 255 ? t : 255;
			return t;
		}

	}

③onDraw方法中的绘制过程:

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		log("onDraw()");
		mPaint.setColor(mCurrentColor);
		mOutRect.set(0, 0, getWidth(), getHeight());
		canvas.drawRoundRect(mOutRect, mRadius, mRadius, mPaint);
		
		mPaint.setColor(Color.parseColor("#FCFCFC") );	//有质感的白色
//		mOutRect.set(mWhileLeftMargin+mWhileLTScale, mWhileTopMargin+mWhileLTScale, mWhileRightMargin-mWhileRBScale, mWhileBottomMargin-mWhileRBScale);
		
		int left = mWhileLeftMargin+mWhileLTScale;
		int top = mWhileTopMargin+mWhileRBScale;
		int right = mWhileRightMargin-mWhileRBScale;
		int bottom =  mWhileBottomMargin-mWhileRBScale;
		
		float r2 = mRadius-mOffBorderWidth-mWhileRBScale;
		
		log("zb", "mWhileLTScale:" + mWhileLTScale + ", mWhileRBScale:" + mWhileRBScale);
		log("zb", "left: " + left + ", top: " + top + ", right: " + right + ", bottom :" + bottom );
		
		mOutRect.set(left, top, right, bottom);
		canvas.drawRoundRect(mOutRect, r2, r2, mPaint);
		
		//画第三部分,一个移动变化的圆圈
		mPaint.setColor(mCurrentColor);
		mOutRect.set(mRectMoveFillLeft+(float)mCurRectMove, mRectMoveFillTop, mRectMoveFillRight+(float)mCurRectMove, mRectMoveFillBottom);
		canvas.drawRoundRect(mOutRect, mRadius, mRadius, mPaint);
		
		//画第四部分,最里面的移动的白色圆圈
		mPaint.setColor(Color.WHITE);
		mOutRect.set(mRectMoveFillLeft+(float)mCurRectMove+mOffBorderWidth, mRectMoveFillTop+mOffBorderWidth, mRectMoveFillRight+(float)mCurRectMove-mOffBorderWidth, mRectMoveFillBottom-mOffBorderWidth);
		canvas.drawRoundRect(mOutRect, mRadius3, mRadius3, mPaint);
	}




打造自定义Android滑动ToggleButton组件 本文还有配套的精品资源,点击获取 简介:在Android应用开发中,自定义组件对于创造丰富的用户界面至关重要。本项目专注于实现一个可滑动的ToggleButton组件,提供新颖的用户交互体验。开发者将学习如何重写 View 和 CompoundButton 类的方法,使用 com.facebook.rebound.jar 库添加动态... 阅读详情

相关推荐

自定义个性化togglebutton

简单的风格.简单的自定义togglebutton

Android之---两种自定义开关(ToggleButton)的实现(代码实现和图片实现)

两种自定义开关(ToggleButton)的实现(代码实现和图片实现) 效果图 第一个button是用代码实现的,第二个不同是用图片实现的。 ToggleButton.java package com.xiaokele.demo.stogglebutton; import android.animation.ValueAnimator; import android.content...

weixin_42630640的博客 976

Android之自定义ToggleButton使用

Android之自定义ToggleButton使用,很实用的一个Demo哦,要你们1个资源分不过分吧

自定义ToggleButton

很久之前就想写博客对自己的过去进行总结,由于个人比较懒这一原因而导致一直都未开始。现在鼓起勇气,克服这一懒惰心理开始写下第一篇博文。另外个人也是技术比较差,有什么写得不够好,不够详细的请各位同学多多指出,我将逐一改正。 好了,下面开始我们的自定义ToggleButton。那么我们先上图 首先ToggleButton这个view控件由一张可拖动,可点击的小圆点和背景图组成。

啊sir的专栏 551

自定义控件togglebutton

自定义控件togglebutton,快速学习自定义控件的方法,非常实用的demo

【ROS学习笔记】8.话题消息(Message)的定义与使用

ROS学习笔记8——话题消息(Message)的定义与使用

takedachia的博客 9547

自定义ToggleButton选择控件

转载请注明出处: 以前的项目中有关于手势开关的按钮,发现自带的ToggleButton不是很好看,于是花了些时间,自定义了个ToggleButton。 先上效果图: 其中,圆形button是可以随手指左右滑动的。 大体思路是分以下几步: 首先是需要自定义属性: 在values文件夹下的attrs xml文件中自定义属性:                   

MrCoder的博客 1274

Image Sensor常见分辨率下HTS,VTS设置

image sensor,HTS,VTS

propor的专栏 4974

android togglebutton 自定义,自定义控件之-----ToggleButton

先来张效果图banner.gif步骤思路继承View1、测量自己的宽高2、绘制自己3、处理触摸事件1、继承Viewpublic class MyToggleButton extends View {public MyToggleButton(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defSt...

weixin_29664819的博客 550

RK3576平台部署NanoTrack:边缘AI视觉跟踪实战指南

边缘AI部署是将深度学习模型在资源受限的嵌入式设备上高效运行的关键技术,其核心在于模型压缩、硬件适配与软件栈优化。通过INT8量化、算子融合与内存优化等原理,能显著降低模型计算量与内存占用,从而在嵌入式NPU上实现实时推理。这项技术的价值在于为安防监控、无人机视觉、工业检测等场景提供低功耗、高响应的智能感知能力。以瑞芯微RK3576平台部署轻量级视觉跟踪模型NanoTrack为例,其过程涉及模型结构分析、RKNN工具链转换、C++推理程序开发及多线程性能优化,完整展现了从算法到产品的工程化路径,为开发者提供

weixin_31887307的博客 426

馈电网络设计:通过Smith圆图工具完成微带线到同轴探针的阻抗匹配

Smith圆图通过图形化阻抗变换路径,显著简化微带线到同轴探针的匹配设计。设计需结合理论计算(微带线阻抗公式、探针等效模型)、圆图操作(串联/并联元件移动规则)及仿真验证,最终实现宽带低反射匹配。

百态·数智思维 | 聚焦大数据、量化与未来AI 1106

自定义togglebutton

package com.zcw.togglebutton; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graph

灬灬的专栏 1669

中文顶刊《会计研究》文本分析技术最新进展总结盘点

会计研究》是由中华人民共和国财政部主管、中国会计学会主办的国家一级学术期刊,为会计领域中文顶级期刊。随着大数据技术的日益成熟, 社交网络类文本 、上市公司披露类文本、媒体报道类文本、 其他类文本 、网络搜索数据、P2P 网络借贷文 本与分析师报告等文本数据逐渐成为财务会计的研究素材。

qq_52891550的博客 2891

Android 自定义View之随手指滑动的ToggleButton

因为项目里需要可滑动的ToggleButton,就去网上搜了一下,下载了两个例子看下,一个是仿ios6.0的滑动效果,虽说是滑动,但不是我想要的样式,还有一个是使用的facebook开源框架rebound的动画效果的ToggleButton,效果很赞,可惜的是不支持滑动。一开始我是想在第二种例子上做点文章,重写onDraw和onTouch方法支持滑动的同时还有动画效果。可惜的是尝试失败了,主要原因还

kobe_sun的博客 1010

MAX30102心率血氧传感器原理图设计,已量产(e-Health传感器)

在最近的便携健康监测设备项目中,我们采用了集成算法的 MAX30102 心率血氧模块 —— 这类带内置 MCU 算法的传感器能直接输出心率 / 血氧数值,大幅降低了主控资源占用。但硬件电路的稳定性直接决定了 PPG 信号的采集精度,下面结合实际项目里的原理图,拆解下这个模块的设计细节。

不脱发的程序猿 1278

使用Clumsy和Process Explorer定位软件高CPU占用问题

使用弱网模拟工具Clumsy和进程查看工具Process Explorer定位软件高CPU占用问题。

dvlinker的技术专栏 5706

Android自定义View仿IOS选择控件Togglebutton实现

Android自定义View仿IOS选择控件Togglebutton实现 目前在搞自定义view这一块的东西,将自己手写的很多效果控件将全部展示在博客中,这个是模仿ios的一个控件,虽然有原生的可以直接用了,但是毕竟知道实现更有助于自己写出风格各样的自定义控件。文中会贴出代码,但如果想在实际项目中使用,还需要增加很多逻辑判断以及监听回掉。 原效果图如下: 画图分析自定义view的绘

3733

GPU 运维实战:H100/H800/B300 换卡与压测

(烧多久、看什么、什么算合格)。文末还给了一个能直接跑的验收判定脚本,三个真实场景的裁决输出都在。

老韩的Linux云计算架构师进阶之路 270

Android 自定义ToggleButton

Android自定义ToggleButton1.需求 在项目需求中,可能需要自定义开关按钮,于是本人就根据网上的教程写了个符合自己需求的按钮 首先看一下要实现的效果:有4中图片的切换效果,点击切换开关状态,还要求支持滑动切换。 2.解决思路 写个MyToggleButton类,继承自View,重写onDraw,onClick,onMeasure,onTouchEvent等事件,

小强程序设计工作室 的博客 673

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

自定义控件——开关按钮ToggleButton

实现一个类似于ToggleButton的开关按钮   效果图:    资源图片: 1.自定义控件类 package com.dc.customview.view; import com.dc.customview.R; import android.content.Context; import android.graphics.Bitmap; impor

淡然一笑、的博客 625

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

ToggleButton学习

用ToggleButton实现一个线性布局在水平布局与垂直布局之间转换 xml配置 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match

a915800048的专栏 347

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

自定义view-Android 简单的滑动开关 ToggleButton

闲的没事,写一个自定义的滑动开关按钮ToggleButton 按钮图可以使用图片或者xml绘制的drawable文件,demo中使用的是默认的,可以直接替换成自己需要的。 效果: 使用很简单 1.将toggle-1.0.arr文件放入libs目录下 2.在build.gradle中加入依赖 implementation(name: 'toggle-1.0', ext: 'aar') 以上两步完成就可以使用了 1.在xml布局中使用 xmlns:app="http://schemas

Rango的专栏 652
上一篇: 学习笔记快速记录
下一篇: 属性动画、事件分发和自定义控件
xiongmaozhijin
博客等级 码龄15年 4粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值