zoukankan      html  css  js  c++  java
  • 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 @Override

     2     public void onProgressChanged(SeekBar paramSeekBar, int progress,
     3             boolean fromUser) {
     4         Log.i("onProgressChanged=","cc progress="+ progress + " lastProgress="+ lastProgress+" newProgress="+ newProgress);
     5         if(progress >newProgress+10 || progress<newProgress-10){
     6             newProgress = lastProgress;
     7             paramSeekBar.setProgress(lastProgress);
     8             return;
     9         }
    10 
    11         newProgress = progress;
    12     }
    13 
    14     @Override
    15     public void onStartTrackingTouch(SeekBar paramSeekBar) {
    16         Log.i("onStartTrackingTouch="," lastProgress="+ lastProgress+" newProgress="+ newProgress);
    17         
    18     }
    19 
    20     @Override
    21     public void onStopTrackingTouch(SeekBar paramSeekBar) {
    22         Log.i("onStopTrackingTouch="," lastProgress="+ lastProgress+" newProgress="+ newProgress);
    23         
    24         if(newProgress<30){
    25             lastProgress = 0;
    26             newProgress =0;
    27             paramSeekBar.setProgress(0);
    28         }else if(newProgress>70){
    29             //设置lastProgress 要放在setProgress之前,否则可能导致执行多次onProgressChanged 改变了原值
    30             lastProgress = 100;
    31             newProgress = 100;
    32             paramSeekBar.setProgress(100);
    33         }else{
    34             lastProgress = 50;
    35             newProgress =50;
    36             paramSeekBar.setProgress(50);
    37         }
    38         Log.v("onStopTrackingTouch2="," lastProgress="+ lastProgress+" newProgress="+ newProgress);
    39         changeProgressStateImg(lastProgress);
    40     }

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

    相关自定义样式,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);
            }
        }
    大自然,飘然的风,QQ群: python技术交流群:453879716,人工智能深度学习群:251088643
    golang技术交流群:316397059,vuejs技术交流群:458915921 渗透技术:534096581,囤币一族:621258209,有兴趣的可以加入
    微信公众号:大自然预测(ssqyuce)原双色球预测, 心禅道(xinchandao)
  • 相关阅读:
    uboot向内核模块传递参数的方法
    arm下用shell控制gpio
    u-boot的内存分布和全局数据结构
    Ambarella SDK build 步骤解析
    MMU段式映射(VA -> PA)过程分析
    ambarella H2 添加文件到ext4文件系统
    使用U-Boot的TFTP(远程/网络内核)
    使用U-Boot的NFS(远程/网络用户空间)
    君正Ingenic X1000E_halley2 更改Logo
    【自动化测试】robotframework中一些建议可能需要掌握的关键字
  • 原文地址:https://www.cnblogs.com/zdz8207/p/seekbar_three.html
Copyright © 2011-2022 走看看