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

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

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

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

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

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

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

具体代码如下,

1、界面的XML代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@ id/activity_switch_button"
  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="com.example.app_switchbutton.SwitchButtonActivity">
 
  <com.example.app_switchbutton.switchbutton
    android:id="@ id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true" />
  <com.example.app_switchbutton.switchbutton
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_alignParentBottom="true"/>
 
</RelativeLayout>

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;
  }
}

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

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

Android实现类似ios滑动按钮的更多相关文章

  1. html5 canvas合成海报所遇问题及解决方案总结

    这篇文章主要介绍了html5 canvas合成海报所遇问题及解决方案总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  4. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. ios – containerURLForSecurityApplicationGroupIdentifier:在iPhone和Watch模拟器上给出不同的结果

    我使用默认的XCode模板创建了一个WatchKit应用程序.我向iOSTarget,WatchkitAppTarget和WatchkitAppExtensionTarget添加了应用程序组权利.(这是应用程序组名称:group.com.lombax.fiveminutes)然后,我尝试使用iOSApp和WatchKitExtension访问共享文件夹URL:延期:iOS应用:但是,测试NSURL

  6. ios – Testflight无法安装应用程序

    我有几个测试人员注册了testflight并连接了他们的设备……他们有不同的ios型号……但是所有这些都有同样的问题.当他们从“safari”或“testflight”应用程序本身单击应用程序的安装按钮时……达到约90%并出现错误消息…

  7. ibm-mobilefirst – 在iOS 7.1上获取“无法安装应用程序,因为证书无效”错误

    当我的客户端将他们的设备更新到iOS7.1,然后尝试从AppCenter更新我们的应用程序时,我收到了上述错误.经过一番搜索,我找到了一个类似问题的帖子here.但是后来因为我在客户端使用AppCenter更新应用程序的环境中,我无法使用USB插件并为他们安装应用程序.在发布支持之前,是否有通过AppCenter进行下载的解决方法?

  8. ios – 视图的简单拖放?

    我正在学习iOS,但我找不到如何向UIView添加拖放行为.我试过了:它说“UIView没有可见的接口声明选择器addTarget”此外,我尝试添加平移手势识别器,但不确定这是否是我需要的它被称为,但不知道如何获得事件的坐标.在iOS中注册移动事件回调/拖放操作的标准简单方法是什么?

  9. ios – 什么控制iTunes中iPhone应用程序支持的语言列表?

    什么控制iPhone应用程序的iTunes页面中支持的语言?

  10. ios – 获得APNs响应BadDeviceToken或Unregistered的可能原因是什么?

    我知道设备令牌在某些时候是有效的.用户如何使其设备令牌变坏?从关于“未注册”的文档:Thedevicetokenisinactiveforthespecifiedtopic.这是否意味着应用程序已被删除?.您应该看到四种分发方法:如果您选择AppStore或Enterprise,您将在后面的对话框中看到Xcode将APNS权利更改为生产:如果选择AdHoc或Development,则aps-environment下的文本将是开发,然后应与后端的配置匹配.

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部