自定义View开关按钮
2017-01-12 17:39
573 查看
今天来介绍下如何自定义类似iOS的按钮。
switch.gif
要想自定义View,需要了解自定义View的相关步骤,一般来说自定义View需要实现以下操作:
自定义view步骤
1.自定义属性
根据自定义View中需要用户设置的属性,来构造自定义属性,直接在xml资源文件中的
并在继承View类的
2.初始化构造函数
一般来说,如果自定义View用于在布局文件声明,则必须初始化覆盖基类的两个参数的构造函数;其他带参构造函数,根据需求进行初始化。
在构造函数中通过
3.测量View——onMeasure
4.给定View高宽——setMeasuredDimension
通过
5.绘制View——onDraw
最核心的方法莫过于
6.回调监听
切换按钮的回调,主要体现在开关状态的变化:
7.手势处理
本项目中并未使用onTouchEvent方法处理手势监听,而是覆盖了父类的
作者 @fynn
项目地址 github
switch.gif
要想自定义View,需要了解自定义View的相关步骤,一般来说自定义View需要实现以下操作:
自定义view步骤
自定义切换按钮
1.自定义属性
根据自定义View中需要用户设置的属性,来构造自定义属性,直接在xml资源文件中的
resources标签下声明:
<declare-styleable name="Switch"> <attr name="checked" format="reference|boolean"/> <attr name="switchOnColor" format="reference|color"/> <attr name="switchOffColor" format="reference|color"/> <attr name="spotOnColor" format="reference|color"/> <attr name="spotOffColor" format="reference|color"/> <attr name="spotPadding" format="reference|dimension"/> <attr name="duration" format="reference|integer" /> </declare-styleable>
并在继承View类的
Switch类中声明全局变量:
private int switchOnColor; private int switchOffColor; private int spotOnColor; private int spotOffColor; private int spotPadding; private boolean mChecked; private int duration;
2.初始化构造函数
一般来说,如果自定义View用于在布局文件声明,则必须初始化覆盖基类的两个参数的构造函数;其他带参构造函数,根据需求进行初始化。
在构造函数中通过
obtainStyledAttributes()方法获取用户设置的属性值:
public Switch(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Switch); switchOnColor = a.getColor(R.styleable.Switch_switchOnColor, DEFAULT_SWITCH_ON_COLOR); switchOffColor = a.getColor(R.styleable.Switch_switchOffColor, DEFAULT_SWITCH_OFF_COLOR); spotOnColor = a.getColor(R.styleable.Switch_spotOnColor, DEFAULT_SPOT_ON_COLOR); spotOffColor = a.getColor(R.styleable.Switch_spotOffColor, DEFAULT_SPOT_OFF_COLOR); spotPadding = a.getDimensionPixelSize(R.styleable.Switch_spotPadding, dp2px(DEFAULT_SPOT_PADDING)); duration = a.getInteger(R.styleable.Switch_duration, ANIMATION_DURATION); mChecked = a.getBoolean(R.styleable.Switch_checked, false); a.recycle(); state = mChecked ? State.SWITCH_ON : State.SWITCH_OFF; setClickable(true); }
3.测量View——onMeasure
onMeasure方法是决定自定义View布局大小的关键,可通过
MeasureSpec获取父布局分配给子布局的大小及布局模式。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); int width = dp2px(DEFAULT_WIDTH) + getPaddingLeft() + getPaddingRight(); int height = dp2px(DEFAULT_HEIGHT) + getPaddingTop() + getPaddingBottom(); if (widthSpecMode != MeasureSpec.AT_MOST) { width = Math.max(width, widthSpecSize); } if (heightSpecMode != MeasureSpec.AT_MOST) { height = Math.max(height, heightSpecSize); } setMeasuredDimension(width, height); }
4.给定View高宽——setMeasuredDimension
通过
setMeasuredDimension方法设置自定义布局想要的View大小。代码如上所示。
5.绘制View——onDraw
最核心的方法莫过于
onDraw了,
onDraw是绘制View的关键,结合
ValueAnimator、
ObjectAnimator等可实现View的动画效果。
private void animateToCheckedState() { valueAnimator = ValueAnimator.ofFloat(0, 1); valueAnimator.setDuration(duration); valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { currentPos = (float) animation.getAnimatedValue(); invalidate(); } }); valueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); isMoving = true; } @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); isMoving = false; } }); if (!valueAnimator.isRunning()) { valueAnimator.start(); currentPos = 0; } }
6.回调监听
切换按钮的回调,主要体现在开关状态的变化:
public interface OnCheckedChangeListener { /** * Called when the checked state of a switch has changed. * * @param s The switch whose state has changed. * @param isChecked The new checked state of switch. */ void onCheckedChanged(Switch s, boolean isChecked); }
7.手势处理
本项目中并未使用onTouchEvent方法处理手势监听,而是覆盖了父类的
performClick方法,同时保证了
OnClickListener的生效。
@Override public boolean performClick() { toggle(); final boolean handled = super.performClick(); if (!handled) { // View only makes a sound effect if the onClickListener was // called, so we'll need to make one here instead. playSoundEffect(SoundEffectConstants.CLICK); } return handled; }
作者 @fynn
项目地址 github
相关文章推荐
- 自定义view实现开关按钮并监听(有滑动效果)
- [Android开发] 自定义View之重写View非常简单实现开关按钮SwitchView
- 自定义View之开关按钮:SwitchButton
- 自定义View(三) switch开关按钮 ViewDragHelper的使用初级
- Android自定义View实现开关按钮
- 自定义view_开关按钮
- Android自定义View实现开关按钮
- Android自定义View——开关按钮SwitchButton
- Android自定义View----开关按钮
- Android简易实战教程--第二十七话《自定义View入门案例之开关按钮详细分析》
- Android简易实战教程--第二十七话《自定义View入门案例之开关按钮详细分析》
- Android自定义View实现拖动选择按钮
- C#自定义开关按钮控件--附带第一个私活项目截图
- Android 自定义实现switch开关按钮
- Android自定义View示例(二)—滑动开关
- 自定义searchview的编辑框,搜索按钮,删除按钮,光标等
- 自定义View实战--实现一个清新美观的加载按钮
- 文件浏览器 + 优酷菜单 + 下拉菜单 + 自定义开关按钮
- IOS自定义UIAlertView样式,实现可替换背景和按钮
- Android自定义View-------IOS风格的滑动开关