Impedire il singolo touch di cambiare SeekBar progresso

Sto utilizzando un SeekBar nella mia applicazione Android. Quando un utente singolo tocca ovunque sul SeekBar , il suo valore di avanzamento viene modificato. Voglio solo che il valore di avanzamento cambia quando l'utente fa scorrere il pollice SeekBar (proprio come un UISlider in iOS).

Ho provato a impostare la properties; clickable del SeekBar su falso ma che non funzionava. Come posso get il comportmento desiderato?

  • Come caricare le foto con il text nella stessa richiesta?
  • Riproduce il suono nell'altoparlante sinistro o destro usando android AudioTrack
  • android: utilizzando ActivityGroup per incorporare le attività
  • Binding dei dati di Android utilizzando il tag include
  • Import SDK di Facebook per Android Studio 0.3.1
  • Imansible utilizzare il command atrace delle shell di Android a causa dell'accesso di scrittura
  • Utilizzo di getResources () in class non attività
  • Imansible get ScrollView per scorrere quando viene visualizzata la tastiera soft
  • Come installare JavaCV su Android e utilizzare FrameGrabber
  • creare busta di soap con intestazione di sicurezza in android usando ksoap2
  • Come utilizzare SQLiteOpenHelper con database su scheda SD?
  • Invia una richiesta JSONArray POST con la libreria di androidi volley
  • 11 Solutions collect form web for “Impedire il singolo touch di cambiare SeekBar progresso”

    Ho affrontato la stessa questione questa settimana e ho risolto con un custom SeekBar: seguendo il mio codice:

     public class Slider extends SeekBar { private Drawable mThumb; public Slider(Context context) { super(context); } public Slider(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void setThumb(Drawable thumb) { super.setThumb(thumb); mThumb = thumb; } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (event.getX() >= mThumb.getBounds().left && event.getX() <= mThumb.getBounds().right && event.getY() <= mThumb.getBounds().bottom && event.getY() >= mThumb.getBounds().top) { super.onTouchEvent(event); } else { return false; } } else if (event.getAction() == MotionEvent.ACTION_UP) { return false; } else { super.onTouchEvent(event); } return true; }} 

    Spero che questo ti aiuti

    Guarda questo altro thread:

    L'utente non può interagire con il Seekbar

    Ho provato quanto segue e funziona bene. Nota che la mia barra di ricerca ha properties; android: max impostata a 100 come questo:


     <SeekBar android:id="@+id/EnableBar" android:layout_span="2" android:max="100" /> 

     package com.androidbook.hiworld; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; import android.widget.SeekBar; public class HiWorldActivity extends Activity { int originalProgress; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); SeekBar seek = (SeekBar)findViewById(R.id.EnableBar); seek.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() { public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { ((TextView)findViewById(R.id.SeekTxt)).setText("Value: "+progress); if(fromTouch == true){ // only allow changes by 1 up or down if ((progress > (originalProgress+24)) || (progress < (originalProgress-24))) { seekBar.setProgress( originalProgress); } else { originalProgress = progress; } } } @Override public void onStopTrackingTouch(SeekBar seekBar) { //Nothing here.. } @Override public void onStartTrackingTouch(SeekBar seekBar) { originalProgress = seekBar.getProgress(); } }); } } 

    È troppo tardi, ma forse qualcuno avrà bisogno della soluzione. Estendo la SeekBar personalizzata e sovrascrivendo onTouchEvent.

     package com.timera.android.common.view; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.SeekBar; public class OnlySeekableSeekBar extends SeekBar { public OnlySeekableSeekBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public OnlySeekableSeekBar(Context context, AttributeSet attrs) { super(context, attrs); } public OnlySeekableSeekBar(Context context) { super(context); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: final int width = getWidth(); final int available = width - getPaddingLeft() - getPaddingRight(); int x = (int) event.getX(); float scale; float progress = 0; if (x < getPaddingLeft()) { scale = 0.0f; } else if (x > width - getPaddingRight()) { scale = 1.0f; } else { scale = (float) (x - getPaddingLeft()) / (float) available; } final int max = getMax(); progress += scale * max; if (progress < 0) { progress = 0; } else if (progress > max) { progress = max; } if (Math.abs(progress - getProgress()) < 10) return super.onTouchEvent(event); else return false; default: return super.onTouchEvent(event); } } } 

    Ho trovato una soluzione per questo, non è molto carina, ma dovrebbe fare il trucco …

    Ecco l'idea:

    1. Creare un sovrapposizione invisibile che coprirà tutto il cursore tranne il button di pollice

      (Ho usato una barra di ricerca blacked out per agire come overlay)

    2. Quando si preme il pollice, call il metodo "bringToFront" sul cursore

    3. Quando il pollice viene rilasciato, call il metodo "bringToFront" sull'overlay invisibile

    Nota per questo per funzionare è necessario modificare la dimensione della sovrapposizione in modo che coprirà tutto tranne il button del pollice (suggerisco di utilizzare due sovrapposizioni [uno per each lato del button di pollice])

    Quando rilasciate il button del pollice dovresti ridimensionare le sovrapposizioni

    … come ho detto, non è bello. Sono sicuro che ci sono modi molto migliori per farlo, ma se devi farlo, proverei questo.

      yourBarChangeListener yourBarChangeListener = new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { // YOUR CODE HERE } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }; yourBar.setOnSeekBarChangeListener(yourBarChangeListener); 
      int oldProgress; boolean isOn = true; vSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStartTrackingTouch(SeekBar seekBar) { oldProgress = seekBar.getProgress(); } @Override public void onStopTrackingTouch(SeekBar seekBar) { if (oldProgress == seekBar.getProgress()) { if (isOn) { seekBar.setThumb(getResources().getDrawable(R.drawable.blck_btn)); isOn = false; } else { seekBar.setThumb(getResources().getDrawable(R.drawable.blck_btn_selected)); isOn = true; } } } 

    È ansible confrontare i progressi quando si effettua la traccia di arresto.

    guardando codice @lordmegamax, ho trovato qualcosa che non funziona.

    1. int oldProgress non può rimanere in onCreate, devi dichiararlo all'esterno.
    2. se si cercaBar comincia sempre dall'inizio, onStartTrackingTouch restituirà sempre 0, quindi il tuo onStopTrackingTouch non functionrà mai.

    Pensando un po ', ho trovato una soluzione.

     //SeekBar Slide skbLogin.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { //Force Slide From Beginning public void onStartTrackingTouch(SeekBar seekBar) { continuosProgress = false; } //Execute when reach the max public void onStopTrackingTouch(SeekBar seekBar) { if(continuosProgress) if(seekBar.getProgress() == 100) btnLogin(); else skbRollBack(); else seekBar.setProgress(0); } //Check Slide from Beginning public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if(progress < 10) continuosProgress = true; } }); 

    Spero che sia d'aiuto. i migliori saluti

    PS: questo è il mio primo post, mi dispiace se facessi qualcosa di sbagliato.

    Questo funziona perfettamente con l'ascoltatore di events all'interno di SeekBar.

    PS. Ho migliorato questo codice da Slim per renderlo più generalizzato.

     /** * ProtectedSeekBar * 01/27/15 * * @author Jetsada Machom <jim@imjim.im> */ public class ProtectedSeekBar extends SeekBar { private Drawable mThumb; public ProtectedSeekBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public ProtectedSeekBar(Context context, AttributeSet attrs) { super(context, attrs); } public ProtectedSeekBar(Context context) { super(context); } @Override public void setThumb(Drawable thumb) { super.setThumb(thumb); mThumb = thumb; } @Override public boolean onTouchEvent(MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN) { if( event.getX() < mThumb.getBounds().left || event.getX() > mThumb.getBounds().right || event.getY() > mThumb.getBounds().bottom || event.getY() < mThumb.getBounds().top) { return false; } } return super.onTouchEvent(event); } } 

    Con questo codice è ansible distriggersre il pollice per spostarsi da parte dell'utente

      SeekBar progress = (SeekBar) findViewById(R.id.timer); seekBar.setProgress(time); 

    where "tempo" è una variabile integer e tiene premuto il progresso

      progress.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if(fromUser){ seekBar.setProgress(time); } } }); 
     private class UpdateListener implements OnSeekBarChangeListener { // max step user can change at once private static final int THUMB_MAX_MOVE = 5; // current seekbar value (50 is initial seekbar value as defined in xml) private int currentProgress = 50; @Override public void onStartTrackingTouch(SeekBar seekBar) { // save current value before user jumps around currentProgress = seekBar.getProgress(); } @Override public void onStopTrackingTouch(SeekBar seekBar) {} @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // check if we've jumped too far if (Math.abs(currentProgress - progress) > THUMB_MAX_MOVE) { // if so, revert to last progress and return seekBar.setProgress(currentProgress); return; } // if not, move was valid and update current progress currentProgress = progress; // do anything more here } } 

    Un'altra opzione che non vedo ancora suggerisce: una sottoclass che traduce gli events di movimento ricevuti per far apparire che each gesto inizia dal centro del pollice. Ciò ha i seguenti impatti sul comportmento della barra di ricerca sottostante:

    • tapping sul posto non produce alcun movimento del pollice (come tutte le altre soluzioni proposte);
    • eseguire un gesto di scorrimento che si allontana dal pollice può ancora tradurre correttamente il pollice (diverso da altre soluzioni proposte).

    Codice

     /** * Translates every gesture to be centered at the current thumb location. */ public final class ThumbCentricSeekBar extends SeekBar { // Constructors go here... private Float offsetX; private Float offsetY; @Override public boolean onTouchEvent(final MotionEvent event) { if (event.getAction() == ACTION_DOWN && offsetX == null) { offsetX = getThumb().getBounds().centerX() - event.getX(); offsetY = getThumb().getBounds().centerY() - event.getY(); } event.offsetLocation(offsetX, offsetY); if (event.getAction() == ACTION_UP) { offsetX = null; offsetY = null; } return super.onTouchEvent(event); } } 

    dimostrazione

    La posizione di touch viene mostrata per illustrare il comportmento descritto.

    immettere qui la descrizione dell'immagine

    Per disabilitare un singolo touch su seebBar si può guardare il tempo tra gli events DOWN e UP, di solito la durata del singolo touch less di 100 ms.

     seekBar.setOnTouchListener(new View.OnTouchListener() { private long startTime = 0; private long endTime = 0; @Override public boolean onTouch(View view, MotionEvent motionEvent) { if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { startTime = motionEvent.getEventTime(); return true; } if (motionEvent.getAction() == MotionEvent.ACTION_UP) { endTime = motionEvent.getEventTime(); if (Math.abs(startTime-endTime)<=100) return true; else return false; } Log.d(TAG, String.valueOf(motionEvent.getEventTime())); return false; } }); 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.