SwitchButton開關按鈕的多種實現方式

源碼下載:http://download.csdn.net/download/a876434758/8751487




  • 剛開始接觸開關樣式的按鈕是在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資源文件--作以下配置

 

1.<?xml version="1.0" encoding="utf-8"?>
2.<selector
4.<item android:state_checked="true" android:drawable="@drawable/ios7_switch_on" />
5.<item android:drawable="@drawable/ios7_switch_off" />
6.</selector>
其中:android:state_checked="true" 表示選中on時候的,效果爲:android:drawable="@drawable/ios7_switch_on"

 

反之就是未選中off情況下的效果:android:drawable="@drawable/ios7_switch_off"

之後在佈局文件中寫控件:

 

01.<ToggleButton
02.android:id="@+id/mTogBtn"
03.android:layout_width="wrap_content"
04.android:layout_height="wrap_content"
05.android:layout_gravity="center_horizontal"
06.android:background="@android:color/transparent"
07.android:button="@drawable/toggle_btn"
08.android:checked="false"
09.android:text=""
10.android:textOff=""
11.android:textOn="" />
這裏的

 

android:textOn="" 表示:選中情況下顯示的文本

android:textOff="" 表示:未選中情況下顯示的文本

android:checked="false" 表示:初始化時候,默認是未選中的

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

android:background="@android:color/transparent" 表示:背景,這裏不用它的默認背景,所以設置爲透明

之後在主程序中實例化,並設置checked點擊監聽

 

01.ToggleButton mTogBtn = (ToggleButton) findViewById(R.id.mTogBtn); // 獲取到控件
02.mTogBtn.setOnCheckedChangeListener(new OnCheckedChangeListener() {
03. 
04.@Override
05.public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
06.// TODO Auto-generated method stub
07.if(isChecked){
08.//選中
09.}else{
10.//未選中
11.}
12.}
13.});// 添加監聽事件
這樣ToggleButton的開關切換就輕鬆實現了。

二.重寫CompoundButton控件實現帶滑動效果的開關按鈕:

重寫CompuundButton的實現可能會顯得相對繁瑣些,主要是考慮狀態是否已經選中等情況的文字顯示。

可以查看官方文檔,之後繼承CompuundButton,在佈局的動畫和顯示上調用onDraw(Canvas canvas)重畫既可以,如果想要加入拖動屬性,那麼在該VIEW內重寫觸摸事件onTouchEvent(MotionEvent ev)在裏面判斷拖動距離,之後根據拖動情況判斷開關是on還是off。

由於繼承的是CompoundButton,所以裏面的監聽方法,setChecked等方法都是自帶的,繼承下來寫操作就可以了,不用自己在去加判斷什麼的屬性了。

由於DEMO中的繼承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判斷是否有更改並做出相應的變化。

例如:

 

01.@Override
02.public void setEnabled(boolean enabled) {
03.// TODO Auto-generated method stub
04.mEnabled = enabled;
05.mAlpha = enabled ? MAX_ALPHA : MAX_ALPHA/2;
06.Log.d("enabled",enabled ? "true": "false");
07.super.setEnabled(enabled);
08.invalidate();
09.}
10. 
11./** 自動判斷切換至相反的屬性 : true -->false ;false -->true */
12.public void toggle() {
13.setChecked(!mSwitchOn);
14.}
15. 
16./** 設置選中的狀態(選中:true   非選中: false) */
17.public void setChecked(boolean checked) {
18.mSwitchOn = checked;
19.invalidate();
20.}
還有,你如果是自定義的VIEW,你在裏面設置了enabled屬性,你必須在onTouchEvent(MotionEvent event)觸摸操作的時候判斷你所設置的enabled屬性是否爲true,是的話就可以相應點擊事件,否則的話你要屏蔽掉點擊事件。因爲你自定義的view中的enabled屬性並不知道他設定後會達到什麼效果,這些都是要注意的點。

 

還有就是要設置接口監聽狀態變化:

 

01./**
02.* 設置 switch 狀態監聽
03.* */
04.public void setOnChangeListener(OnSwitchChangedListener listener) {
05.switchListener = listener;
06.}
07./**
08.* switch 開關監聽接口
09.*  */
10.public interface OnSwitchChangedListener{
11.public void onSwitchChange(SlideSwitchView switchView, boolean isChecked);
12.}

 

有的人可能會希望有SwitchButton在enabled設置爲false的時候,SwitchButton不能點擊且要改變顏色,使他看過去是不能點擊的。你可以進行如下操作(在學習別的人代碼中得到的提示,學以致用):

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

 

1./** 最大透明度,就是不透明 */
2.private final int MAX_ALPHA = 255;
3./** 當前透明度,這裏主要用於如果控件的enable屬性爲false時候設置半透明 ,即不可以點擊 */
4.private int mAlpha = MAX_ALPHA;
之後重寫setEnabled方法,通過這個方法判斷enabled屬性值

 

 

1.@Override
2.public void setEnabled(boolean enabled) {
3.// TODO Auto-generated method stub
4.mEnabled = enabled;
5.mAlpha = enabled ? MAX_ALPHA : MAX_ALPHA/2;
6.super.setEnabled(enabled);
7.invalidate();
8.}
如果改變了enabled屬性,系統便會查看UI是否需要變化,之後在UI方法onDraw(Canvas canvas)中調用:

 

 

1.android.graphics.Canvas.saveLayerAlpha(RectF bounds, int alpha, int saveFlags)
方法,其中的第2個屬性alpha就是透明度,之後便可以實現相應的效果。

 

 

由於目前對於重寫VIEW的onDraw方法的瞭解不是很深入,所以這裏的DEMO中的幾個方法都是查看網絡之後加上自己的優化和註釋演變過來,等這一塊深入了後在重寫寫一篇關於這個的感受和使用說明。由於可能理解不是很深刻,如果有什麼不足之處可以提出,謝謝。

 

最後讓我們來看看效果如何,上圖:

\\

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章