Android自定义view仿IOS开关效果

下面我将为您详细讲解“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日

相关文章

  • sourcetree生成秘钥公钥

    以下是“Sourcetree生成秘钥公钥”的完整攻略: Sourcetree生成秘钥公钥 Sourcetree是一款免费的Git和Mercurial客户端,支持Windows和macOS平台。在使用Sourcetree时,您可能需要生成秘钥公钥,以便在Git服务器上进行身份验证。本攻略将介绍如何在Sourcetree生成秘钥公钥。 步骤1:安装Sourcet…

    other 2023年5月7日
    00
  • 秒懂sqlintersect

    当然,我很乐意为您提供有关“秒懂SQL Intersect”的完整攻略。以下是详细的步骤和两个示例: 1 SQL Intersect SQL Intersect是一种用于比较两个或多个SELECT语句结果的操作符。它返回两个结果集的交集,即两个结果集中都存在的行。 2 SQL Intersect语法 以下是SQLsect的语法: SELECT column1…

    other 2023年5月6日
    00
  • 解决vue-loader加载不上的问题

    首先,在讲解解决vue-loader加载不上的问题的攻略之前,我们需要了解vue-loader的基本概念和用法。vue-loader是Vue.js官方推荐的一个webpack加载器,可以将Vue组件的单文件(含有.vue扩展名的文件)转换成JavaScript模块。由于vue-loader是一个webpack加载器,所以我们在使用vue-loader的时候,…

    other 2023年6月27日
    00
  • ios中延时执行的几种方式比较及汇总

    以下是关于“iOS中延时执行的几种方式比较及汇总”的完整攻略,包括基本概念、常用方法、示例说明和注意事项。 基本概念 在iOS开发中,经常需要延时执行某些代码,例如在用户点击按钮后延时一段时间再执行某个操作。为了实现延时执行,iOS提供了多种方法,开发者可以根据实际需求选择合适的方法。 常用方法 以下是iOS中常用的延时执行方法: performSelect…

    other 2023年5月7日
    00
  • 详解如何使用mock.js实现接口测试的自动化

    当然,下面是关于如何使用mock.js实现接口测试的自动化的完整攻略,包含两个示例说明: 1. 安装和引入mock.js 首先,您需要安装mock.js并将其引入到您的项目中。您可以通过npm进行安装: npm install mockjs –save-dev 然后,在您的测试文件中引入mock.js: import Mock from ‘mockjs’;…

    other 2023年10月17日
    00
  • C字符串函数对应的C++ string操作详解

    C字符串函数对应的C++ string操作详解 本文将详细介绍C字符串函数和C++ string操作之间的对应关系和区别。 strlen和string::length() strlen strlen函数用于计算C风格字符串的长度,返回值是该字符串的字符数,不包括末尾的空字符’\0’。 示例: char str[] = "hello world&qu…

    other 2023年6月20日
    00
  • 深入理解Java三大特性中的多态

    深入理解Java三大特性中的多态 什么是多态 多态是面向对象编程中非常重要的一个概念,它是指同一种行为展现出不同的表现形式或效果。在Java中,多态是基于继承和接口实现的,通常通过父类/接口类型引用指向其子类/实现类对象实现。 当使用这样的引用调用方法时,根据对象的实际类型会调用对应子类/实现类中的方法,这种行为就是多态。 多态的实现 1. 继承实现多态 继…

    other 2023年6月26日
    00
  • 学习笔记之Vuex的用法总结(Vue状态管理)

    学习笔记之Vuex的用法总结(Vue状态管理) 什么是Vuex? Vuex是一个专为Vue.js开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex让我们的状态管理更简单清晰。 Vuex的基本概念 在使用Vuex之前,需要了解一些基本概念。 State(状态) Vuex使用单一状态树,也就是…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部