android開關按鈕
剛開始接觸開關樣式的按鈕是在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
↳ |
||||
|
↳ |
|||
|
|
↳ |
||
|
|
|
↳ |
android.widget.CompoundButton |
Known Direct Subclasses |
以上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 |
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 |
設置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 |
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="https://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>
反之就是未選中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{
- //未選中
- }
- }
- });// 添加監聽事件
二.重寫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判斷是否有更改並做出相應的變化。
例如:
- @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();
- }
還有就是要設置接口監聽狀態變化:
- /**
- * 設置 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;
- @Override
- public void setEnabled(boolean enabled) {
- // TODO Auto-generated method stub
- mEnabled = enabled;
- mAlpha = enabled ? MAX_ALPHA : MAX_ALPHA/2;
- super.setEnabled(enabled);
- invalidate();
- }
- android.graphics.Canvas.saveLayerAlpha(RectF bounds, int alpha, int saveFlags)
由於目前對於重寫VIEW的onDraw方法的了解不是很深入,所以這裏的DEMO中的幾個方法都是查看網絡之後加上自己的優化和注釋演變過來,等這一塊深入了後在重寫寫一篇關於這個的感受和使用說明。由於可能理解不是很深刻,如果有什麼不足之處可以提出,謝謝。
最後讓我們來看看效果如何,上圖:
最後上源碼DEMO:下載地址
最後更新:2017-04-03 12:56:16
上一篇:
可拖拽gridview
下一篇:
連載:麵向對象葵花寶典:思想、技巧與實踐(26) - 類模型三板斧
如何解決:Android中 Error generating final archive: Debug Certificate expired on 10/09/18 16:30 的錯誤
林更新、楊冪帶貨,2000元一雙的小白鞋如何在天貓走紅
周末薦文 | 貧窮,對你的思維方式造成了多大的影響?
矽穀飄來五個字,SMACK
Grafana+Prometheus係統監控之Redis
天氣預報抓取天氣信息模塊實現(代碼)
HTML中的DOCTYPE需要注意的事情!
JS魔法堂:深究JS異步編程模型
《數據結構與抽象:Java語言描述(原書第4版)》一P.2.2 前置條件和後置條件
[MySQL 5.7]:binlog --statement