Android 三档自定义滑动开关,禁止点击功能的实现,用默认的seekbar组件实现

android三档自定义滑动开关,禁止点击功能的实现,普通开关网上有很多例子,三档滑动开关的则找了整天都没有相关例子,开始用普通开关的源码修改了自己实现了一个类,但效果不如人意,各种边界情况的算法很难考虑周全很难调试出满意的效果。

今 天尝试用系统组件seekbar实现自定义风格的滑动条,但禁止点击和判断滑动不到指定范围返回花了不少时间,网上基本上都说用继承seekbar修改里 面的方法实现,但整了半天也没有一个能够达到效果了,而且感觉太麻烦了,所以自己把默认的实现的几个接口返回的信息详细打印出来调试了下,发现可以通过返 回参数来实现自己想要的结果。

先上个效果图

核心部分代码:

private SeekBar seekbar;

private int lastProgress = 0;

private int newProgress = 0;

seekbar = (SeekBar)findViewById(R.id.seekBar);
        seekbar.setOnSeekBarChangeListener(this);
        //lastProgress=? 从配置文件中读取
        seekbar.setProgress(lastProgress);

1

@Overridepublic 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;
    }

    @Override
    public void onStartTrackingTouch(SeekBar paramSeekBar) {
        Log.i("onStartTrackingTouch="," lastProgress="+ lastProgress+" newProgress="+ newProgress);

    }

    @Override
    public 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里面的布局

         <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="25dip" >

                <SeekBar
                    android: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="http://schemas.android.com/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="http://schemas.android.com/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> 

===================================

注:在实际应用中对上面代码进行了多次调优,这里把最终发布版本的代码再共享下,效果图如下:

核心代码(优化部分,和上面相同的就不再重复了):

@Override
public 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;
    }

    @Override
    public void onStartTrackingTouch(SeekBar paramSeekBar) {

    }

    @Override
    public 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);
        }
    }
时间: 2024-10-21 12:04:15

Android 三档自定义滑动开关,禁止点击功能的实现,用默认的seekbar组件实现的相关文章

Android自定义按钮实现长按功能

通过自定义BUTTON,写一个LongTouchBtn类,在按下的时候执行onTouchEvent事件,通过这个事件使用回调函数来实现长按功能! XML: <huahua.btnlongtouch.LongTouchBtn android:id="@+id/btn2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text=&q

【android】自定义组合控件PullToRefreshRecyeclerView

场景:自从Android 5.0发布以来,越来越多的开发者开始接触RecyeclerView,但是RecyclerView如何实现下拉刷新,上拉加在更多.于是我就偷懒 写了一个,以供大家参考和学习,以待大家改进. 构思:想必大家对SwipeRefreshLayout这个控件有一定了解,没错本次自定义组合控件也就是SwipeRefreshLayout与RecyeclerView的组合. 那么我们一步一步来实现: 1.首先写一个组合布局如下:pulltorefreshrecyclerview.xml

Android SwitchButton(滑动开关)

版本:1.0 日期:2014.5.17 2014.6.1 版权:© 2014 kince 转载注明出处 在介绍SwitchButton之前,先来看一下系统Button是如何实现的.源码如下: @RemoteView public class Button extends TextView { public Button(Context context) { this(context, null); } public Button(Context context, AttributeSet att

Android进阶——自定义View之自己绘制彩虹圆环调色板

引言 前面几篇文章都是关于通过继承系统View和组合现有View来实现自定义View的,刚好由于项目需要实现一个滑动切换LED彩灯颜色的功能,所以需要一个类似调色板的功能,随着手在调色板有效区域滑动,LED彩灯随即显示相应的颜色,也可以通过左右的按钮,按顺序切换显示一组颜色,同时都随着亮度的改变LED彩灯的亮度随即变化,这篇基本上把继承View重绘实现自定义控件的大部分知识总结了下(当然还有蛮多没有涉及到,比如说自适应布局等),源码在Github上 一.继承View绘制自定义控件的通用步骤 自定

Android Studio 3.0 下载 使用新功能介绍

谷歌2017发布会更新了挺多内容的,而且也发布了AndroidStudio3.0预览版,一些功能先睹为快.(英语一般,有些翻译不太好) 下载地址 https://developer.android.google.cn/studio/archive.html 选择显示全部即可看到下载地址,这里给出来了. Windows (64-bit): android-studio-ide-171.4010489-windows.zip (702075896 bytes) https://dl.google.c

android中自定义下拉框(转)

android自带的下拉框好用不?我觉得有时候好用,有时候难有,项目规定这样的效果,自带的控件实现不了,那么只有我们自己来老老实实滴写一个新的了,其实最基本的下拉框就像一些资料填写时,点击的时候出现在编辑框的下面,然后又很多选项的下拉框,可是我在网上找了一下,没有这种下拉框额,就自己写了一个,看效果图先: ,这个是资料填写的一部分界面,三个下拉框,选择故乡所在地: 点击之后弹出下拉框,选择下面的选项: 三个下拉框时关联的,第一个决定了第二数据内容,第二个决定了第三个数据内容,如果三个全部选好之后

Android中自定义视图View之---前奏篇

前言 好长时间没写blog了,心里感觉有点空荡荡的,今天有时间就来写一个关于自定义视图的的blog吧.关于这篇blog,网上已经有很多案例了,其实没什么难度的.但是我们在开发的过程中有时候会用到一些自定义的View以达到我们所需要的效果.其实网上的很多案例我们看完之后,发现这部分没什么难度的,我总结了两点: 1.准备纸和笔,计算坐标 2.在onDraw方法中开始画图,invalidate方法刷新,onTouchEvent方法监听触摸事件 对于绘图相关的知识,之前在弄JavaSE相关的知识的时候,

Android中自定义视图View之---开发案例

自定义视图View的案例 下面我们就是开始正式的进入自定义视图View了 在讲解正式内容之前,我们先来看一下基本知识 1.我们在自定义视图View的时候正确的步骤和方法 1).必须定义有Context/Attrbuite参数的构造方法,并且调用父类的方法 public LabelView(Context context, AttributeSet attrs) 不然会报错: 2).重写onMeasure方法 @Override protected void onMeasure(int width

android selector(如对TextView点击样式改变)

selector 1.selector 从单词的意思来说:选择者,选择器,就是对你的目标的控制. 从API来说: A controller for the selection of SelectableChannel objects. Selectable channels can be registered with a selector and get a SelectionKey that represents the registration. The keys are also add