android开关按钮

时间:2023-01-03 07:14:27


刚开始接触开关样式的按钮是在IOS系统上面,它的切换以及滑动十分帅气,深入人心。

所谓的开关按钮,就是只有2个状态:on和off,下图就是系统IOS 7上开关按钮效果。

起初我在android上我只会使用CheckBox去满足对应的功能。后来,查看开发文档发现,android也有了自己的原生态开关控件,并且在4.0版本中又优化加入了新的类似控件--Switch控件,以及使用起来十分简单的ToggleButton,可是它们只是带有切换效果,而不带有滑动切换效果,并且Switch控件只支持高版本的系统,对于2.3就不支持。所以,要想看如何实现滑动切换的效果,必须了解这些控件的实现方式。下面,让我们查看下android开发文档,看看这些是如何实现使用的。


注意:本文中涉及到自定义控件 并自定义配置属性declare-styleable,

如果你对于自定义控件的自定义配置属性还不是很了解可以看:​​android 自定义控件 使用declare-styleable进行配置属性(源码角度)​​


查看查看开发文档:

CompoundButton

extends Button
implements Checkable


java.lang.Object

android.view.View


android.widget.TextView



android.widget.Button




android.widget.CompoundButton

 

Known Direct Subclasses

CheckBox,RadioButton,Switch,ToggleButton

以上4类都是开关类型切换的控件,它们的父类都是CompoundButton。



 它对应的方法和类有:


点击选择监听接口。

Nested Classes

interface

CompoundButton.OnCheckedChangeListener

Interface definition for a callback to be invoked when the checked state of a compound button changed.


返回左右填充的VIEW,加上间隔

Public Methods

int

​getCompoundPaddingLeft​​()Returns the left padding of the view, plus space for the left Drawable if any.

int

​getCompoundPaddingRight​​()Returns the right padding of the view, plus space for the right Drawable if any.


boolean:是否被选中。

boolean

​isChecked​​()


设置Button的Drawable属性

void

​setButtonDrawable​​(int resid)Set the background to a given Drawable, identified by its resource id.

 

设置是否选中

void

​setChecked​​(boolean checked)Changes the checked state of this button.

 

改变当前的状态,true-->false  ;false-->true

void

​toggle​​()Change the checked state of the view to the inverse of its current state


控件全局 绘制

void

​onDraw​​​(​​Canvas​​ canvas)Implement this to do your drawing.

 protected void onDraw (Canvas canvas)

         实现你自己的绘制。

                   参数

                            canvas    在画布上绘制背景

   protected boolean verifyDrawable (Drawable who)

         如果你的视图子类显示他自己的可视化对象,他将要重写此方法并且为了显示可绘制返回true。此操作允许进行绘制时有动画效果。

  确认当重写从方法时,需调用父类相应方法。

                   参数

                            who         需判断的可绘制对象(Drawable)。如果是你要显示的对象,返回True,否则返回调用父类的结果。

                   返回值

                           boolean 如果可绘制对象(Drawable)已经在视图中显示,返回True否则返回false。并且此处不允许使用动画。



下面让我们来看看如何实现这个效果把:


一.使用ToggleButton控件实现:

使用ToggleButton控件十分方便,你可以看作他为一个CheckBox,只用设置它的button、background等几个属性即可。

首先:res--创建drawable文件夹 -- 创建switch_btn.xml资源文件--作以下配置




<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/ios7_switch_on" />
<item android:drawable="@drawable/ios7_switch_off" />
</selector>

其中:android:state_checked="true" 表示选中on时候的,效果为:android:drawable="@drawable/ios7_switch_on" 


之后在布局文件中写控件:



<ToggleButton
android:id="@+id/mTogBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@android:color/transparent"
android:button="@drawable/toggle_btn"
android:checked="false"
android:text=""
android:textOff=""
android:textOn="" />

这里的    

android:textOn=""   表示:选中情况下显示的文本

android:textOff=""   表示:未选中情况下显示的文本

android:checked="false"  表示:初始化时候,默认是未选中的

android:button="@drawable/toggle_btn"  表示:button样式

android:background="@android:color/transparent"  表示:背景,这里不用它的默认背景,所以设置为透明

之后在主程序中实例化,并设置checked点击监听



ToggleButton mTogBtn = (ToggleButton) findViewById(R.id.mTogBtn); // 获取到控件
mTogBtn.setOnCheckedChangeListener(new

@Override
public void onCheckedChanged(CompoundButton buttonView,boolean
// TODO Auto-generated method stub
if(isChecked){
//选中
else{
//未选中
}
}
});// 添加监听事件


这样ToggleButton的开关切换就轻松实现了。


二.重写CompoundButton控件实现带滑动效果的开关按钮:

CompuundButton的实现可能会显得相对繁琐些,主要是考虑状态是否已经选中等情况的文字显示。

CompuundButton,在布局的动画和显示上调用onDraw(Canvas canvas)重画既可以,如果想要加入拖动属性,那么在该VIEW内重写触摸事件onTouchEvent(MotionEvent ev)在里面判断拖动距离,之后根据拖动情况判断开关是on还是off。

CompoundButton,所以里面的监听方法,setChecked等方法都是自带的,继承下来写操作就可以了,不用自己在去加判断什么的属性了。

CompoundButton的SwitchButton是使用自定义配置的,所以如果不了解自定义配置的可以看以下文章:​​android 自定义控件 使用declare-styleable进行配置属性(源码角度)​​

    具体的这边不贴代码了,可以查看DEMO里面的,都有注释。


三.重写CheckBox控件实现带滑动效果的开关按钮:

CheckBox其实就是继承CompoundButton控件的,只是重构CheckBox会比CompoundButton方便好多,里面的很多方法都是写好的,只要自己去判断触摸事件onTouchEvent(MotionEvent ev),以及onDraw(Canvas canvas)重画就可以。这里DEMO中使用到的是第3放库内的一个控件,大致操作和上面其实大同小异。


四.重写View实现带滑动效果的开关按钮:

   众所周知,以上所有的控件都是继承了View这个父类,所以,如果你用View去操作的话,就没有自带方法的限制,可是要满足你要 实现的SwitchButton效果,你必须自己写开关状态监听接口,并且自己写setChecked方法实现同等的效果。在优化方面要自己多加细心考虑。其他操作与以上控件的重构大同小异。

   注意:由于状态切换等,enabled属性改变等,是你自定义的方法内的话,你必须自己去调用invalidate();方法,去让UI判断是否有更改并做出相应的变化。

例如:

@Override
public void setEnabled(boolean
// TODO Auto-generated method stub
mEnabled = enabled;
2;
"enabled",enabled ? "true": "false");
super.setEnabled(enabled);
invalidate();
}

/** 自动判断切换至相反的属性 : true -->false ;false -->true */
public void
setChecked(!mSwitchOn);
}

/** 设置选中的状态(选中:true 非选中: false) */
public void setChecked(boolean
mSwitchOn = checked;
invalidate();
}


还有,你如果是自定义的VIEW,你在里面设置了enabled属性,你必须在onTouchEvent(MotionEvent event)触摸操作的时候判断你所设置的enabled属性是否为true,是的话就可以相应点击事件,否则的话你要屏蔽掉点击事件。因为你自定义的view中的enabled属性并不知道他设定后会达到什么效果,这些都是要注意的点。

还有就是要设置接口监听状态变化:


/** 
* 设置 switch 状态监听
* */
public void
switchListener = listener;
}
/**
* switch 开关监听接口
* */
public interface
public void onSwitchChange(SlideSwitchView switchView, boolean
}

有的人可能会希望有SwitchButton在enabled设置为false的时候,SwitchButton不能点击且要改变颜色,使他看过去是不能点击的。你可以进行如下操作(在学习别的人代码中得到的提示,学以致用):


先初始化透明度:255为不透明



/** 最大透明度,就是不透明 */
private final int MAX_ALPHA = 255;
/** 当前透明度,这里主要用于如果控件的enable属性为false时候设置半透明 ,即不可以点击 */
private int
之后重写setEnabled方法,通过这个方法判断enabled属性值




@Override
public void setEnabled(boolean
// TODO Auto-generated method stub
mEnabled = enabled;
2;
super.setEnabled(enabled);
invalidate();
}

如果改变了enabled属性,系统便会查看UI是否需要变化,之后在UI方法onDraw(Canvas canvas)中调用:


android.graphics.Canvas.saveLayerAlpha(RectF bounds, int alpha, int

方法,其中的第2个属性alpha就是透明度,之后便可以实现相应的效果。




由于目前对于重写VIEW的onDraw方法的了解不是很深入,所以这里的DEMO中的几个方法都是查看网络之后加上自己的优化和注释演变过来,等这一块深入了后在重写写一篇关于这个的感受和使用说明。由于可能理解不是很深刻,如果有什么不足之处可以提出,谢谢。


最后让我们来看看效果如何,上图:

 

android开关按钮

                     

android开关按钮



最后上源码DEMO:​​下载地址