Android 仿苹果IOS6开关按钮
作者:还有星星 发布时间:2023-11-21 15:16:08
标签:android,ios,开关,按钮
先给大家展示下效果图:
不知道大家对效果图感觉怎么样,个人觉还不错,感兴趣的朋友可以参考下实现代码哦。
public class ToggleButton extends View {
private SpringSystem springSystem;
private Spring spring ;
/** */
private float radius;
/** 开启颜色*/
private int onColor = Color.parseColor("#4ebb7f");
/** 关闭颜色*/
private int offBorderColor = Color.parseColor("#dadbda");
/** 灰色带颜色*/
private int offColor = Color.parseColor("#ffffff");
/** 手柄颜色*/
private int spotColor = Color.parseColor("#ffffff");
/** 边框颜色*/
private int borderColor = offBorderColor;
/** 画笔*/
private Paint paint ;
/** 开关状态*/
private boolean toggleOn = false;
/** 边框大小*/
private int borderWidth = 2;
/** 垂直中心*/
private float centerY;
/** 按钮的开始和结束位置*/
private float startX, endX;
/** 手柄X位置的最小和最大值*/
private float spotMinX, spotMaxX;
/**手柄大小 */
private int spotSize ;
/** 手柄X位置*/
private float spotX;
/** 关闭时内部灰色带高度*/
private float offLineWidth;
/** */
private RectF rect = new RectF();
/** 默认使用动画*/
private boolean defaultAnimate = true;
/** 是否默认处于打开状态*/
private boolean isDefaultOn = false;
private OnToggleChanged listener;
private ToggleButton(Context context) {
super(context);
}
public ToggleButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setup(attrs);
}
public ToggleButton(Context context, AttributeSet attrs) {
super(context, attrs);
setup(attrs);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
spring.removeListener(springListener);
}
public void onAttachedToWindow() {
super.onAttachedToWindow();
spring.addListener(springListener);
}
public void setup(AttributeSet attrs) {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Style.FILL);
paint.setStrokeCap(Cap.ROUND);
springSystem = SpringSystem.create();
spring = springSystem.createSpring();
spring.setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(50, 7));
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
toggle(defaultAnimate);
}
});
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ToggleButton);
offBorderColor = typedArray.getColor(R.styleable.ToggleButton_tbOffBorderColor, offBorderColor);
onColor = typedArray.getColor(R.styleable.ToggleButton_tbOnColor, onColor);
spotColor = typedArray.getColor(R.styleable.ToggleButton_tbSpotColor, spotColor);
offColor = typedArray.getColor(R.styleable.ToggleButton_tbOffColor, offColor);
borderWidth = typedArray.getDimensionPixelSize(R.styleable.ToggleButton_tbBorderWidth, borderWidth);
defaultAnimate = typedArray.getBoolean(R.styleable.ToggleButton_tbAnimate, defaultAnimate);
isDefaultOn = typedArray.getBoolean(R.styleable.ToggleButton_tbAsDefaultOn, isDefaultOn);
typedArray.recycle();
borderColor = offBorderColor;
if (isDefaultOn) {
toggleOn();
}
}
public void toggle() {
toggle(true);
}
public void toggle(boolean animate) {
toggleOn = !toggleOn;
takeEffect(animate);
if(listener != null){
listener.onToggle(toggleOn);
}
}
public void toggleOn() {
setToggleOn();
if(listener != null){
listener.onToggle(toggleOn);
}
}
public void toggleOff() {
setToggleOff();
if(listener != null){
listener.onToggle(toggleOn);
}
}
/**
* 设置显示成打开样式,不会触发toggle事件
*/
public void setToggleOn() {
setToggleOn(true);
}
/**
* @param animate asd
*/
public void setToggleOn(boolean animate){
toggleOn = true;
takeEffect(animate);
}
/**
* 设置显示成关闭样式,不会触发toggle事件
*/
public void setToggleOff() {
setToggleOff(true);
}
public void setToggleOff(boolean animate) {
toggleOn = false;
takeEffect(animate);
}
private void takeEffect(boolean animate) {
if(animate){
spring.setEndValue(toggleOn ? 1 : 0);
}else{
//这里没有调用spring,所以spring里的当前值没有变更,这里要设置一下,同步两边的当前值
spring.setCurrentValue(toggleOn ? 1 : 0);
calculateEffect(toggleOn ? 1 : 0);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
Resources r = Resources.getSystem();
if(widthMode == MeasureSpec.UNSPECIFIED || widthMode == MeasureSpec.AT_MOST){
widthSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, r.getDisplayMetrics());
widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
}
if(heightMode == MeasureSpec.UNSPECIFIED || heightSize == MeasureSpec.AT_MOST){
heightSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, r.getDisplayMetrics());
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
final int width = getWidth();
final int height = getHeight();
radius = Math.min(width, height) * 0.5f;
centerY = radius;
startX = radius;
endX = width - radius;
spotMinX = startX + borderWidth;
spotMaxX = endX - borderWidth;
spotSize = height - 4 * borderWidth;
spotX = toggleOn ? spotMaxX : spotMinX;
offLineWidth = 0;
}
SimpleSpringListener springListener = new SimpleSpringListener(){
@Override
public void onSpringUpdate(Spring spring) {
final double value = spring.getCurrentValue();
calculateEffect(value);
}
};
private int clamp(int value, int low, int high) {
return Math.min(Math.max(value, low), high);
}
@Override
public void draw(Canvas canvas) {
//
rect.set(0, 0, getWidth(), getHeight());
paint.setColor(borderColor);
canvas.drawRoundRect(rect, radius, radius, paint);
if(offLineWidth > 0){
final float cy = offLineWidth * 0.5f;
rect.set(spotX - cy, centerY - cy, endX + cy, centerY + cy);
paint.setColor(offColor);
canvas.drawRoundRect(rect, cy, cy, paint);
}
rect.set(spotX - 1 - radius, centerY - radius, spotX + 1.1f + radius, centerY + radius);
paint.setColor(borderColor);
canvas.drawRoundRect(rect, radius, radius, paint);
final float spotR = spotSize * 0.5f;
rect.set(spotX - spotR, centerY - spotR, spotX + spotR, centerY + spotR);
paint.setColor(spotColor);
canvas.drawRoundRect(rect, spotR, spotR, paint);
}
/**
* @param value
*/
private void calculateEffect(final double value) {
final float mapToggleX = (float) SpringUtil.mapValueFromRangeToRange(value, 0, 1, spotMinX, spotMaxX);
spotX = mapToggleX;
float mapOffLineWidth = (float) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, 10, spotSize);
offLineWidth = mapOffLineWidth;
final int fb = Color.blue(onColor);
final int fr = Color.red(onColor);
final int fg = Color.green(onColor);
final int tb = Color.blue(offBorderColor);
final int tr = Color.red(offBorderColor);
final int tg = Color.green(offBorderColor);
int sb = (int) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, fb, tb);
int sr = (int) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, fr, tr);
int sg = (int) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, fg, tg);
sb = clamp(sb, 0, 255);
sr = clamp(sr, 0, 255);
sg = clamp(sg, 0, 255);
borderColor = Color.rgb(sr, sg, sb);
postInvalidate();
}
/**
* @author ThinkPad
*
*/
public interface OnToggleChanged{
/**
* @param on = =
*/
public void onToggle(boolean on);
}
public void setOnToggleChanged(OnToggleChanged onToggleChanged) {
listener = onToggleChanged;
}
public boolean isAnimate() {
return defaultAnimate;
}
public void setAnimate(boolean animate) {
this.defaultAnimate = animate;
}
}
别忘了自定义属性:attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ToggleButton">
<attr name="tbBorderWidth" format="dimension"/>
<attr name="tbOffBorderColor" format="reference|color"/>
<attr name="tbOffColor" format="reference|color"/>
<attr name="tbOnColor" format="reference|color"/>
<attr name="tbSpotColor" format="reference|color"/>
<attr name="tbAnimate" format="reference|boolean"/>
<attr name="tbAsDefaultOn" format="reference|boolean"/>
</declare-styleable>
</resources>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
xmlns:toggle="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
>
<LinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:gravity="center_horizontal"
android:layout_height="wrap_content">
<com.example.ekikousei.view.ToggleButton
android:id="@+id/mToggleButton01"
android:layout_width="54dp"
android:layout_height="30dp">
</com.example.ekikousei.view.ToggleButton>
</LinearLayout>
<LinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:gravity="center_horizontal"
android:layout_height="wrap_content">
<com.example.ekikousei.view.ToggleButton
android:id="@+id/mToggleButton02"
android:layout_width="54dp"
android:layout_height="30dp"
toggle:tbBorderWidth="2dp"
toggle:tbOffBorderColor="#000"
toggle:tbOffColor="#ddd"
toggle:tbOnColor="#f00"
toggle:tbSpotColor="#00f">
</com.example.ekikousei.view.ToggleButton>
</LinearLayout>
</LinearLayout>
Maintivity
public class MainActivity extends Activity {
private ToggleButton mToggleButton01;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToggleButton01 = (ToggleButton) findViewById(R.id.mToggleButton01);
mToggleButton01.setOnToggleChanged(new ToggleButton.OnToggleChanged() {
@Override
public void onToggle(boolean on) {
if (on) {
Toast.makeText(MainActivity.this, "打开", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(MainActivity.this, "默认关闭", Toast.LENGTH_SHORT).show();
}
}
});
}
}
猛戳这里:studio点击下载
以上所述是小编给大家介绍的Android 之仿苹果IOS6开关按钮网站的支持!
来源:http://blog.csdn.net/jky_yihuangxing/article/details/52955923


猜你喜欢
- 一、正则表达式去除代码行号作为开发人员,我们经常从网上复制一些代码,有些时候复制的代码前面是带有行号,如:MyEclipse本身自带有查找替
- 一、依赖注入方式思考:向一个类中传递数据的方式有几种?普通方法(set方法)构造方法思考:依赖注入描述了在容器中建立bean与bean之间依
- 本文实例讲述了散列表的原理与Java实现方法。分享给大家供大家参考,具体如下:概述符号表是一种用于存储键值对(key-value pair)
- 从Java 5开始,Java语言对方法参数支持一种新写法,叫 可变长度参数列表,其语法就是类型后跟...,表示此处接受的参数为0到多个Obj
- 现如今的APP各式各样,同样也带来了各种需求,一个下拉刷新都能玩出花样了,前两天订饭的时候不经意间看到了“百度外卖”的下拉刷新,今天的主题就
- 一.递归方法1.递归就是自己调用本身的方法,前提是有方法。2.递归使用找出递归的规律递归要有出口条件,也就是结束条件3.注意事项递归次数不能
- Redis模糊匹配批量删除操作,使用RedisTemplate操作: public void deleteByPrex(String pre
- 前言在JDK当中给我们提供的各种并发工具当中,比如ReentrantLock等等工具的内部实现,经常会使用到一个工具,这个工具就是LockS
- java.lang.NoSuchMethodException: com.sun.proxy.$Proxy58.list错误解决办法玩web
- 问题原因今天在看集合源码的时候,突然看到接口继承接口,觉得有点差异,以前写代码也就是类继承一个类,实现接口。这样写的多了,突然看到接口继承接
- 前言项目中有需求在APP的Webview中长按图片可以保存。后来就去研究一下该怎么实现,顺便整理了一下。WebView基本配置mWvCont
- 本文实例为大家分享了C#实现打字小游戏的具体代码,供大家参考,具体内容如下using System;using System.Drawing
- 实现了Java web开发账号单一登录的功能,防止同一账号重复登录,后面登录的踢掉前面登录的,使用过滤器Filter实现的。可以先下载项目下
- 1 简介Solace是一个强大的实时性的事件驱动消息队列。本文将介绍如何在Spring中使用,虽然代码使用的是Spring Boot,但并没
- 使用注解来配置Action可以实现零配置,零配置将从基于纯XML的配置转化为基于注解的配置。使用注解,可以在大多数情况下避免使用
- 目标:了解Swagger的作用和概念了解前后端分离在springBoot中集成SwaggerSwagger简介前后端分离VUE+spring
- 前言回老家,实在太无聊,于是乎给自己整了一套台式机配置,总价 1W+,本以为机器到位后可以打打游戏,学学技术打发无聊的时光。但是我早已不是从
- 本文实例讲述了JDBC使用游标实现分页查询的方法。分享给大家供大家参考,具体如下:/*** 一次只从数据库中查询最大maxCount条记录*
- vs2010测试通过,主要思想是由出生日期和当前日期,两个日期计算出年龄(岁、月、天)using System;using System.C
- 前言MyBatis-Plus 是基于 MyBatis 进行封装的一套优秀的持久层框架,它提供了丰富的便捷操作方法和强大的代码生成器,大大简化