Android UI設(shè)計(jì)系列之自定義SwitchButton開(kāi)關(guān)實(shí)現(xiàn)類(lèi)似IOS中UISwitch的動(dòng)畫(huà)效果(2)
做IOS開(kāi)發(fā)的都知道,IOS提供了一個(gè)具有動(dòng)態(tài)開(kāi)關(guān)效果的UISwitch組件,這個(gè)組件很好用效果相對(duì)來(lái)說(shuō)也很絢麗,當(dāng)我們?nèi)c(diǎn)擊開(kāi)關(guān)的時(shí)候有動(dòng)畫(huà)效果,但遺憾的是Android上并沒(méi)有給我們提供類(lèi)似的組件(聽(tīng)說(shuō)在Android4.0的版本上提供了具有動(dòng)態(tài)效果的開(kāi)關(guān)組件,不過(guò)我還沒(méi)有去看文檔),如果我們想實(shí)現(xiàn)類(lèi)似的效果那該怎么辦了呢?看來(lái)又得去自定義了。
公司的產(chǎn)品最近一直在做升級(jí),主要做的就是把界面做的更絢麗更美觀給用戶更好的體驗(yàn)(唉,顧客是上帝......),其中的設(shè)置功能中就有開(kāi)關(guān)按鈕,原來(lái)的開(kāi)關(guān)做的是兩幅圖片,通過(guò)點(diǎn)擊圖片來(lái)給開(kāi)關(guān)設(shè)置不同的狀態(tài)圖片,但是這種效果很死板和程序的整體風(fēng)格不太協(xié)調(diào),于是就想著實(shí)現(xiàn)類(lèi)似于IOS中的開(kāi)關(guān)效果。
拿著筆在圖紙上畫(huà)了畫(huà),我實(shí)現(xiàn)的原理也是采用了兩幅圖片,一個(gè)整體的背景圖:和一個(gè)小滑塊圖:,用小滑塊圖實(shí)現(xiàn)在背景圖上滑動(dòng),當(dāng)小滑塊滑到左邊時(shí)恰好遮擋了開(kāi)字,就是顯示的關(guān)了,同樣原理當(dāng)小滑塊滑動(dòng)到右側(cè)時(shí)恰好遮擋了關(guān)字也就是現(xiàn)實(shí)開(kāi)了,滑動(dòng)的實(shí)現(xiàn)主要用的就是TranslateAnimation類(lèi),如有對(duì)TranslateAnimation不太熟悉的,問(wèn)問(wèn)度娘,她那有關(guān)TranslateAnimation的解說(shuō)多了去了,畢竟自己動(dòng)手,豐衣食足嘛,(*^__^*) 嘻嘻……
好了,老規(guī)矩來(lái)看一下項(xiàng)目結(jié)構(gòu)吧:
工程中switch_button.xml文件就是對(duì)應(yīng)的SwitchButton的布局文件,內(nèi)容不需要解釋?zhuān)阋豢淳投?/p>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/switch_parent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/switch_bg"> <ImageView android:id="@+id/switch_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/switch_btn" /> </LinearLayout>
SwitchButton的布局文件中根節(jié)點(diǎn)是個(gè)LinearLayout,把它的背景設(shè)置成了一個(gè)含有開(kāi)關(guān)文字的圖片,里邊包含一個(gè)ImageView,這個(gè)ImageView就是用來(lái)在LinearLayout中進(jìn)行滑動(dòng)的。
其中自定義開(kāi)關(guān)組件就是都在wedgit包下的SwitchButton,那么趕緊來(lái)看一下SwitchButton的代碼吧
public class SwitchButton extends LinearLayout { /** * 開(kāi)關(guān)圖片 */ private LinearLayout switchParent; /** * 滑塊圖片 */ private ImageView switchButton; /** * 按鈕狀態(tài),默認(rèn)關(guān)閉 */ private boolean isOn = false; /** * 滑塊需要滑動(dòng)的距離 */ private int scrollDistance; /** * 開(kāi)關(guān)按鈕監(jiān)聽(tīng)器 */ private SwitchChangedListner listner; public SwitchButton(Context context) { super(context); initWedgits(context); } public SwitchButton(Context context, AttributeSet attrs) { super(context, attrs); initWedgits(context); } /** * 初始化組件 * * @param context * 上下文環(huán)境 */ private void initWedgits(Context context) { try { View view = LayoutInflater.from(context).inflate( R.layout.switch_button, this); switchParent = (LinearLayout) view.findViewById(R.id.switch_parent); switchButton = (ImageView) view.findViewById(R.id.switch_button); addListeners(); } catch (Exception e) { e.printStackTrace(); } } /** * 添加事件監(jiān)聽(tīng)器 */ private void addListeners() { try { switchParent.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { isOn = !isOn; scrollSwitch(); if (null != listner) { // 開(kāi)關(guān)開(kāi)發(fā)或者關(guān)閉的回調(diào)方法 listner.switchChanged(getId(), isOn); } } }); } catch (Exception e) { e.printStackTrace(); } } /** * 滑動(dòng)開(kāi)關(guān) */ private void scrollSwitch() { // 獲取滑塊需要滑動(dòng)的距離,滑動(dòng)距離等于父組建的寬度減去滑塊的寬度 scrollDistance = switchParent.getWidth() - switchButton.getWidth(); // 初始化滑動(dòng)事件 Animation animation = null; if (isOn) { animation = new TranslateAnimation(0, scrollDistance, 0, 0); } else { animation = new TranslateAnimation(scrollDistance, 0, 0, 0); } // 設(shè)置滑動(dòng)時(shí)間 animation.setDuration(200); // 滑動(dòng)之后保持狀態(tài) animation.setFillAfter(true); // 開(kāi)始滑動(dòng) switchButton.startAnimation(animation); } /** * 獲取開(kāi)關(guān)狀態(tài) * * @return 【true:打開(kāi)】【false:關(guān)閉】 */ public boolean isOn() { return isOn; } /** * 設(shè)置開(kāi)關(guān)狀態(tài) * * @param isOn * 開(kāi)關(guān)狀態(tài)【true:打開(kāi)】【false:關(guān)閉】 */ public void setOn(boolean isOn) { if (this.isOn == isOn) { return; } this.isOn = isOn; post(new Runnable() { @Override public void run() { scrollSwitch(); } }); } /** * 設(shè)置開(kāi)關(guān)狀態(tài)監(jiān)聽(tīng)器 * * @param listner * 開(kāi)關(guān)狀態(tài)監(jiān)聽(tīng)器 */ public void setOnSwitchListner(SwitchChangedListner listner) { this.listner = listner; } /** * 開(kāi)關(guān)狀態(tài)監(jiān)聽(tīng)器 * * @author llew * */ public interface SwitchChangedListner { /** * 開(kāi)關(guān)狀態(tài)改變 * * @param viewId * 當(dāng)前開(kāi)關(guān)ID * @param isOn * 開(kāi)關(guān)是否打開(kāi)【true:打開(kāi)】【false:關(guān)閉】 */ public void switchChanged(Integer viewId, boolean isOn); } }
SwitchButton的實(shí)現(xiàn)也很簡(jiǎn)單,首先是初始化組件initWedgits(),然后添加事件監(jiān)聽(tīng)器addListeners(),在監(jiān)聽(tīng)器中做邏輯判斷,代碼都有注釋?zhuān)筒辉僭敿?xì)說(shuō)明了
那么到了最后,我們來(lái)看看MainActivity中對(duì)SwitchButton的用法吧
public class MainActivity extends Activity { private SwitchButton switchButton; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); initWedgits(); } /** * 初始化各組件 */ private void initWedgits() { try { switchButton = (SwitchButton) findViewById(R.id.switchButton); // switchButton.setOn(false); switchButton.setOn(true); addListeners(); } catch (Exception e) { e.printStackTrace(); } } /** * 添加事件監(jiān)聽(tīng)器 */ private void addListeners() { try { switchButton.setOnSwitchListner(new SwitchChangedListner() { @Override public void switchChanged(Integer viewId, boolean isOn) { if(isOn) { Toast.makeText(getApplicationContext(), "開(kāi)關(guān)打開(kāi)了", Toast.LENGTH_LONG).show(); } else { Toast.makeText(getApplicationContext(), "開(kāi)關(guān)關(guān)閉了", Toast.LENGTH_LONG).show(); } } }); } catch (Exception e) { e.printStackTrace(); } } }
好了,代碼都貼完了,接下來(lái)看看運(yùn)行效果吧,(*^__^*) 嘻嘻……
很遺憾的是,木有動(dòng)畫(huà)效果,先這樣
好了,基本上自定義開(kāi)關(guān)組件到這里就講完了,如有不足,請(qǐng)大家諒解。
源碼下載:Android UI實(shí)現(xiàn)類(lèi)似IOS中UISwitch的動(dòng)畫(huà)效果
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- android開(kāi)發(fā)教程之switch控件使用示例
- Android UI控件Switch的使用方法
- Android開(kāi)關(guān)控件Switch的使用案例
- Android 自定義Switch開(kāi)關(guān)按鈕的樣式實(shí)例詳解
- android自定義開(kāi)關(guān)控件-SlideSwitch的實(shí)例
- Android自定義控件實(shí)現(xiàn)滑動(dòng)開(kāi)關(guān)效果
- Android自定義控件之開(kāi)關(guān)按鈕學(xué)習(xí)筆記分享
- Android開(kāi)發(fā)進(jìn)階自定義控件之滑動(dòng)開(kāi)關(guān)實(shí)現(xiàn)方法【附demo源碼下載】
- Android開(kāi)發(fā)實(shí)現(xiàn)Switch控件修改樣式功能示例【附源碼下載】
相關(guān)文章
Android自動(dòng)填充短信驗(yàn)證碼功能(demo)
在項(xiàng)目開(kāi)發(fā)中為了給用戶帶來(lái)極好的體驗(yàn)效果,通常需要實(shí)現(xiàn)驗(yàn)證碼的自動(dòng)填充功能,怎么實(shí)現(xiàn)呢?今天小編給大家分享Android自動(dòng)填充短信驗(yàn)證碼功能的實(shí)現(xiàn)方法,需要的朋友參考下吧2017-02-02Android優(yōu)化之啟動(dòng)頁(yè)去黑屏實(shí)現(xiàn)秒啟動(dòng)
本文的內(nèi)容主要是講Android啟動(dòng)頁(yè)優(yōu)化,去黑屏實(shí)現(xiàn)秒啟動(dòng)的功能,有需要的小伙伴們可以參考學(xué)習(xí)。2016-08-08Android聊天工具基于socket實(shí)現(xiàn)
這篇文章主要介紹了基于socket實(shí)現(xiàn)的一個(gè)簡(jiǎn)單的Android聊天工具,實(shí)現(xiàn)方法簡(jiǎn)單,具有一定的參考價(jià)值,感興趣的朋友可以參考一下2016-02-02Android開(kāi)發(fā)數(shù)據(jù)結(jié)構(gòu)算法ArrayList源碼詳解
這篇文章主要為大家介紹了Android開(kāi)發(fā)數(shù)據(jù)結(jié)構(gòu)算法ArrayList源碼詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10基于Android自定義控件實(shí)現(xiàn)刮刮樂(lè)效果
這篇文章主要介紹了基于Android自定義控件實(shí)現(xiàn)刮刮樂(lè)效果 的相關(guān)資料,需要的朋友可以參考下2015-12-12android監(jiān)聽(tīng)返回按鈕事件的方法
這篇文章主要介紹了android監(jiān)聽(tīng)返回按鈕事件的方法,涉及Android事件監(jiān)聽(tīng)的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10Android?EventBus粘性事件實(shí)現(xiàn)機(jī)制探究
最近項(xiàng)目做組件化,需要進(jìn)行組件化的通信,有時(shí)候可能會(huì)出現(xiàn)異步的情況,事件接收方還沒(méi)準(zhǔn)備好事件就已經(jīng)發(fā)送過(guò)來(lái)了,這時(shí)候想到了EventBus的粘性事件,這篇文章主要給大家介紹了關(guān)于Android?EventBus粘性事件實(shí)現(xiàn)機(jī)制的相關(guān)資料,需要的朋友可以參考下2022-05-05Android鬧鐘機(jī)制實(shí)現(xiàn)定時(shí)任務(wù)功能
這篇文章主要為大家詳細(xì)介紹了Android鬧鐘機(jī)制實(shí)現(xiàn)定時(shí)任務(wù)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01Android ContentResolver使用說(shuō)明
這篇文章主要介紹了Android ContentResolver使用說(shuō)明,需要的朋友可以參考下2016-01-01