下面我将为您详细讲解“Android自定义view仿IOS开关效果”的完整攻略。
简介
本文将介绍如何实现一个仿IOS开关的自定义View,当然,这种开关在Android中早已有其它的替代品,但是通过手动编写开关的代码,了解自定义View的知识,在此基础上进行风格的定制以及不同需求的实现,这是值得一学的。
实现思路
开关主要由背景圆角矩形、白色小球、阴影三部分组成,具体步骤如下:
-
编写自定义View,继承View类。
-
在onMeasure()方法中计算View宽高大小。
-
在onDraw()方法中画出开关的三个部分。
-
在onTouchEvent()方法中监听手势事件,移动白色小球,并刷新View。
-
在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技术站