搞一个switch控件看了网上的很多都是用的selector去定义thumb 跟 track,这样可以改变它的背景跟小圆点。但没有办法设置文字,源码给了设置文字的方法,也只能设置再小圆点上。所以索性自己用一个View画一下背景跟文字,用动画来模拟一个switch控件。。。本来想搞个背景selector的但是这样没有了动画,感觉有点low。。。

继承自View的switch控件,可以显示文字。

package com.yunhe.myapplication;import android.animation.Animator;
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;/*** Created by wuzhi.peng on 2019/7/4**/
public class CustomSwitch extends View implements ValueAnimator.AnimatorUpdateListener,ValueAnimator.AnimatorListener {//默认的宽高比例private static final float DEFAULT_WIDTH_HEIGHT_PERCENT = 0.38f;//动画最大的比例private static final float ANIMATION_MAX_FRACTION = 1;private int mWidth,mHeight;//画跑道型背景private Paint mBackgroundPain;//画背景上的字private Paint mDisaboleTextPaint;private Paint mEnableTextPaint;//画白色圆点private Paint mSlidePaint;//是否正在动画private boolean isAnimation;private ValueAnimator mValueAnimator;private float mAnimationFraction;private String openText;private String closeText;private int mOpenColor = Color.GREEN;private int mCloseColor = Color.GRAY;private int mCurrentColor = mCloseColor;//监听private OnCheckedChangeListener mCheckedChangeListener;private boolean isChecked;public CustomSwitch(Context context) {this(context,null);}public CustomSwitch(Context context, AttributeSet attrs) {this(context, attrs,0);}public CustomSwitch(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.CustomSwitch);openText = typedArray.getString(R.styleable.CustomSwitch_openText);closeText = typedArray.getString(R.styleable.CustomSwitch_closeText);mOpenColor = typedArray.getColor(R.styleable.CustomSwitch_openColor,Color.GREEN);mCloseColor = typedArray.getColor(R.styleable.CustomSwitch_closeColor,Color.GRAY);mCurrentColor = mCloseColor;typedArray.recycle();init();}private void init(){mBackgroundPain = new Paint();mBackgroundPain.setAntiAlias(true);mBackgroundPain.setDither(true);mBackgroundPain.setColor(Color.GRAY);mDisaboleTextPaint = new Paint();mDisaboleTextPaint.setAntiAlias(true);mDisaboleTextPaint.setDither(true);mDisaboleTextPaint.setStyle(Paint.Style.STROKE);mDisaboleTextPaint.setColor(Color.WHITE);mDisaboleTextPaint.setTextAlign(Paint.Align.CENTER);mEnableTextPaint = new Paint();mEnableTextPaint.setAntiAlias(true);mEnableTextPaint.setDither(true);mEnableTextPaint.setStyle(Paint.Style.STROKE);mEnableTextPaint.setColor(Color.WHITE);mEnableTextPaint.setTextAlign(Paint.Align.CENTER);mSlidePaint = new Paint();mSlidePaint.setColor(Color.WHITE);mSlidePaint.setAntiAlias(true);mSlidePaint.setDither(true);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width =  MeasureSpec.getSize(widthMeasureSpec);int height = (int) (width*DEFAULT_WIDTH_HEIGHT_PERCENT);setMeasuredDimension(width,height);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);mWidth = w;mHeight = h;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);drawBackground(canvas);drawSlide(canvas);}private void drawSlide(Canvas canvas){float distance = mWidth - mHeight;canvas.drawCircle(mHeight/2+distance*mAnimationFraction,mHeight/2,mHeight/3,mSlidePaint);}private void drawBackground(Canvas canvas){Path path = new Path();RectF rectF = new RectF(0,0,mHeight,mHeight);path.arcTo(rectF,90,180);rectF.left = mWidth-mHeight;rectF.right = mWidth;path.arcTo(rectF,270,180);path.close();mBackgroundPain.setColor(mCurrentColor);canvas.drawPath(path,mBackgroundPain);mDisaboleTextPaint.setTextSize(mHeight/2);mEnableTextPaint.setTextSize(mHeight/2);Paint.FontMetrics fontMetrics = mDisaboleTextPaint.getFontMetrics();float top = fontMetrics.top;float bottom = fontMetrics.bottom;int baseLine = (int) (mHeight/2 + (bottom-top)*0.3);if (!"".equals(openText)){//启用mDisaboleTextPaint.setAlpha((int) (255*mAnimationFraction));canvas.drawText(openText,mWidth*0.4f,baseLine,mDisaboleTextPaint);}if (!"".equals(closeText)){//启用mEnableTextPaint.setAlpha((int) (255*(1-mAnimationFraction)));canvas.drawText(closeText,mWidth*0.6f,baseLine,mEnableTextPaint);}}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()){case MotionEvent.ACTION_DOWN:return true;case MotionEvent.ACTION_CANCEL:break;case MotionEvent.ACTION_UP:if (isAnimation){return true;}if (isChecked){startCloseAnimation();isChecked = false;if (mCheckedChangeListener!=null){mCheckedChangeListener.onCheckedChanged(false);}}else {startOpeAnimation();isChecked = true;if (mCheckedChangeListener!=null){mCheckedChangeListener.onCheckedChanged(true);}}return true;}return super.onTouchEvent(event);}private void startOpeAnimation(){mValueAnimator = ValueAnimator.ofFloat(0.0f, ANIMATION_MAX_FRACTION);mValueAnimator.setDuration(500);mValueAnimator.addUpdateListener(this);mValueAnimator.addListener(this);mValueAnimator.start();startColorAnimation();}private void startCloseAnimation(){mValueAnimator = ValueAnimator.ofFloat(ANIMATION_MAX_FRACTION, 0.0f);mValueAnimator.setDuration(500);mValueAnimator.addUpdateListener(this);mValueAnimator.addListener(this);mValueAnimator.start();startColorAnimation();}private void startColorAnimation(){int colorFrom = isChecked?mOpenColor:mCloseColor; //mIsOpen为true则表示要启动关闭的动画int colorTo = isChecked? mCloseColor:mOpenColor;ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);colorAnimation.setDuration(500); // millisecondscolorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animator) {mCurrentColor = (int)animator.getAnimatedValue();}});colorAnimation.start();}//设置监听public void setOnCheckedChangeListener(OnCheckedChangeListener listener){mCheckedChangeListener = listener;}public boolean isChecked() {return isChecked;}public void setChecked(boolean checked) {isChecked = checked;if (isChecked){mCurrentColor = mOpenColor;mAnimationFraction = 1.0f;}else {mCurrentColor = mCloseColor;mAnimationFraction = 0.0f;}invalidate();}@Overridepublic void onAnimationStart(Animator animator) {isAnimation = true;}@Overridepublic void onAnimationEnd(Animator animator) {isAnimation = false;}@Overridepublic void onAnimationCancel(Animator animator) {isAnimation = false;}@Overridepublic void onAnimationRepeat(Animator animator) {isAnimation = true;}@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {mAnimationFraction = (float) valueAnimator.getAnimatedValue();invalidate();}public interface OnCheckedChangeListener{void onCheckedChanged(boolean isChecked);}
}上面是自定义View的源码,比较简单就画了一个背景跟文字,还有一个小白点。 点击的时候做动画。设置了监听,可以监听选中状态。
attrs文件里面
<declare-styleable name="CustomSwitch"><attr name="closeText" format="string" /><attr name="openText" format="string" /><attr name="closeColor" format="color" /><attr name="openColor" format="color" />
</declare-styleable>

添加了几个属性,这个可以自己定义。

xml中的用法

<com.yunhe.myapplication.CustomSwitch
app:closeText="禁用"
app:openText="启用"
app:closeColor="#aaaaaa"
app:openColor="#ff0000"
android:layout_width="200dp"
android:layout_height="wrap_content"
/>
 

自定义Switch背景带文字相关推荐

  1. python生成带背景 带文字 的二维码图片

    2019独角兽企业重金招聘Python工程师标准>>> # -*- coding: UTF-8 -*- from __future__ import unicode_literals ...

  2. OpenCV-Python调整图像对比度和带文字白纸照片背景漂白方法

    一.引言 在前面我们介绍了直方图均衡可以调整图像的对比度,那么还有没有其他方式调整对比度呢?答案是肯定的,今天就来招硬核的. 二.对比度调整的硬核方法 这招硬核方法就是参考灰度图像的阈值处理,我们知道 ...

  3. ArcGIS API for JavaScript 3.24 文字标注的添加和带背景的文字添加

    说明:本人是一个gis小白,由于网上的资料过于专业,当时学习的时候经常看不懂,于是写了一些简单的关于ArcGIS Api for javaScript分享,若该分享中出现错误,希望大家指出,若能帮助到 ...

  4. html文字下加背景图片大全唯美,带文字的励志简约背景图片

    有一些图片虽然简约,但是依然是很励志的,依然是给人传递满满的正能量.下面是由学习啦小编为大家整理的带文字的励志简约背景图片和励志语录,希望你会喜欢! 带文字的励志图片 励志简约背景图片 励志语录 1. ...

  5. C#生成带背景和文字的二维码图片

    /// <summary>         /// 生成带背景和文字的二维码图片         /// </summary>         /// <param na ...

  6. android 自定义 seekbar,Android自定义控件 带文字提示的SeekBar

    封面 1.写在前面 SeekBar控件在开发中还是比较常见的,比如音视频进度.音量调节等,但是原生控件有时还不能满足我们的需求,今天就来学习一下如何自定义SeekBar控件,本文主要实现了一个带文字指 ...

  7. 自定义绘制圆环与实心圆(带文字)

    自定义绘制圆环 package com.cn.myvdun; import android.content.Context; import android.graphics.Canvas; impor ...

  8. 【Android】Android实现自定义带文字和图片的Button

    在Android开发中经常会需要用到带文字和图片的button,下面来讲解一下常用的实现办法. 一.用系统自带的Button实现 最简单的一种办法就是利用系统自带的Button来实现,这种方式代码量最 ...

  9. 【小程序】手动实现switch开关中带文字效果(开关左右文字相同/不同都可以)

    最终效果: 左右文字宽度相同 左右文字宽度不同 左右长度相同 效果:配合wx:show切换 注意:左右长度相同的话可以设置合适的相同的宽度. html: <view class="sw ...

最新文章

  1. 网红“AI大佬”被爆论文剽窃,Jeff Dean都看不下去了
  2. mysql注入式攻击_SQL的注入式攻击方式和避免方法
  3. 了解 WPF 中的路由事件和命令
  4. 2016-08-05
  5. PPRevealSideViewController
  6. 【转载】安卓开发者在使用deepin15.4时可能会遇到的问题
  7. Python开发中收集的一些常用功能Demo
  8. 8.5-Day1T1--Asm.Def 谈笑风生
  9. MSSQL系列之十五 全文索引
  10. 统计学基础知识之统计思维
  11. 实用的latex报告排版模板
  12. linux编译生成动态库、静态库,以及使用
  13. RT-Thread : STM32 系列外设驱动添加指南
  14. Node学习 | Day04 数据库与身份验证(数据库的基本概念、安装并配置MySQL、MySQL的基本使用、在项目中操作MySQL、前后端的身份验证)
  15. MySQL详细安装步骤
  16. h5调用指纹识别_如何玩转指纹解锁H5插件?
  17. C++记录程序运行时间5大方法
  18. 一个简单的马尔可夫过程例子
  19. 机器学习算法——支持向量机SVM5(核函数)
  20. html5手机号输入框,input输入框限制(座机,手机号码)

热门文章

  1. 为什么选择使用 TypeScript ?
  2. 汉字点阵字库的原理与显示
  3. android sendmessage传递对象,android handler sendMessage
  4. AI赋能传统行业:知其然并知其所以然 - 专访平安科技美国研究院院长韩玫
  5. Ettercap中间人攻击截取FTP账号密码
  6. #Python3小练习,随缘更新
  7. Netty事件监听和处理(下)
  8. mysql navicat 设计表_Navicat for MySQL 设计报表版面教程
  9. 犀思云再获“2022年优秀SASE案例”,SaaS反向加速了解一下
  10. java计算机毕业设计至臻阁古董拍卖网源码+数据库+系统+lw文档+mybatis+运行部署