这里有新鲜出炉的精品教程,程序狗速度看过来!
Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用“安卓”或“安致”。
本篇文章主要介绍了Android自定义滑动验证条的示例代码,具有一定的参考价值,有兴趣的可以了解一下
本文介绍了Android自定义滑动验证条的示例代码,分享给大家,具体如下:
*注:不知道为什么,h5的标签在这里没用了,所以我也只能用Markdown的语法来写了
项目地址:https://github.com/994866755/handsomeYe.seekbar.github.io
需求:
在我们的某些应用中需要滑动验证。比如说这个样子的:
刚开始我也很懵逼要怎么去弄,结果我去看了一些人的代码,有人是用自定义viewgroup去做,就是viewgroup包含滑动块和滑动条。但我觉得太麻烦,直到我知道android有个控件seekbar可以实现这个效果。
一、使用SeekBar实现滑动条
- <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"
- />
这里网上有很多介绍,我也顺便解释一下:
(1)android:max是总共的容量,这里设100就行。
(2)android:progressDrawable是只设置进度框的背景,就是整个条的背景,比如图中的没滑动的时候是灰色,滑动的地方是绿色。
(3)android:thumb这个属性是设置滑块的样式,比如图中的没滑时是>>,滑到最右变成勾。默认的样式是一个圆。
(4)android:thumbOffset这个是滑块的起始位置,怎么说呢,你可以当图中第一条的滑块是android:thumbOffset = “0dp”,如果你设置成正数,这个滑块的位置会向左移动,设成负数会向右移动。我这里设成-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">
- <!-- 按下状态-->
- <item android:drawable="@mipmap/seekbar_thumb" android:state_pressed="true"
- />
- <!-- 有焦点状态 -->
- <item android:drawable="@mipmap/seekbar_thumb" android:state_focused="true"
- />
- <!-- 普通状态 -->
- <item android:drawable="@mipmap/seekbar_thumb" />
- </selector>
这里就不多介绍了。
三、加入监听
在activity中加入监听,比如你可以让滑块不滑到最右时自动弹回原位等等。
- 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();
- }
- }
- });
最后实现的效果是这样:
你可以自己加文字在中间,这个我就不在demo里弄了。
四、剩下的处理
你以为这样就完啦?那你太天真了,你会发现如果你按上面的步骤做,最后会有一个很蛋疼的效果:
你不滑动滑块,只点击滑动条中间,滑块会马上到中间。
也就是说我们想做的效果是只滑动而不能点击,仅仅做成这样是没办法实现这个需求。
那怎么办?我在网上找了很多文章,大多都是不能滑也不能点,而我要的是能滑不能点。难道SeekBar没戏啦?我想了想,最后我用事件分发来解决。
既然是事件分发,我这里也不想写事件分发的内容,以后我们写一篇专门关于事件分发的文章,这里如果有小伙伴不了解事件分发的话,自己先去google一下。
既然是事件分发,那我们就需要自定义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)讲解
为了方便讲解,我把其它的内容删掉,就留关键方法,没错,就是dispatchTouchEvent。但是如果我不说,可能dispatchTouchEvent里面的代码你会看得蒙。
先说说我的思想:简单来说就是你点击的地方要在滑块的范围,才分发事件,不然retrun true不分发事件。所以有了x - index > 20,这里的index =150是我滑块的大概宽度,所以要你点击的地方在我滑块的宽度的20像素直接我才分发事件。所以x - index > 20的话不分发。
int x = (int) event.getX(); 获取点击时的坐标,注意,是相对于view左上角的,而不是相对屏幕的。
我这里分别按顺序判断了
,注意,是按顺序。为什么要按顺序呢?首先你自己测试你会发现,点击seekbar时ACTION_DOWN和ACTION_MOVE都会执行,所以你不能光判定按下,还要判断滑动。那为什么不一起判断而要按顺序判定呢?因为一起判断的话你可以试试,你会发现根本就滑不了。
- event.getAction() == MotionEvent.ACTION_DOWN和event.getAction() ==MotionEvent.ACTION_MOVE
而学过事件分发的都知道事件先执行ACTION_DOWN再执行ACTION_MOVE,所以先判断点击的地方是否在滑块+20像素的范围内,如果不在,定义一个布尔值k记录不在,然后执行 if (!k){return true;}
唉!感觉这个算法讲得不是很好,听不懂没关系,你照抄就行,记得把index改成你滑块的宽度就行。
来源: http://www.phperz.com/article/17/0913/345756.html