SeekBar平滑滚动修改

平台:Android2.3
场景:Hifi播放器,使用原生的SeekBar进行音量的调节,是一种音量骤变的效果(从50点到200,50->200值的跳变)。这样的用户体验有些糟糕。所以客户需求,调节音量时,当值的设定跨度很大时,采用平滑渐进的设定方式,即50,52,54,,,,200.
时间:2011.11.15

前提:
1.采用了定制组件+Apk响应的实现方式

2.需求主要分为:
1).音量平滑设定。对于音量的控制由底层提供接口,在SeekBar中的调节,只需要对应上每次setProgress()设定的值即可。在Apk中,重载SeekBar的onProgressChanged()函数时,进行设定即可。
2).SeekBar的平滑滚动修改

3.SeekBar继承与AbsSeekBar,修改相关两个核心函数:负责UI刷新的onProgressRefresh(),负责交互的trackTouchEvent(),其中的setProgress()调用是修改切入点。
具体思路,截断trackTouchEvent()中setProgress()的调用,增加一个定时器来分解值的设定。同时由于涉及到UI的更新,需要通过Handler来协助处理,否则可能造成主线程的阻塞。

修改:

    private boolean WISKY_DEBUG = true;
    private String TAG = "SeekBar";
    private static int refreshTime = 50;            //执行频率(ms)
    private final MySeekBar mySeekbar = this;
    private static int absValue = 0;                    //控制刷新次数
    private Timer timer;
    private Handler h = null;
    private Message message = null;
    private static final int INVALIDATE = 1;
    private static int mRefershFlag;                            //刷新标志----1,递增。0,递减.
    private boolean isFinished = false;                     //是否完成移动操作
    private boolean isTimerOn = false;                      //定时器是否开启

    private static final int volume_level = 18;     //音量设置单步长度
        h = new Handler(){
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                switch(msg.what) {
                case INVALIDATE:
                            TimerRunner();          
                    break;
                default:
                    break;
                }

                super.handleMessage(msg);
            }
        };
        private void setTimer(){

                        isFinished = false;
                isTimerOn = true;

                        if(timer == null){
                            timer = new Timer();
                            timer.schedule(new TimerTask(){

                                            @Override
                                            public void run() {
                                                        if (null == message) {
                                                            message = new Message();
                                                        } else {
                                                            message = Message.obtain();
                                                        }

                                                    message.what = INVALIDATE;
                                                        h.sendMessage(message);

                                                    //absValue--;                       //次数递减
                                                    absValue = absValue - volume_level;
                                                    if(absValue <= 0 ){
                                                                    cancelTimer();
                                                    }


                                            }}, 0, refreshTime);
                        }                           

        }
        private void cancelTimer(){

                if(timer != null){
                    timer.cancel();
                    timer = null;
                }

                isFinished = true;
                isTimerOn = false;

        }
        private void TimerRunner(){
                                                            int curProgress = getProgress();
                                                            if(WISKY_DEBUG) Log.i(TAG, "My__TimerRunner()______enter curProgress is " + String.valueOf(curProgress));

                                                            if(mRefershFlag == 1){                      //递增
                                                                    curProgress = curProgress + volume_level;
                                                                    mySeekbar.setProgress(curProgress, true);
                                                            }
                                                            else{                                           //递减
                                                                    curProgress = curProgress - volume_level;
                                                                    mySeekbar.setProgress(curProgress, true);
                                                            }


        }
    private void trackTouchEvent(MotionEvent event) {
...
//  setProgress((int) progress, true);
        absValue = Math.abs(getProgress() - (int)progress);
        //单次移动大于24时,启动timer进行自动滑动
        if(absValue > 24){
                    if(WISKY_DEBUG) Log.i(TAG, "My__trackTouchEvent()__enter____________my if_______absValue is " + String.valueOf(absValue));
                    if(getProgress() >= (int)progress){
                            mRefershFlag = 0;                   //之前的比现在的大---递减
                    }
                    else{
                            mRefershFlag = 1;                   //递增
                    }

                    setTimer();

        }
        else{
                    if(WISKY_DEBUG) Log.i(TAG, "My__trackTouchEvent()__enter____________else______________________________________");
                    if(timer == null){          //定时器已经释放掉---定时器存在时,不让进行设置progress
                            setProgress((int) progress, true);
                    }
        }
    }
        public boolean getisTimerOn(){

                return isTimerOn;
        }


        public boolean getisFinished(){

                return isFinished;
        }

        public void setisFinished(boolean isfinished){

                    isFinished = isfinished;
        }

经过上面对SeekBar的重写后,在Apk中调用进行相关的配合调用即可。

后话:时间太久远,好不容易看懂自己乱七八糟的代码。当时真的是为了实现功能而实现,后续没有任何整理。代码也是脏乱差。-_-!!!
整个实现的代码link:链接:http://pan.baidu.com/s/1dDxrcOh 密码:disx

你可能感兴趣的:(SeekBar平滑滚动修改)