seekBar滑块验证解锁

一、项目背景
最近项目比较忙,所以,这次更新文章比较慢,还请jrs们多多给我提建议哈。本次的内容是最近项目中的一个需求,当密码输错三次后,需要通过滑块验证解锁,来再次显示密码输入框!直接上图看效果哈!!!这里是效果图
说明下效果哈:
当滑块没有滑动到最右端,即滑块没有变成对号的时候,如果手指松开,拖动即停止了,这个时候滑块会自动的回到起始的位置。如果滑块滑到最右端,即滑块变成对号的时候,进度条的中间显示文本——验证成功!同时,滑块验证消失,密码输入框显示。

二、功能的实现
2.1首先,看看seekbar的核心图,这里写图片描述

***说明:其实,seekbar的核心其实是 :三个背景的图的叠加+一个thumb的滑块(很重要!!!)***

2.2 然后,再来看布局文件的内容

    <!--滑块验证-->
    <RelativeLayout
        android:id="@+id/seekbar_rlyt"
        android:layout_width="match_parent"
        android:layout_height="39dp"
        android:layout_marginLeft="@dimen/Size_15dp"
        android:layout_marginRight="@dimen/Size_15dp"
        android:background="@drawable/btn_bg_grag_0_radius"
        android:visibility="visible"
        >

        <SeekBar
            android:id="@+id/seekbar_sb"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/seekbar_margin"
            android:layout_marginRight="@dimen/seekbar_margin"
            android:max="100"
            android:maxHeight="38dp"
            android:minHeight="38dp"
            android:thumbOffset="5dp"
            android:progressDrawable="@drawable/seekbarbackground"
            android:thumb="@drawable/seekbar_thumb_uncompelete_selector"
            />

        <TextView
            android:id="@+id/seekbar_tv"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:layout_centerInParent="true"
            android:text="验证成功"
            android:textSize="@dimen/Size_14sp"
            android:textColor="@color/white"
            android:visibility="gone"
            />
    </RelativeLayout>

说明:1、这里用了一个相对布局,来控制验证完成后显示验证成功的文案。
2、SeekBar常用属性

    android:max[integer]//设置拖动条的最大值
    android:progress[integer]//设置当前的进度值
    android:secondaryProgress[integer]//设置第二进度,通常用做显示视频等的缓冲效果
    android:thumb[drawable]//设置滑块的图样
    android:progressDrawable[drawable]//设置进度条的图样

2.3 来看看三层图片的背景图文件,在drawable目录下面新建一个layer-list文件,即android:progressDrawable=”@drawable/seekbarbackground”的seekbarbackground文件(实际上是三层结构):

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- 第一层背景图,即seekbar的背景 -->
    <item  android:id="@android:id/background"
        android:drawable="@drawable/seekbar_def_bg_selector"
        />


    <!-- 第二进度条式样(即第二层图的背景,常做音乐或者视频播放器的缓冲进度)由于我这里不需要设置缓冲进度,所以这里就不设置了 -->
    <!--<item  android:id="@android:id/secondaryProgress"-->
           <!--android:drawable="@drawable/seekbar_def_bg_selector"-->
        <!--&gt;</item>-->


<!--第三层图背景,即真正的进度条的背景。注意:一定要设置clip标签-->
    <item android:id="@android:id/progress">
        <clip>
            <shape android:shape="rectangle">
                <corners android:radius="0dp"/>

                <solid android:color="@color/tint_blue_color"></solid>
            </shape>
        </clip>
    </item>
</layer-list>

再往下看:
android:drawable=”@drawable/seekbar_def_bg_selector”文件的内容:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true" android:drawable="@drawable/seekbar_def_bg"> </item>
    <item android:state_pressed="false" android:drawable="@drawable/seekbar_def_bg"> </item>
</selector>

2.3.1 seekbar_def_bg图片即:
这里写图片描述
可以看到,这个图片即为我们的seekbar的背景图片了

2.3.2 第三层背景图片,即进度条是一个shape,@color/tint_blue_color的内容是<color name="tint_blue_color">#43AAFF</color>
即为蓝色的进度条颜色了

2.4 来看看滑块的内容,在drawable目录下新建一个selector文件即android:thumb=”@drawable/seekbar_thumb_uncompelete_selector”

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/drage_left"> </item>
    <item android:state_pressed="false" android:drawable="@drawable/drage_left"> </item>
    </selector>

说明:可以看到,thumb的背景图可以设置一个selector图片,因此滑块可以设置当按下的时候设置一种图片,松开滑块的时候再设置一种图片。由于我这里只需要一种图片,所以按下和松开滑块都设置了一种图片。图片为这里写图片描述

2.5 看看逻辑代码哈

    mSeekBar_Sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {  //滑块正在滑动过程中的监听
                if (progress >= 95){       //滑动动作完成,设置滑块的图片是对号的图片
                    mSeekBar_Sb.setThumb(getResources().getDrawable(R.drawable.seekbar_thumb_compelete_selector));
                    mSeekBar_tv.setVisibility(View.VISIBLE);

                }else {          //滑动动作没有完成,设置滑块的图片是箭头的图片
                    mSeekBar_Sb.setThumb(getResources().getDrawable(R.drawable.seekbar_thumb_uncompelete_selector));
                    mSeekBar_tv.setVisibility(View.GONE);

                }

            }


            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {   //滑块准备滑动前的监听
                seekBar.setThumbOffset(0);

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {       //滑块滑动滑动完成后的监听
                if (seekBar.getProgress() < 95) {
                    seekBar.setProgress(6);
                }else {
                    //                    0.6s后隐藏滑块
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                //

                                Thread.sleep(600);
                                Message message = handler.obtainMessage();
                                message.what = 0;
                                handler.sendMessage(message);
                            }catch (Exception e){
                                e.printStackTrace();
                            }


                        }
                    }).start();
                }
            }
        });
private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {    //隐藏滑块,显示密码登录
            switch (msg.what){
                case 0:
//                    清空密码输入框
                    mPwdLogin.setText("");
                    mPassword_login_llyt.setVisibility(View.VISIBLE);
                    mSeekBar_rlyt.setVisibility(View.GONE);
                    break;

                   default:
                       break;
            }
        }

    };
//    判断滑块是否显示
    private void initSeekBarSate() {
        if (inputTimes >= 3) {       //输错>=3次,滑块显示,需要滑块解锁
            mSeekBar_rlyt.setVisibility(View.VISIBLE);
            mSeekBar_tv.setVisibility(View.GONE);

            mSeekBar_Sb.setProgress(6);
            //                                提交按钮置灰
            mSubmit.setBackgroundDrawable(getResources().getDrawable(R.drawable.btn_grag_2_radius_login));
            mSubmit.setTextColor(getResources().getColor(R.color.eidtext_input_color));
            mSubmit.setEnabled(false);

            showShortToast("向右滑动验证");
//            隐藏密码输入
            mPassword_login_llyt.setVisibility(View.GONE);
        }else {
            mSeekBar_rlyt.setVisibility(View.GONE);

            //            显示密码输入
            mPassword_login_llyt.setVisibility(View.VISIBLE);
        }
    }

三、优化的说明
3.1 滑块消失后密码输入框显示的时间问题
由于滑块在滑到最右端的时候,滑块布局消失,密码输入框会立刻显示,这样的用户体验会不好的。所以这里要在滑块滑到最右端的时候,给一个时间差,让滑块消失后的0.6s后,密码输入框显示。代码即

 new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                //

                                Thread.sleep(600);
                                Message message = handler.obtainMessage();
                                message.what = 0;
                                handler.sendMessage(message);
                            }catch (Exception e){
                                e.printStackTrace();
                            }


                        }
                    }).start();

private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {    //隐藏滑块,显示密码登录
            switch (msg.what){
                case 0:
//                    清空密码输入框
                    mPwdLogin.setText("");
                    mPassword_login_llyt.setVisibility(View.VISIBLE);
                    mSeekBar_rlyt.setVisibility(View.GONE);
                    break;

                   default:
                       break;
            }
        }

    };

3.2 每次滑完滑块后,滑块的初始化位置问题
滑块能滑动的最左边和最右边距离其实是将滑块的中心点滑动到最左边或者最右边,这里写图片描述
滑动到最右边的时候
这里写图片描述
滑块(对号)已经一半滑出去了。为了解决这个问题,我在每次设置滑块的初始位置的时候,都设置mSeekBar_Sb.setProgress(6);的进度是6,而不是0,这样就保正了滑块在最左边只显示一半的问题。最右边的时候,进度>=95的时候,滑块图片设置为对号的,而不是100,if (progress >= 95)这样就避免了滑到最右端的时候滑块图片只显示一半的问题。
四、存在的问题
4.1 接着上面的内容,虽然解决了滑块滑到最右端的时候,滑块的对号图片全部显示的问题,但是,滑块还能继续向右滑动,直至progress = 100,这个时候对号图片还是会出现一半的问题(待优化)。
4.2 给背景图(即第一个图)设置一个背景动画效果
这里写图片描述
而背景图是放在layer-list的,对于这里面的图片设置动画效果,我查看了一些文档,都没有说明。

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- 第一层背景图,即seekbar的背景 -->
    <item  android:id="@android:id/background"
        android:drawable="@drawable/seekbar_def_bg_selector"
        />
/layer-list>

如果有哪位大神看到了,有好的解决方法,可以一起讨论讨论哈,可以给我留言。谢谢大家的支持!!!!!!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值