1. 程式人生 > >SwitchButton 開關按鈕 的多種實現方式 (附原始碼DEMO)

SwitchButton 開關按鈕 的多種實現方式 (附原始碼DEMO)

剛開始接觸開關樣式的按鈕是在IOS系統上面,它的切換以及滑動十分帥氣,深入人心。

所謂的開關按鈕,就是隻有2個狀態:on和off,下圖就是系統IOS 7上開關按鈕效果。

起初我在android上我只會使用CheckBox去滿足對應的功能。後來,檢視開發文件發現,android也有了自己的原生態開關控制元件,並且在4.0版本中又優化加入了新的類似控制元件--Switch控制元件,以及使用起來十分簡單的ToggleButton,可是它們只是帶有切換效果,而不帶有滑動切換效果,並且Switch控制元件只支援高版本的系統,對於2.3就不支援。所以,要想看如何實現滑動切換的效果,必須瞭解這些控制元件的實現方式。下面,讓我們檢視下android開發文件,看看這些是如何實現使用的

注意:本文中涉及到自定義控制元件 並自定義配置屬性declare-styleable,

檢視檢視開發文件:

CompoundButton

以上4類都是開關型別切換的控制元件,它們的父類都是CompoundButton。

 它對應的方法和類有:

點選選擇監聽介面。

Nested Classes

interface

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

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

Public Methods

int

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

int

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

boolean:是否被選中。

設定Button的Drawable屬性

void

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

設定是否選中

void

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

改變當前的狀態,true-->false  ;false-->true

void

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

控制元件全域性 繪製

void

( 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" 

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

之後在佈局檔案中寫控制元件:

<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 OnCheckedChangeListener() {

		@Override
		public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
			// TODO Auto-generated method stub
			if(isChecked){
				//選中
			}else{
				//未選中
			}
		}
	});// 新增監聽事件
這樣ToggleButton的開關切換就輕鬆實現了。

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

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

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

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

    由於DEMO中的繼承

    具體的這邊不貼程式碼了,可以檢視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 enabled) {
		// TODO Auto-generated method stub
		mEnabled = enabled;
		mAlpha = enabled ? MAX_ALPHA : MAX_ALPHA/2;
		Log.d("enabled",enabled ? "true": "false");
		super.setEnabled(enabled);
		invalidate();
	}
	
	/** 自動判斷切換至相反的屬性 : true -->false ;false -->true */
	public void toggle() {
		setChecked(!mSwitchOn);
	}
	
    /** 設定選中的狀態(選中:true   非選中: false) */
    public void setChecked(boolean checked) {
    	mSwitchOn = checked;
        invalidate();
    }
還有,你如果是自定義的VIEW,你在裡面設定了enabled屬性,你必須在onTouchEvent(MotionEvent event)觸控操作的時候判斷你所設定的enabled屬性是否為true,是的話就可以相應點選事件,否則的話你要遮蔽掉點選事件。因為你自定義的view中的enabled屬性並不知道他設定後會達到什麼效果,這些都是要注意的點。

還有就是要設定介面監聽狀態變化:

	/** 
	 * 設定 switch 狀態監聽 
	 * */
	public void setOnChangeListener(OnSwitchChangedListener listener) {
		switchListener = listener;
	}
	/** 
	 * switch 開關監聽介面
	 *  */
	public interface OnSwitchChangedListener{
		public void onSwitchChange(SlideSwitchView switchView, boolean isChecked);
	}

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

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

	/** 最大透明度,就是不透明 */
	private final int MAX_ALPHA = 255;
	/** 當前透明度,這裡主要用於如果控制元件的enable屬性為false時候設定半透明 ,即不可以點選 */
	private int mAlpha = MAX_ALPHA;
之後重寫setEnabled方法,通過這個方法判斷enabled屬性值
	@Override
	public void setEnabled(boolean enabled) {
		// TODO Auto-generated method stub
		mEnabled = enabled;
		mAlpha = enabled ? MAX_ALPHA : MAX_ALPHA/2;
		super.setEnabled(enabled);
		invalidate();
	}
如果改變了enabled屬性,系統便會檢視UI是否需要變化,之後在UI方法onDraw(Canvas canvas)中呼叫:
android.graphics.Canvas.saveLayerAlpha(RectF bounds, int alpha, int saveFlags)
方法,其中的第2個屬性alpha就是透明度,之後便可以實現相應的效果。

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

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

                      

最後上原始碼DEMO:下載地址

相關推薦

SwitchButton 開關按鈕多種實現方式 原始碼DEMO

剛開始接觸開關樣式的按鈕是在IOS系統上面,它的切換以及滑動十分帥氣,深入人心。 所謂的開關按鈕,就是隻有2個狀態:on和off,下圖就是系統IOS 7上開關按鈕效果。 起初我在android上我只會使用CheckBox去滿足對應的功能。後來,檢視開發文件發現,andro

SwitchButton 開關按鈕多種實現方式 原始碼DEMO

剛開始接觸開關樣式的按鈕是在iOS系統上面,它的切換以及滑動十分帥氣,深入人心。 所謂的開關按鈕,就是隻有2個狀態:on和off,下圖就是系統IOS 7上開關按鈕效果。 起初我在Android上我只會使用CheckBox去滿足對應的功能。後來,檢視開發文件發現,android也有了自己的原生態開關

單點登入SSO實現方式原始碼

原文地址:http://www.cnblogs.com/youring2/p/sso-practice.html SSO的基本概念 SSO英文全稱Single Sign On(單點登入)。SSO是在多個應用系統中,使用者只需要登入一次就可以訪問所有相互信任的應用系統

誰都能看懂的單點登入SSO實現方式原始碼

SSO的基本概念 SSO英文全稱Single Sign On(單點登入)。SSO是在多個應用系統中,使用者只需要登入一次就可以訪問所有相互信任的應用系統。它包括可以將這次主要的登入對映到其他應用中用於同一個使用者的登入的機制。它是目前比較流行的企業業務整合的解決方案之一

Android 音視訊深入 十六 FFmpeg 推流手機攝像頭,實現直播 原始碼下載

原始碼地址https://github.com/979451341/RtmpCamera/tree/master配置RMTP伺服器,雖然之前說了,這裡就直接貼上過來吧1.配置RTMP伺服器這個我不多說貼兩個部落格分別是在mac和windows環境上的,大家跟著弄MAC搭建RT

android 仿 新聞閱讀器 選單彈出效果原始碼DEMO

開發中碰到問題之後實現的,覺得可能有的開發者用的到或則希望獨立成一個小功能DEMO,所以就放出來這麼一個DEMO。 原本覺得是最後完成後髮網站客戶端的,可是這樣體現不出一個功能一個功能的分析實現效果,而且週期時間長,所以就完成一部分,發一部分,敬請諒解。 下面的選單彈出

在.NET Core中三種實現“可插拔”AOP編程方式源碼

必須 n) 即使 extension cti 開閉 void 定義 面向切面編程 原文:在.NET Core中三種實現“可插拔”AOP編程方式(附源碼)一看標題肯定會聯想到使用動態編織的方式實現AOP編程,不過這不是作者本文討論的重點。 本文討論另外三種在netcore中

SpringMvc中,Controller方法的多種實現方式指定返回到哪個頁面,指定返回到頁面的資料

1)ModelAndView@RequestMapping("/list") public ModelAndView itemsList() throws Exception{ List<Items> list = itmesService.lis

StreamSets學習系列之StreamSets支持多種安裝方式圖文詳解

pre 技巧 height targe png 數據分析 語言 微信公眾號 mage   不多說,直接上幹貨! Streamsets的官網 https://streamsets.com/

學習Promise實現原理源碼

cte 標記 必須 es6 nal 每次 fine 函數返回 如果 本篇文章主要在於探究 Promise 的實現原理,帶領大家一步一步實現一個 Promise , 不對其用法做說明,如果讀者還對Promise的用法不了解,可以查看阮一峰老師的ES6 Promise教程。 1

Promise實現原理原始碼

本篇文章主要在於探究 Promise 的實現原理,帶領大家一步一步實現一個 Promise , 不對其用法做說明,如果讀者還對Promise的用法不瞭解,可以檢視阮一峰老師的ES6 Promise教程。 接下來,帶你一步一步實現一個 Promise 1. Promise 基本結

Spring boot基於redis實現附近的人原始碼下載

核心原始碼 public class NearbyPO { @NotNull(message = "id值不能為空") private Integer id; @NotBlank(message

單點登入實現方式Single Sign On

Server端: 1.共享cookie方式(共享session),把session-id放到每一次請求的url裡,即把session拿出來讓所有的Server共享,不安全; 2.SSO-Token方式(Ticket),不再已session-id作為身份的標識,另外生成一種標識

DMA和UART的深刻認識--串列埠接收的3種工作方式STM32F4程式碼

可能會遇到的問題:1.能實現接收但不傳送 注意是否是識別函數出錯2.DMA單次傳輸模式要求再初始化,否者出現第二次中斷不執行。使用迴圈模式出現的問題是要結合配置公式:3.DMA再次初始化不完全,會出現接收一次成功,再來一次不行。第三次能接收的問題4.串列埠除錯連續點選的次數太

PLSql -- 遞迴查詢的另幾種實現方式函式/儲存過程

問題 這是一個樹結構,查詢教師“胡明星”的所有主管及姓名:(無主管的教師也需要顯示),顯示(教師編號、教師名稱、主管編號、主管名稱) 解決1 declare v_tno hand_t

半透明視窗中顯示標準控制元件控制元件與文字不透明實現方案原始碼

原文 http://blog.csdn.net/harbinzju/article/details/7907127 和大家分享一下在半透明視窗中顯示標準控制元件的實現方案。通過層疊視窗可以簡單實現半透明與不規則形狀視窗的效果,但在其上顯示標準控制元件(控制元件與文字不

Android中AIDL實現程序通訊原始碼下載

AIDL概述 之前的部落格《Android中通過Messenger與Service實現程序間雙向通訊》演示瞭如何通過Messenger實現與Service進行跨程序通訊,即IPC。但用Messenger實現的IPC存在一點不足:Service內部維護著一個Me

Android Service Activity三種互動方式原始碼

android SDK提供了Service,用於類似*nix守護程序或者windows的服務。 Service有兩種型別: 1.本地服務(Local Service):用於應用程式內部 2.遠端服務(Remote Sercie):用於android系統內部的應用程式之間 前

【android】自定義ProgressDialog實現暫時隱藏進度值並顯示等待狀態原始碼下載

有時,我們需要訪問網路才能獲取到需要操作的任務數(例如下載的檔案數),而在伺服器返回任務數之前要想隱藏進度百分比和進度數值,就需要我們自己重寫ProgressDialog。等到獲取到任務數後再把進度值和百分比顯示出來。先上效果圖: 關鍵程式碼: public clas

資料庫連線的兩種實現方式讀取配置檔案——DBCP&C3P0;DBCP實現連線程式碼,C3P0實現連線程式碼——包含完整程式碼

兩種資料庫連線實現方式 第一種方式:DBCP DBCP使用流程 導jar包使用DBCP建立資料庫連線物件 DataSource ds=BasicDataSourceFactory.createDatasource("一個儲存連線資訊的properties集合");使