在Android中实现滑块(SeekBar)

时间:2011-12-25 12:12:50

标签: android slider touch seekbar

我想实现一个滑块,它基本上是两条线,一条垂直线和一条水平线,交叉点触摸屏幕。我设法制作一个,但我必须提出问题:

  1. 滑块不是很平滑,当我移动手指时有轻微的延迟
  2. 如果我放置两个滑块,它不是多点触控,我想同时使用它们
  3. 以下是代码:

    public class Slider extends View {
    
        private Controller controller = new Controller();
        private boolean initialisedSlider;
        private int sliderWidth, sliderHeight;
        private Point pointStart;
        private Paint white;
        private int mode;
    
        final static int VERTICAL = 0, HORIZONTAL = 1, BOTH = 2;
    
        public Slider(Context context) {
            super(context);
            setFocusable(true);    
            // TODO Auto-generated constructor stub
        }
        public Slider(Context context, AttributeSet attrs) {
            super(context, attrs);     
            setFocusable(true);    
            pointStart = new Point();
            initialisedSlider = false;   
            mode = Slider.BOTH;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            if(!initialisedSlider) {
                initialisedSlider = true;
                sliderWidth = getMeasuredWidth();
                sliderHeight = getMeasuredHeight();
    
                pointStart.x = (int)(sliderWidth/2.0);
                pointStart.y = (int)(sliderHeight/2.0);
                controller = new Controller(pointStart, 3);
    
                white = new Paint();
                white.setColor(0xFFFFFFFF);
            }
    
            canvas.drawLine(controller.getCoordX(),0,
                            controller.getCoordX(),sliderHeight, 
                            white);
            canvas.drawLine(0, controller.getCoordY(), 
                            sliderWidth, controller.getCoordY(), 
                            white);
    
        }
    
        public boolean onTouchEvent(MotionEvent event) {
            int eventaction = event.getAction();     
            int X = (int)event.getX(); 
            int Y = (int)event.getY(); 
            switch (eventaction) { 
            case MotionEvent.ACTION_DOWN:
                if(isInBounds(X,Y)) {
                    updateController(X, Y);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if(isInBounds(X,Y)) {
                    updateController(X, Y);
                }
                break;
            case MotionEvent.ACTION_UP:
                if(isInBounds(X,Y)) {
                    updateController(X, Y);
                }
                break;
            }
            invalidate();  
            return true; 
        }
    
        private boolean isInBounds(int x, int y) {
            return ((x<=(sliderWidth)) && (x>=(0)) 
                     && (y<=(sliderHeight)) && (y>=(0)));
        }
        private void updateController(int x, int y) {
            switch(mode) {
            case Slider.HORIZONTAL:
                controller.setCoordX(x);
                break;
            case Slider.VERTICAL:
                controller.setCoordY(y);
                break;
            case Slider.BOTH:
                controller.setCoordX(x);
                controller.setCoordY(y);
                break;
            }
        }
    
        private class Controller {
            private int coordX, coordY;
            Controller() {
    
            }
            Controller(Point point, int width) {
                setCoordX(point.x);
                setCoordY(point.y);
            }
            public void setCoordX(int coordX) {
                this.coordX = coordX;
            }
            public int getCoordX() {
                return coordX;
            }
            public void setCoordY(int coordY) {
                this.coordY = coordY;
            }
            public int getCoordY() {
                return coordY;
            }
        }
    }
    

    XML文件:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello" />
        <com.android.lasttest.Slider 
            android:id="@+id/slider"
            android:layout_width="100dp" 
            android:layout_height="100dp" 
            android:layout_gravity="center_horizontal" 
            android:adjustViewBounds="true"/>
        <com.android.lasttest.Slider 
            android:id="@+id/slider"
            android:layout_width="150dp" 
            android:layout_height="150dp" 
            android:layout_gravity="center_horizontal" 
            android:adjustViewBounds="true"/>
        <com.android.lasttest.Slider 
            android:id="@+id/slider"
            android:layout_width="200dp" 
            android:layout_height="200dp" 
            android:layout_gravity="center_horizontal" 
            android:adjustViewBounds="true"/>
    
    </LinearLayout>
    

3 个答案:

答案 0 :(得分:18)

答案 1 :(得分:11)

如何实现SeekBar

enter image description here

将SeekBar添加到您的布局

max

注释

  • 100是搜索栏可以访问的最高值。默认值为0。最低为min。 xml 0-100值仅在API 26中提供,但您可以通过编程方式将progress范围转换为早期版本所需的范围。
  • android:rotation="270"是滑点的初始位置(称为&#34;拇指&#34;)。
  • 对于垂直SeekBar,请使用public class MainActivity extends AppCompatActivity { TextView tvProgressLabel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // set a change listener on the SeekBar SeekBar seekBar = findViewById(R.id.seekBar); seekBar.setOnSeekBarChangeListener(seekBarChangeListener); int progress = seekBar.getProgress(); tvProgressLabel = findViewById(R.id.textView); tvProgressLabel.setText("Progress: " + progress); } SeekBar.OnSeekBarChangeListener seekBarChangeListener = new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // updated continuously as the user slides the thumb tvProgressLabel.setText("Progress: " + progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) { // called when the user first touches the SeekBar } @Override public void onStopTrackingTouch(SeekBar seekBar) { // called after the user finishes moving the SeekBar } }; }

侦听代码中的更改

onStopTrackingTouch

注释

  • 如果您在用户移动搜索栏时不需要进行任何更新,那么您只需更新AppDomain.CurrentDomain.SetupInformation.ConfigurationFile中的用户界面。

另见

答案 2 :(得分:0)

供将来的读者使用!

material components android 1.2.0-alpha01开始,您将拥有slider组件

例如:

<com.google.android.material.slider.Slider
        android:id="@+id/slider"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:valueFrom="20f"
        android:valueTo="70f"
        android:stepSize="10" />