web-dev-qa-db-fra.com

Implémentation d'un curseur (SeekBar) dans Android

Je veux implémenter un curseur, qui est essentiellement deux lignes, une verticale et une horizontale, traversant l'endroit où l'écran est touché. J'ai réussi à en faire un mais je dois des problèmes:

  1. Le curseur n'est pas très lisse, il y a un léger retard lorsque je bouge le doigt
  2. Si je place deux curseurs, ce n'est pas du multitouch et j'aimerais les utiliser simultanément

Voici le code:

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

Et le fichier 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>
20
Flavian Hautbois
20
Amit Hooda

Comment implémenter un SeekBar

enter image description here

Ajoutez le SeekBar à votre mise en page

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="vertical"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <TextView
        Android:id="@+id/textView"
        Android:layout_margin="20dp"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"/>

    <SeekBar
        Android:id="@+id/seekBar"
        Android:max="100"
        Android:progress="50"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"/>

</LinearLayout>

Remarques

  • max est la valeur la plus élevée à laquelle la barre de recherche peut aller. La valeur par défaut est 100. Le minimum est 0. La valeur xml min n'est disponible qu'à partir de l'API 26, mais vous pouvez simplement convertir par programme le 0-100 gamme à tout ce dont vous avez besoin pour les versions antérieures.
  • progress est la position initiale du point de curseur (appelé "pouce").
  • Pour un SeekBar vertical, utilisez Android:rotation="270".

Écoutez les changements de code

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

Remarques

  • Si vous n'avez pas besoin de faire de mises à jour pendant que l'utilisateur déplace la barre de recherche, vous pouvez simplement mettre à jour l'interface utilisateur dans onStopTrackingTouch.

Voir également

16
Suragch