Android自定义view仿IOS开关效果

yizhihongxing

下面我将为您详细讲解“Android自定义view仿IOS开关效果”的完整攻略。

简介

本文将介绍如何实现一个仿IOS开关的自定义View,当然,这种开关在Android中早已有其它的替代品,但是通过手动编写开关的代码,了解自定义View的知识,在此基础上进行风格的定制以及不同需求的实现,这是值得一学的。

实现思路

开关主要由背景圆角矩形、白色小球、阴影三部分组成,具体步骤如下:

  1. 编写自定义View,继承View类。

  2. 在onMeasure()方法中计算View宽高大小。

  3. 在onDraw()方法中画出开关的三个部分。

  4. 在onTouchEvent()方法中监听手势事件,移动白色小球,并刷新View。

  5. 在performClick()方法中发生点击事件。

代码实现

定义View

首先定义一个CustomSwitchView类,继承View类。

public class CustomSwitchView extends View {
    private final String TAG = CustomSwitchView.class.getSimpleName();
    // 自定义View的宽度和高度
    private int mWidth = 150, mHeight = 70;
    // 默认为关闭状态
    private boolean mIsOn = false;
    // 开关的背景颜色
    private int mBackgroundColor = Color.parseColor("#CCCCCC");
    // 开关的圆角半径
    private float mRadius = 35;
    // 开关白色按钮的半径
    private float mButtonRadius = mHeight / 2 - 5;
    // 开关白色按钮的水平坐标
    private float mButtonX;
    // 开关白色按钮的最左边和最右边的坐标,用于限制按钮的移动范围
    private float mButtonLeft, mButtonRight;
    // 开关的状态改变事件监听器
    private OnSwitchStateChangedListener mOnSwitchStateChangedListener;

    public CustomSwitchView(Context context) {
        super(context);
    }

    public CustomSwitchView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomSwitchView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    // 初始化方法,计算一些参数值
    private void init() {
        mWidth = getWidth();
        mHeight = getHeight();
        mRadius = mHeight / 2;
        mButtonRadius = mHeight / 2 - 5;
        mButtonLeft = mButtonRadius + 5;
        mButtonRight = mWidth - mButtonRadius - 5;
        mButtonX = mIsOn ? mButtonRight : mButtonLeft;
    }

    // 绘制View图形
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        init();

        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setAntiAlias(true);

        // 画背景和阴影
        RectF rect = new RectF(0, 0, mWidth, mHeight);
        paint.setColor(mBackgroundColor);
        paint.setShadowLayer(3f, 3f, 3f, 0x7f000000);
        canvas.drawRoundRect(rect, mRadius, mRadius, paint);

        // 画开关白色按钮
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(mButtonX, mRadius, mButtonRadius, paint);
    }

    // 重写onTouchEvent方法来监听手势事件
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                performClick();
            case MotionEvent.ACTION_MOVE:
                float x = event.getX();
                if (x < mButtonLeft) {
                    mButtonX = mButtonLeft;
                } else if (x > mButtonRight) {
                    mButtonX = mButtonRight;
                } else {
                    mButtonX = x;
                }
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                float center = (mButtonLeft + mButtonRight) / 2;
                if (mButtonX >= center) {
                    mButtonX = mButtonRight;
                } else {
                    mButtonX = mButtonLeft;
                }
                mIsOn = (mButtonX == mButtonRight);
                if (mOnSwitchStateChangedListener != null) {
                    mOnSwitchStateChangedListener.onStateChanged(mIsOn);
                }
                invalidate();
                break;
            default:
        }
        return true;
    }

    // 重写performClick方法,发生点击事件
    @Override
    public boolean performClick() {
        super.performClick();
        return true;
    }

    // 设置开关的状态改变事件监听器
    public void setOnSwitchStateChangedListener(OnSwitchStateChangedListener listener) {
        this.mOnSwitchStateChangedListener = listener;
    }

    // 开关状态改变事件监听器
    public interface OnSwitchStateChangedListener {
        void onStateChanged(boolean isOn);
    }
}

在xml布局文件中使用View

在xml布局文件中使用自定义控件,设置控件的宽高大小即可:

<com.xxx.xxx.CustomSwitchView
    android:id="@+id/switchView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    android:layout_gravity="center_horizontal"
    />

监听开关状态改变事件

我们可以通过实现OnSwitchStateChangedListener接口,监听开关状态的改变事件。

CustomSwitchView switchView = findViewById(R.id.switchView);
switchView.setOnSwitchStateChangedListener(new CustomSwitchView.OnSwitchStateChangedListener() {
    @Override
    public void onStateChanged(boolean isOn) {
        if (isOn) {
            // 开关打开
        } else {
            // 开关关闭
        }
    }
});

示例说明

示例一:修改开关背景颜色

在CustomSwitchView类中定义一个setBackgroundColor()方法,允许外部修改开关的背景颜色。

public void setBackgroundColor(int color) {
    mBackgroundColor = color;
    invalidate();
}

在Activity中通过调用switchView.setBackgroundColor()方法修改开关背景颜色。

CustomSwitchView switchView = findViewById(R.id.switchView);
switchView.setBackgroundColor(Color.parseColor("#FF4081")); // 修改背景色为深粉色

示例二:修改开关初始化状态

在CustomSwitchView类中定义一个setSwitchStatus()方法,允许外部修改开关的初始化状态。

public void setSwitchStatus(boolean isOn) {
    mIsOn = isOn;
    mButtonX = mIsOn ? mButtonRight : mButtonLeft;
    invalidate();
}

在Activity中通过调用switchView.setSwitchStatus()方法修改开关的初始化状态。

CustomSwitchView switchView = findViewById(R.id.switchView);
switchView.setSwitchStatus(true); // 初始状态为开启

总结

在本文中,我们实现了一个仿IOS开关的自定义View。通过手写代码实现一个比较简单的自定义View是值得推荐的一种学习方式。

完整代码请见github项目:https://github.com/wanglu1209/CustomSwitchView

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android自定义view仿IOS开关效果 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • python递归&迭代方法实现链表反转

    接下来我将详细讲解如何使用Python的递归和迭代方法实现链表的反转。 什么是链表反转 链表反转(reverse a linked list)指的是将链表中的所有节点的指针方向都倒转,即原来指向下一个节点的指针变为指向前一个节点,这样可以让链表的尾部变为头部,实现链表的逆序。 实现方法 链表反转可以使用递归和迭代两种方法进行实现。 递归方法 递归反转链表的思…

    other 2023年6月27日
    00
  • 使用Spring Boot Mybatis 搞反向工程的步骤

    使用Spring Boot和Mybatis进行反向工程是一个非常方便的方法,通过几个简单的步骤可以自动生成数据库操作的代码,这里我详细讲解一下具体的步骤。 1. 引入依赖 首先,需要在Maven或Gradle中添加对Spring Boot和Mybatis的依赖。例如,在Maven中可以如下添加: <dependencies> <depend…

    other 2023年6月27日
    00
  • iOS自定义日期选择器

    iOS自定义日期选择器是指开发者可以在iOS应用程序中使用自行编写的日期选择器而非使用系统提供的UIDatePicker。 下面是关于自定义日期选择器的完整攻略: 一、设计思路 1.确定选择器的外观和交互方式2.实现日期选择器的布局3.实现日期选择器的逻辑功能 二、外观和交互方式 在设计日期选择器的外观和交互方式时,需要考虑用户体验和应用程序的主题。 可以选…

    other 2023年6月26日
    00
  • 提高Vector容器的删除效率

    提高Vector容器的删除效率 Vector是C++ STL中最常用的容器之一,它能够动态地增加或缩减数组的大小。然而,删除Vector容器中的元素可能会导致性能问题,特别是当Vector中包含大量元素时。在本文中,我们将介绍如何提高Vector容器的删除效率。 Vector容器的删除操作 Vector容器的删除操作分为两类:删除单个元素和删除一段连续的元素…

    其他 2023年3月28日
    00
  • java各种类型对象占用内存情况分析

    Java各种类型对象占用内存情况分析攻略 在Java中,不同类型的对象在内存中占用的空间大小是不同的。了解这些对象的内存占用情况对于优化内存使用和性能调优非常重要。本攻略将详细讲解Java中各种类型对象的内存占用情况,并提供两个示例说明。 1. 基本数据类型 Java的基本数据类型在内存中占用的空间大小是固定的,不受对象的影响。以下是常见的基本数据类型及其占…

    other 2023年8月2日
    00
  • Android内存优化杂谈

    Android内存优化杂谈攻略 1. 了解内存管理 在进行Android内存优化之前,首先需要了解Android的内存管理机制。Android系统使用Java虚拟机(JVM)来运行应用程序,而JVM使用垃圾回收机制来管理内存。了解内存管理机制可以帮助我们更好地优化内存使用。 2. 使用内存分析工具 使用内存分析工具可以帮助我们找出内存泄漏和内存占用过高的问题…

    other 2023年8月1日
    00
  • PHP句法规则详解 入门学习

    当涉及到PHP句法规则的入门学习时,以下是一个完整的攻略,其中包含两个示例说明。 基本语法 PHP是一种服务器端脚本语言,用于开发动态网页和Web应用程序。以下是一些PHP的基本语法规则: PHP代码通常包含在<?php和?>标签之间。 PHP语句以分号;结尾。 PHP对大小写不敏感,但建议使用小写字母。 以下是一个示例,展示了一个简单的PHP程…

    other 2023年8月10日
    00
  • shell实现同时操作多个服务器:服务器批量管理

    Shell实现同时操作多个服务器: 服务器批量管理 简介 服务器的数量随着公司的发展和业务的扩大日渐增多,对于运维人员而言,服务器的管理和维护是一个重要的任务,而批量管理服务器是大大减少管理时间和提高工作效率的一个好方法。本文介绍如何使用Shell脚本实现同时操作多个服务器的批量管理。 环境准备 在使用Shell脚本批量管理服务器之前,需要确保目标服务器与操…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部