热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android实现类似ios滑动按钮

这篇文章主要为大家详细介绍了Android实现类似ios滑动按钮,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

IOS的滑动按钮菜单在UI设计里面绝对堪称一绝,在学习了Android的自定义view后,我萌生了模仿它的想法。

实现上面的模拟需要自定义一个View;

1)、在View的OnDraw里画出圆角矩形,分别为灰色圆角矩形,红色圆角矩形,和绿色圆角矩形。然后计算相应的位置。

2)、本例中的宽高比为1:0.65,内部红色矩形尺寸为外部矩形尺寸0.9,内部的圆的半径为外部高的0.45倍。按照这个比例计算相应的坐标。

3)、本例中的动画是用ValueAnimation实现的,具体实现在下部代码中。

4)、本例中的透明度实现方法和运动动画一样。

5)、自定义View为外部提供了读取和修改内部状态的接口。

具体代码如下,

1、界面的XML代码:

<&#63;xml version="1.0" encoding="utf-8"&#63;>

 
  
  
 

2、实现自定义view的java代码: 

package com.example.app_switchbutton;
 
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RadioButton;
 
/**
 * Created by 尽途 on 2017/4/26.
 */
 
public class switchbutton extends View {
  private int widthSize;
  private int heightSize;
  private boolean isOn=false;
  private float WhiteRoundRect_width,WhiteRoundRect_height;
  private float Circle_X,Circle_Y,WhiteRoundRect_X,WhiteRoundRect_Y;
  private float Radius;
  private float currentValue;
  private int currentAlphaofGreen,currentAlphaofGray;
  public switchbutton(Context context){
    super(context);
  }
  public switchbutton(Context context, AttributeSet attributeSet){
    super(context,attributeSet);
    setLayerType(LAYER_TYPE_SOFTWARE,null);
    initData();
  }
 
  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    widthSize=MeasureSpec.getSize(widthMeasureSpec);
    heightSize=(int)(widthSize*0.65f);
    setMeasuredDimension(widthSize,heightSize);
    initData();
  }
  void initData(){
    if (isOn){
      currentValue=widthSize-0.5f*heightSize;
      currentAlphaofGreen=255;
      currentAlphaofGray=0;
    }
    else {
      currentValue=0.5f*heightSize;
      currentAlphaofGreen=0;
      currentAlphaofGray=255;
    }
  }
 
  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
  }
 
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (isOn){
      DrawBackGreenRoundRect(canvas);
      DrawCircle(canvas);
    }
    else {
      DrawBackGrayRoundRect(canvas);
      DrawBackWhiteRoundRect(canvas);
      DrawCircle(canvas);
    }
  }
  private void DrawBackGrayRoundRect(Canvas canvas){
    Paint paint0=new Paint();
    paint0.setStyle(Paint.Style.FILL);
    paint0.setColor(Color.GRAY);
    paint0.setAntiAlias(true);
    paint0.setAlpha(currentAlphaofGray);
    RectF roundRect=new RectF(0,0,widthSize,heightSize);
    canvas.drawRoundRect(roundRect,heightSize*0.5f,heightSize*0.5f,paint0);
  }
  private void DrawBackGreenRoundRect(Canvas canvas){
    Paint paint1=new Paint();
    paint1.setStyle(Paint.Style.FILL);
    paint1.setColor(Color.GREEN);
    paint1.setAntiAlias(true);
    paint1.setAlpha(currentAlphaofGreen);
    RectF roundRect=new RectF(0,0,widthSize,heightSize);
    canvas.drawRoundRect(roundRect,heightSize*0.5f,heightSize*0.5f,paint1);
  }
  private void DrawCircle(Canvas canvas){
    Circle_Y=heightSize*0.5f;
    Radius=heightSize*0.45f;
    Paint paint2=new Paint();
    paint2.setStyle(Paint.Style.FILL);
    paint2.setColor(Color.WHITE);
    paint2.setAntiAlias(true);
    canvas.drawCircle(currentValue,Circle_Y,Radius,paint2);
  }
  private void DrawBackWhiteRoundRect(Canvas canvas){
    Paint paint3=new Paint();
    paint3.setStyle(Paint.Style.FILL);
    paint3.setColor(Color.RED);
    paint3.setAntiAlias(true);
    paint3.setAlpha(currentAlphaofGray);
    WhiteRoundRect_X=heightSize*0.05f;
    WhiteRoundRect_Y=heightSize*0.05f;
    WhiteRoundRect_width=widthSize-0.05f*heightSize;
    WhiteRoundRect_height=heightSize*0.95f;
    RectF rectf=new RectF(WhiteRoundRect_X,WhiteRoundRect_Y,WhiteRoundRect_width,WhiteRoundRect_height);
    canvas.drawRoundRect(rectf,WhiteRoundRect_height*0.5f,WhiteRoundRect_height*0.5f,paint3);
  }
 
  /**
   * 添加了过渡值动画,实现了平缓运动
   * @param startValue
   * @param endValue
   */
  private void setAnimation(float startValue,float endValue){
    ValueAnimator valueAnimator=ValueAnimator.ofFloat(startValue,endValue);
    valueAnimator.setDuration(1500);
    valueAnimator.setTarget(currentValue);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        currentValue=(float)animation.getAnimatedValue();
        invalidate();
      }
    });
    valueAnimator.start();
  }
  private void setAlphaAnimationofGray(int startValue,int endValue){
    ValueAnimator valueAnimator=ValueAnimator.ofInt(startValue,endValue);
    valueAnimator.setDuration(1500);
    valueAnimator.setTarget(currentAlphaofGray);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        currentAlphaofGray=(int)animation.getAnimatedValue();
        invalidate();
      }
    });
    valueAnimator.start();
  }
  private void setAlphaAnimationofGreen(int startValue,int endValue){
    ValueAnimator valueAnimator=ValueAnimator.ofInt(startValue,endValue);
    valueAnimator.setDuration(1500);
    valueAnimator.setTarget(currentAlphaofGreen);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        currentAlphaofGreen=(int)animation.getAnimatedValue();
        invalidate();
      }
    });
    valueAnimator.start();
  }
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()){
      case MotionEvent.ACTION_DOWN:
        return true;
      case MotionEvent.ACTION_MOVE:
        return false;
      case MotionEvent.ACTION_UP:
        isOn=!isOn;
        invalidate();
        break;
      default:
        break;
    }
    if (isOn){
      float startCircle_X=0.5f*heightSize;
      float endCircle_X=widthSize-0.5f*heightSize;
      setAnimation(startCircle_X,endCircle_X);
      setAlphaAnimationofGray(255,0);
      setAlphaAnimationofGreen(0,255);
    }else {
      float startCircle_X=widthSize-0.5f*heightSize;
      float endCircle_X=heightSize*0.5f;
      setAnimation(startCircle_X,endCircle_X);
      setAlphaAnimationofGray(0,255);
      setAlphaAnimationofGreen(255,0);
 
    }
    return super.onTouchEvent(event);
  }
  public void writeSwitchButtonState(boolean isOn){
    this.isOn=isOn;
  }
  public boolean readSwitchButtonState(){
    return isOn;
  }
}

模仿的不是很到位,请大家见谅。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 默认情况下,Git 使用 Nano 编辑器进行提交信息的编辑,但如果您更喜欢使用 Vim,可以通过简单的配置更改来实现这一变化。本文将指导您如何通过修改全局配置文件来设置 Vim 作为默认的 Git 提交编辑器。 ... [详细]
  • 吴石访谈:腾讯安全科恩实验室如何引领物联网安全研究
    腾讯安全科恩实验室曾两次成功破解特斯拉自动驾驶系统,并远程控制汽车,展示了其在汽车安全领域的强大实力。近日,该实验室负责人吴石接受了InfoQ的专访,详细介绍了团队未来的重点方向——物联网安全。 ... [详细]
  • 在Notepad++中配置Markdown语法高亮及实时预览功能
    本文详细介绍了如何在Notepad++中配置Markdown语法高亮和实时预览功能,包括必要的插件安装和设置步骤。 ... [详细]
  • 探讨如何在映射文件中处理重复的属性字段,以避免数据操作时出现错误。 ... [详细]
  • Fiddler 安装与配置指南
    本文详细介绍了Fiddler的安装步骤及配置方法,旨在帮助用户顺利抓取用户Token。文章还涵盖了一些常见问题的解决方案,以确保安装过程顺利。 ... [详细]
  • 网络流24题——试题库问题
    题目描述:假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算 ... [详细]
  • Android 中的布局方式之线性布局
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 处理Android EditText中数字输入与parseInt方法
    本文探讨了如何在Android应用中从EditText组件安全地获取并解析用户输入的数字,特别是用于设置端口号的情况。通过示例代码和异常处理策略,展示了有效的方法来避免因非法输入导致的应用崩溃。 ... [详细]
  • 本文探讨了程序员这一职业的本质,认为他们是专注于问题解决的专业人士。文章深入分析了他们的日常工作状态、个人品质以及面对挑战时的态度,强调了编程不仅是一项技术活动,更是个人成长和精神修炼的过程。 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 使用TabActivity实现Android顶部选项卡功能
    本文介绍如何通过继承TabActivity来创建Android应用中的顶部选项卡。通过简单的步骤,您可以轻松地添加多个选项卡,并实现基本的界面切换功能。 ... [详细]
  • 本文详细介绍了C++中的构造函数,包括其定义、特点以及如何通过构造函数进行对象的初始化。此外,还探讨了转换构造函数的概念及其在不同情境下的应用,以及如何避免不必要的隐式类型转换。 ... [详细]
  • Android与JUnit集成测试实践
    本文探讨了如何在Android项目中集成JUnit进行单元测试,并详细介绍了修改AndroidManifest.xml文件以支持测试的方法。 ... [详细]
  • 在尝试使用 Android 发送 SOAP 请求时遇到错误,服务器返回 '无法处理请求' 的信息,并指出某个值不能为 null。本文探讨了可能的原因及解决方案。 ... [详细]
  • 新浪微博热搜暂停更新;即刻APP回归;Android 11 Beta版发布 | 科技新闻速递
    为您带来最新的科技资讯,涵盖社交媒体动态、软件更新及行业重大事件。CSDN携手您共同关注科技前沿。 ... [详细]
author-avatar
再见看淡_266
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有