Android自定義滑動驗證條的示例代碼
本文介紹了Android自定義滑動驗證條的示例代碼,分享給大家,具體如下:
*注:不知道為什么,h5的標簽在這里沒用了,所以我也只能用Markdown的語法來寫了
項目地址:https://github.com/994866755/handsomeYe.seekbar.github.io
需求:
在我們的某些應用中需要滑動驗證。比如說這個樣子的:
剛開始我也很懵逼要怎么去弄,結(jié)果我去看了一些人的代碼,有人是用自定義viewgroup去做,就是viewgroup包含滑動塊和滑動條。但我覺得太麻煩,直到我知道android有個控件seekbar可以實現(xiàn)這個效果。
一、使用SeekBar實現(xiàn)滑動條
<SeekBar android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:max="100" android:maxHeight="45dp" android:minHeight="45dp" android:progress="0" android:clickable="false" android:progressDrawable="@drawable/bg_forgotpassword_seekbar" android:thumb="@drawable/bg_seekbar_thumb" android:id="@+id/sb_progress" android:thumbOffset="-1dp" android:padding="1dp" />
這里網(wǎng)上有很多介紹,我也順便解釋一下:
(1)android:max是總共的容量,這里設100就行。
(2)android:progressDrawable是只設置進度框的背景,就是整個條的背景,比如圖中的沒滑動的時候是灰色,滑動的地方是綠色。
(3)android:thumb這個屬性是設置滑塊的樣式,比如圖中的沒滑時是>>,滑到最右變成勾。默認的樣式是一個圓。
(4)android:thumbOffset這個是滑塊的起始位置,怎么說呢,你可以當圖中第一條的滑塊是android:thumbOffset = “0dp”,如果你設置成正數(shù),這個滑塊的位置會向左移動,設成負數(shù)會向右移動。我這里設成-1是以為是0的時候會擋住左邊的邊框,這樣不好看,我設成-1為了讓滑塊向右移動一點。
二、設置SeekBar樣式
寫好布局后來寫下樣式,也就是上面的progressDrawable和thumb屬性。
(1)progressDrawable(滑動條)
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!--seekBar背景--> <item android:id="@android:id/background"> <!--形狀--> <shape android:shape="rectangle"> <!--大小--> <size android:height="29dp" /> <!--圓角--> <corners android:radius="2dp" /> <!--背景--> <solid android:color="#E7EAE9" /> <!--邊框--> <stroke android:width="1dp" android:color="#C3C5C4" /> </shape> </item> <!--seekBar的進度條--> <item android:id="@android:id/progress"> <clip> <shape> <corners android:radius="2dp" /> <solid android:color="#7AC23C" /> <stroke android:width="1dp" android:color="#C3C5C4" /> </shape> </clip> </item> </layer-list>
(2)thumb(滑塊)
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 按下狀態(tài)--> <item android:drawable="@mipmap/seekbar_thumb" android:state_pressed="true" /> <!-- 有焦點狀態(tài) --> <item android:drawable="@mipmap/seekbar_thumb" android:state_focused="true" /> <!-- 普通狀態(tài) --> <item android:drawable="@mipmap/seekbar_thumb" /> </selector>
這里就不多介紹了。
三、加入監(jiān)聽
在activity中加入監(jiān)聽,比如你可以讓滑塊不滑到最右時自動彈回原位等等。
sbProgress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { if (seekBar.getProgress() != seekBar.getMax()) { seekBar.setProgress(0); }else { sbProgress.setEnabled(false); setData(); } } });
最后實現(xiàn)的效果是這樣:
你可以自己加文字在中間,這個我就不在demo里弄了。
四、剩下的處理
你以為這樣就完啦?那你太天真了,你會發(fā)現(xiàn)如果你按上面的步驟做,最后會有一個很蛋疼的效果:
你不滑動滑塊,只點擊滑動條中間,滑塊會馬上到中間。
也就是說我們想做的效果是只滑動而不能點擊,僅僅做成這樣是沒辦法實現(xiàn)這個需求。
那怎么辦?我在網(wǎng)上找了很多文章,大多都是不能滑也不能點,而我要的是能滑不能點。難道SeekBar沒戲啦?我想了想,最后我用事件分發(fā)來解決。
既然是事件分發(fā),我這里也不想寫事件分發(fā)的內(nèi)容,以后我們寫一篇專門關于事件分發(fā)的文章,這里如果有小伙伴不了解事件分發(fā)的話,自己先去google一下。
既然是事件分發(fā),那我們就需要自定義seekbar啦,其實很簡單。我先貼代碼,然后再講解。
(1)代碼君:
public class VerificationSeekBar extends SeekBar{ //這兩個值為用算法使用的2空間復雜度 private int index = 150; private boolean k = true; public VerificationSeekBar(Context context) { super(context); } public VerificationSeekBar(Context context, AttributeSet attrs) { super(context, attrs); } public VerificationSeekBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean dispatchTouchEvent(MotionEvent event) { int x = (int) event.getX(); if (event.getAction() == MotionEvent.ACTION_DOWN){ k = true; if (x - index > 20) { k = false; return true; } } if (event.getAction() == MotionEvent.ACTION_MOVE){ if (!k){ return true; } } return super.dispatchTouchEvent(event); } }
(2)講解
為了方便講解,我把其它的內(nèi)容刪掉,就留關鍵方法,沒錯,就是dispatchTouchEvent。但是如果我不說,可能dispatchTouchEvent里面的代碼你會看得蒙。
先說說我的思想:簡單來說就是你點擊的地方要在滑塊的范圍,才分發(fā)事件,不然retrun true不分發(fā)事件。所以有了x - index > 20,這里的index =150是我滑塊的大概寬度,所以要你點擊的地方在我滑塊的寬度的20像素直接我才分發(fā)事件。所以x - index > 20的話不分發(fā)。
int x = (int) event.getX(); 獲取點擊時的坐標,注意,是相對于view左上角的,而不是相對屏幕的。
我這里分別按順序判斷了event.getAction() == MotionEvent.ACTION_DOWN和event.getAction() ==MotionEvent.ACTION_MOVE
,注意,是按順序。為什么要按順序呢?首先你自己測試你會發(fā)現(xiàn),點擊seekbar時ACTION_DOWN和ACTION_MOVE都會執(zhí)行,所以你不能光判定按下,還要判斷滑動。那為什么不一起判斷而要按順序判定呢?因為一起判斷的話你可以試試,你會發(fā)現(xiàn)根本就滑不了。
而學過事件分發(fā)的都知道事件先執(zhí)行ACTION_DOWN再執(zhí)行ACTION_MOVE,所以先判斷點擊的地方是否在滑塊+20像素的范圍內(nèi),如果不在,定義一個布爾值k記錄不在,然后執(zhí)行 if (!k){return true;}
唉!感覺這個算法講得不是很好,聽不懂沒關系,你照抄就行,記得把index改成你滑塊的寬度就行。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android實現(xiàn)USB掃碼槍獲取掃描內(nèi)容
這篇文章主要為大家詳細介紹了Android實現(xiàn)USB掃碼槍獲取掃描內(nèi)容,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09Android編程之Button控件配合Toast控件用法分析
這篇文章主要介紹了Android編程之Button控件配合Toast控件用法,結(jié)合實例形式分析了Button控件及Toast控件的功能及具體使用技巧,需要的朋友可以參考下2015-12-12Android Intent傳遞對象的兩種方法(Serializable,Parcelable)詳細介紹
這篇文章主要介紹了Android Intent傳遞對象的兩種方法(Serializable,Parcelable)詳細介紹的相關資料,需要的朋友可以參考下2016-12-12