How can I make an Android seek-bar move smoothly?

前端 未结 5 1347
故里飘歌
故里飘歌 2021-02-04 11:05

I\'m trying to make a SeekBar move more smoothly than just jumping straight to the position. I\'m doing this as I\'ve got a SeekBar with 3 options for a slider-type implementati

相关标签:
5条回答
  • 2021-02-04 11:24

    Built my own control. Job done :) Code here

    0 讨论(0)
  • 2021-02-04 11:29

    I found the following solution to make the seekbar move smoothly, yet still snap to a limited range of values. Assuming you have the following views in your layout:

    <SeekBar
      android:id="@+id/sldProgress"
      style="@style/MySliderStyle"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:max="100"
      android:progress="50" />
    
    <TextView
      android:id="@+id/lblProgress"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="5" />
    

    You can use the following code in your activity (change the value of android:max in the above xml, and the smoothness factor in the code below according to your needs - higher values = smoother):

    public class MyActivity extends Activity {
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        sliderListener sldListener = new sliderListener();
        SeekBar sldProgress = (SeekBar) findViewById(R.id.sldProgress);
        sldProgress.setOnSeekBarChangeListener(sldListener);
      }
      private class sliderListener implements OnSeekBarChangeListener {
        private int smoothnessFactor = 10;
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
          progress = Math.round(progress / smoothnessFactor);
          TextView lblProgress = (TextView) findViewById(R.id.lblProgress);
          lblProgress.setText(String.valueOf(progress));
        }
    
        public void onStartTrackingTouch(SeekBar seekBar) {
        }
    
        public void onStopTrackingTouch(SeekBar seekBar) {
          seekBar.setProgress(Math.round((seekBar.getProgress() + (smoothnessFactor / 2)) / smoothnessFactor) * smoothnessFactor);
        }
      }
    }
    
    0 讨论(0)
  • 2021-02-04 11:37

    You don't need to build anything by yourself just user android animation it will do the thing for you

    The code written in kotlin

        mySeekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
                //Todo: code
            }
    
            override fun onStartTrackingTouch(seekBar: SeekBar?) {
            }
    
            override fun onStopTrackingTouch(seekBar: SeekBar) {
                if (seekBar.progress > 70) {
                    ObjectAnimator.ofInt(seekBar, "progress", 100).setDuration(100).start()
                } else if (seekBar.progress < 30) {
                    ObjectAnimator.ofInt(seekBar, "progress", 0).setDuration(100).start()
                } else {
                    ObjectAnimator.ofInt(seekBar, "progress", 50).setDuration(100).start()
                }
            }
        })
    
    0 讨论(0)
  • 2021-02-04 11:41

    This works fine for me, quite simple and straight forward.

    if (currentPosition > 0) {
        ObjectAnimator animation = ObjectAnimator.ofInt(seekBar, "progress", currentPosition);
        animation.setDuration(400);
        animation.setInterpolator(new DecelerateInterpolator());
        animation.start();
    }
    
    0 讨论(0)
  • 2021-02-04 11:41

    Create a custom SeekBar

    public class SmoothSeekBar extends AppCompatSeekBar implements SeekBar.OnSeekBarChangeListener {
    
    private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener;
    
    private boolean mNeedCallListener = true;
    
    private ValueAnimator mAnimator;
    
    public SmoothSeekBar(Context context) {
        super(context);
        init(context);
    }
    
    public SmoothSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }
    
    public SmoothSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }
    
    
    public void init(Context context) {
        Context mContext = context;
    }
    
    @Override
    public void setOnSeekBarChangeListener(
            SeekBar.OnSeekBarChangeListener onSeekBarChangeListener) {
        mOnSeekBarChangeListener = onSeekBarChangeListener;
        super.setOnSeekBarChangeListener(this);
    }
    
    @Override
    public void setProgress(final int progress) {
        final int currentProgress = getProgress();
        if (mAnimator != null) {
            mAnimator.cancel();
            mAnimator.removeAllUpdateListeners();
            mAnimator.removeAllListeners();
            mAnimator = null;
            mNeedCallListener = true;
        }
        mAnimator = ValueAnimator.ofInt(currentProgress, progress);
        mAnimator.setDuration(getResources().getInteger(android.R.integer.config_longAnimTime));
        mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (int) animation.getAnimatedValue();
                if (value == progress) {
                    mNeedCallListener = true;
                } else {
                    mNeedCallListener = false;
                }
                Logger.e("ProgressBar value ", value + "");
                SmoothSeekBar.super.setProgress(value);
            }
        });
        mAnimator.start();
    
    }
    
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (fromUser || mNeedCallListener) {
            if (mOnSeekBarChangeListener != null) {
                mOnSeekBarChangeListener.onProgressChanged(seekBar, progress, fromUser);
            }
        }
    }
    
    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        if (mOnSeekBarChangeListener != null) {
            mOnSeekBarChangeListener.onStartTrackingTouch(seekBar);
        }
    }
    
    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        if (mOnSeekBarChangeListener != null) {
            mOnSeekBarChangeListener.onStopTrackingTouch(seekBar);
        }
    }
    }
    

    Now add SeekBar in xml and enjoy

     <com.yourPackage.SmoothSeekBar
        android:id="@+id/seekBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    
    0 讨论(0)
提交回复
热议问题