seekbar只能拖拽禁止点击及seekbar常见问题

来源:互联网 发布:淘宝店铺做淘客链接 编辑:程序博客网 时间:2024/06/06 15:50

项目中需要用到滑块验证或拼图验证,参考了大神们的一些demo,都涉及用到seekbar,本人在使用的过程中也遇到一些问题,所以用自己总结了一些。

先贴本人参考过的大神们验证的作品:

拼图验证:

http://qingmang.me/articles/-4771769944547152798

http://www.open-open.com/lib/view/open1483581590428.html

滑块验证:

http://blog.csdn.net/qq_30379689/article/details/53284378

但是这些seekbar中都有一个问题,就是没有禁止seekbar的点击,只要点击到seekbar的后方,滑块就会跳到后方,达不到拖拉验证的效果。

所以又参考了另一位大神的文章,得到了解决:

http://blog.csdn.net/tingfengzheshuo/article/details/44858187


大致效果图,不会动,麻烦下载代码看了- -||:



完整代码于最下方,本demo介绍以下问题:

1.滑块不能位于进度条的最左边

如:

解决:

设置偏移量

android:thumbOffset="5dp"


2.滑块不能居中在进度条中

解决:

设置高度自适应,会自动契合滑块高度

android:layout_height="wrap_content"

然后使用以下属性设置高度

android:maxHeight="30dip"
android:minHeight="30dip"


3.如何在滑块上写字

解决:

重写ondraw方法

protected synchronized void onDraw(Canvas canvas) {          super.onDraw(canvas);          Rect rect = new Rect();          this.mPaint.getTextBounds(this.text, 0, this.text.length(), rect);          int x = (getWidth() / 2) - rect.centerX();          int y = (getHeight() / 2) - rect.centerY();          canvas.drawText(this.text, x, y, this.mPaint);      }

4.禁止seekbar点击后方,只能拖拽

解决思路:

1)保存一个旧的位置progress——oldsign,默认是0

2)用户点击seekbar后方的时候,记录用户点击的progress

3)通过判断当前点击的progress是否 < (oldsign+某个值),如果是则能拖动,如果否则设置seekbar位置progress为0,从而达到不动效果。

import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.widget.SeekBar;import android.widget.SeekBar.OnSeekBarChangeListener;public class ValidateSeekBar extends SeekBar implements OnSeekBarChangeListener{private Context context;//记录旧的位置private int oldsign;//写进度条上text的画笔private Paint mPaint; private String textStr ="请拖动到最右边完成验证";//text内容private String text=textStr;//text字体大小private int textSize =20;//text颜色private String textColor ="#607B8B";public interface ValidateSeekBarCallBack {void onProgressChangedCallBack(SeekBar seekbar, int progress, boolean arg2);void onStartTrackingTouchCallBack(SeekBar seekbar);void onStopTrackingTouchCallBack(SeekBar seekbar);}private ValidateSeekBarCallBack callback;public ValidateSeekBar(Context context) {super(context);this.context = context;init();}public ValidateSeekBar(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);this.context = context;init();}public ValidateSeekBar(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;init();}private void init() {this.mPaint = new Paint();          this.mPaint.setColor(Color.parseColor(textColor));         this.mPaint.setTextSize(textSize);        setMax(100);        setOnSeekBarChangeListener(this);}@Override      protected synchronized void onDraw(Canvas canvas) {          super.onDraw(canvas);          Rect rect = new Rect();          this.mPaint.getTextBounds(this.text, 0, this.text.length(), rect);          int x = (getWidth() / 2) - rect.centerX();          int y = (getHeight() / 2) - rect.centerY();          canvas.drawText(this.text, x, y, this.mPaint);      }@Overridepublic void onProgressChanged(SeekBar seekbar, int progress, boolean arg2) {//控制textview会闪的bugif(progress<(seekbar.getMax()/9+1)&&progress!=0){text="";}//当点击的位置大于 (0 + 100/9+1)时就不能被拖动  ,+号后数字越大,允许前方开始拖拽的范围就会越大//为什么要用“/”+某数值?是因为防止进度条的最大值有可能是1000、500、300等,所以都取进度条的 9分之1 + 一个自定义数值//为什么不能将判断改为当前位置大于 0? 因为在点击滑块的时候,progerss已经改变if(progress>oldsign+(seekbar.getMax()/9+1)){seekbar.setProgress(oldsign);return;}seekbar.setProgress(progress);oldsign = progress;if(this.callback!=null){this.callback.onProgressChangedCallBack(seekbar,progress,arg2);}}@Overridepublic void onStartTrackingTouch(SeekBar seekbar) {seekbar.setProgress(oldsign);if(this.callback!=null){this.callback.onStartTrackingTouchCallBack(seekbar);}}@Overridepublic void onStopTrackingTouch(SeekBar seekbar) {if(seekbar.getProgress()!=seekbar.getMax()){oldsign=0;text =textStr;seekbar.setProgress(oldsign);}else{text ="完成验证";}if(this.callback!=null){this.callback.onStopTrackingTouchCallBack(seekbar);}}  /** * seekbar回调 * @param callback */public void setValidateSeekBarCallBack(ValidateSeekBarCallBack callback){this.callback =callback;}public void refreshText(){text=textStr;}}

事实上,这个方法也是不完整的,因为前方可拖动的范围太难掌控,导致如果只是点击滑块按钮的附近位置的时候,滑块就会动,只有在可拖拉范围外才不会动。

遗留的坑:

1.由于点击滑块,progress位置会变,所以得设置可拖拉范围,但范围不可控导致点滑块周边范围时,滑块会动。

2.不能平滑回滚滑块


代码不用钱:

http://download.csdn.net/detail/tangjiarao/9878925