一、项目背景
最近项目比较忙,所以,这次更新文章比较慢,还请jrs们多多给我提建议哈。本次的内容是最近项目中的一个需求,当密码输错三次后,需要通过滑块验证解锁,来再次显示密码输入框!直接上图看效果哈!!!
说明下效果哈:
当滑块没有滑动到最右端,即滑块没有变成对号的时候,如果手指松开,拖动即停止了,这个时候滑块会自动的回到起始的位置。如果滑块滑到最右端,即滑块变成对号的时候,进度条的中间显示文本——验证成功!同时,滑块验证消失,密码输入框显示。
***说明:其实,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文件(实际上是三层结构):
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background"
android:drawable="@drawable/seekbar_def_bg_selector"
/>
<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”文件的内容:
<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的内容是
即为蓝色的进度条颜色了
2.4 来看看滑块的内容,在drawable目录下新建一个selector文件即android:thumb=”@drawable/seekbar_thumb_uncompelete_selector”
<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">
<item android:id="@android:id/background"
android:drawable="@drawable/seekbar_def_bg_selector"
/>
/layer-list>
如果有哪位大神看到了,有好的解决方法,可以一起讨论讨论哈,可以给我留言。谢谢大家的支持!!!!!!