android三档自定义滑动开关,禁止点击功能的实现,普通开关网上有很多例子,三档滑动开关的则找了整天都没有相关例子,开始用普通开关的源码修改了自己实现了一个类,但效果不如人意,各种边界情况的算法很难考虑周全很难调试出满意的效果。
今 天尝试用系统组件seekbar实现自定义风格的滑动条,但禁止点击和判断滑动不到指定范围返回花了不少时间,网上基本上都说用继承seekbar修改里 面的方法实现,但整了半天也没有一个能够达到效果了,而且感觉太麻烦了,所以自己把默认的实现的几个接口返回的信息详细打印出来调试了下,发现可以通过返 回参数来实现自己想要的结果。
先上个效果图
核心部分代码:
privateSeekBarseekbar;
private int lastProgress = 0;
private int newProgress = 0;
seekbar=(SeekBar)findViewById(R.id.seekBar);
seekbar.setOnSeekBarChangeListener( this);
//lastProgress=?从配置文件中读取
seekbar.setProgress(lastProgress);1
@Override
public void onProgressChanged(SeekBar paramSeekBar, int progress,boolean fromUser) {Log.i("onProgressChanged=","cc progress="+ progress + " lastProgress="+ lastProgress+" newProgress="+ newProgress);if(progress >newProgress+10 || progress<newProgress-10){newProgress = lastProgress;paramSeekBar.setProgress(lastProgress);return;}newProgress = progress;}@Overridepublic void onStartTrackingTouch(SeekBar paramSeekBar) {Log.i("onStartTrackingTouch="," lastProgress="+ lastProgress+" newProgress="+ newProgress);}@Overridepublic void onStopTrackingTouch(SeekBar paramSeekBar) {Log.i("onStopTrackingTouch="," lastProgress="+ lastProgress+" newProgress="+ newProgress);if(newProgress<30){lastProgress = 0;newProgress =0;paramSeekBar.setProgress(0);}else if(newProgress>70){//设置lastProgress 要放在setProgress之前,否则可能导致执行多次onProgressChanged 改变了原值lastProgress = 100;newProgress = 100;paramSeekBar.setProgress(100);}else{lastProgress = 50;newProgress =50;paramSeekBar.setProgress(50);}Log.v("onStopTrackingTouch2="," lastProgress="+ lastProgress+" newProgress="+ newProgress);changeProgressStateImg(lastProgress);}
相关自定义样式,layout里面的布局
<LinearLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_marginTop="25dip" ><SeekBarandroid:id="@+id/seekBar"android:layout_width="520px"android:layout_height="wrap_content"android:layout_centerInParent="true"android:max="100"android:maxHeight="32px"android:minHeight="32px"android:paddingLeft="25px"android:paddingRight="25px"android:progressDrawable="@drawable/seekbar_style"android:thumb="@drawable/seekbar_thumb" /></LinearLayout>
简单解释下seekbar中几个重要的属性:
android:layout_height="wrap_content" //建议使用wrap_content,否则一定要保证设置的值不小于seekbar图片资源中的最高值
android:paddingLeft="25px"
android:paddingRight="25px"
//说明进度条的最低和最大高度,解决高度问题。 android:paddingLeft="18px" android:paddingRight="18px" //解决拖动按钮在最左最右显示不全的问题,padding的值一般是thumb的一半宽度。 android:progressDrawable="@drawable/seekbar_style" //设置了此值,就表示使用自定义的进度条样式,在其中可以设置进度条背景图,进度条图,缓冲条图。 android:thumb="@drawable/seekbar_thumb" //seekbar的拖动按钮图片
seekbar_style.xml
<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="/apk/res/android"> <item android:id="@android:id/background" android:drawable="@drawable/seekbar_bg"/> <item android:id="@android:id/progress" android:drawable="@drawable/seekbar_bg"/> <item android:id="@android:id/secondaryProgress" android:drawable="@drawable/seekbar_bg"/>
</layer-list>
seekbar_thumb.xml\
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="/apk/res/android"> <!-- 按下状态--> <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/thumb_normal" /> <!-- 普通无焦点状态 --> <item android:state_focused="false" android:state_pressed="false" android:drawable="@drawable/thumb_normal" /> <!-- 有焦点状态--> <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/thumb_normal" /> <!-- 有焦点 --> <item android:state_focused="true" android:drawable="@drawable/thumb_normal" /></selector>
===================================
注:在实际应用中对上面代码进行了多次调优,这里把最终发布版本的代码再共享下,效果图如下:
核心代码(优化部分,和上面相同的就不再重复了):
@Overridepublic void onProgressChanged(SeekBar paramSeekBar, int progress,boolean fromUser) {// Log.i("onProgressChanged=", "cc progress=" + progress//+ " lastProgress=" + lastProgress + " newProgress="//+ newProgress);//+- 20 根据滑动条的宽度确定对应的比例if (progress > newProgress + 20 || progress < newProgress - 20) {newProgress = lastProgress;paramSeekBar.setProgress(lastProgress);return;}newProgress = progress;}@Overridepublic void onStartTrackingTouch(SeekBar paramSeekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar paramSeekBar) {// Log.i("onStopTrackingTouch=", " lastProgress=" + lastProgress//+ " newProgress=" + newProgress+ " functionType=" + functionType);if(newProgress == lastProgress){return;}if("proximitytag".equals(functionType) && newProgress <30 ){lastProgress = 0;newProgress = 0;paramSeekBar.setProgress(0);return;}if("findme".equals(functionType) && newProgress >70){lastProgress = 100;newProgress = 100;paramSeekBar.setProgress(100);return;}if("stop".equals(functionType) && newProgress >30 && newProgress <70){lastProgress = 50;newProgress = 50;paramSeekBar.setProgress(50);return;}if (newProgress < 30) {lastProgress = 0;newProgress = 0;paramSeekBar.setProgress(0);functionType = "proximitytag";} else if (newProgress > 70) {// 设置lastProgress 要放在setProgress之前,否则可能导致执行多次onProgressChanged 改变了原值lastProgress = 100;newProgress = 100;paramSeekBar.setProgress(100);functionType = "findme";} else {lastProgress = 50;newProgress = 50;paramSeekBar.setProgress(50);functionType = "stop";}Log.v("onStopTrackingTouch2=", " lastProgress=" + lastProgress+ " newProgress=" + newProgress);changeProgressStateImg(lastProgress);}public void changeProgressStateImg(int last_progress) {ImageView proximitytag = (ImageView) MainActivity.this.findViewById(R.id.proximitytag);ImageView stop = (ImageView) MainActivity.this.findViewById(R.id.stop);ImageView findme = (ImageView) MainActivity.this.findViewById(R.id.findme);proximitytag.setBackgroundResource(R.drawable.proximityblack);stop.setBackgroundResource(R.drawable.stopblack);findme.setBackgroundResource(R.drawable.findblack);if (last_progress == 0) {proximitytag.setBackgroundResource(R.drawable.proximityblue);} else if (last_progress == 50) {stop.setBackgroundResource(R.drawable.stopblue);} else {findme.setBackgroundResource(R.drawable.findblue);}}