2013-02-16 27 views
13

Hi sbloccare Voglio un pulsante che dovrebbe funzionare come 'slide to unlock' pulsante di IOSCome rendere scorrevole a pulsante in Android

insomma voglio un pulsante che non ha alcun effetto clic, ma possono scorrere da sinistra a destra mentre il trascinamento e il completamento del trascinamento dovrebbero considerare il clic.

per favore suggerire qualsiasi codice di esempio se possibile.

Grazie!

risposta

26

Prima di tutto vorrei ringraziare @matthias per la sua risposta. Ho usato la seguente barra di ricerca con un po 'di personalizzazione:

<SeekBar 
     android:id="@+id/myseek" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:clickable="false" 
     android:max="100" 
     android:progressDrawable="@android:color/transparent" 
     android:thumb="@drawable/ic_launcher" /> 

e nel codice Java

sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { 

     @Override 
     public void onStopTrackingTouch(SeekBar seekBar) { 

      if (seekBar.getProgress() > 95) { 

      } else { 

       seekBar.setThumb(getResources().getDrawable(R.drawable.ic_launcher)); 
      } 

     } 

     @Override 
     public void onStartTrackingTouch(SeekBar seekBar) { 


     } 

     @Override 
     public void onProgressChanged(SeekBar seekBar, int progress, 
       boolean fromUser) { 
      if(progress>95){ 
       seekBar.setThumb(getResources().getDrawable(R.drawable.load_img1)); 
      } 

     } 
    }); 
+0

Anche se il codice necessita di qualche ritocco (almeno nel mio caso) questo è di gran lunga il modo più semplice per fare una "slide to you" nlock "impresa su android. Ottimo lavoro! –

+0

@Jignesh Ansodariya: Ciao ho usato lo stesso concetto per sblocco dello schermo/di blocco, ma non riesco a disattivare l'SeekBar alla spina – Aerrow

0

Android fornisce il widget Switch simile alla diapositiva per sbloccare. Tuttavia, dovrai personalizzarlo un po ', ad es. disabilitare la modifica al clic.

15

ho iniziato con l'esempio che Jignesh Ansodariya pubblicato, ma come sottolinea Aerrow, l'utente può fare clic in qualsiasi punto della SeekBar per sbloccare. Ciò lo rende piuttosto inutilizzabile, dal momento che il punto con un pulsante di scorrimento è che i clic accidentali dovrebbero essere ignorati. La mia soluzione era quella di creare una sottoclasse di SeekBar, in questo modo:

public class SlideButton extends SeekBar { 

    private Drawable thumb; 
    private SlideButtonListener listener; 

    public SlideButton(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    public void setThumb(Drawable thumb) { 
     super.setThumb(thumb); 
     this.thumb = thumb; 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if (event.getAction() == MotionEvent.ACTION_DOWN) { 
      if (thumb.getBounds().contains((int) event.getX(), (int) event.getY())) { 
       super.onTouchEvent(event); 
      } else 
       return false; 
     } else if (event.getAction() == MotionEvent.ACTION_UP) { 
      if (getProgress() > 70) 
       handleSlide(); 

      setProgress(0); 
     } else 
      super.onTouchEvent(event); 

     return true; 
    } 

    private void handleSlide() { 
     listener.handleSlide(); 
    } 

    public void setSlideButtonListener(SlideButtonListener listener) { 
     this.listener = listener; 
    } 
} 

public interface SlideButtonListener { 
    public void handleSlide(); 
} 

XML:

 <package.SlideButton 
      android:id="@+id/unlockButton" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:clickable="false" 
      android:max="100" 
      android:progressDrawable="@android:color/transparent" 
      android:thumb="@drawable/button_lock" > 
     </package.SlideButton> 

E infine il codice dentro la mia attività:

((SlideButton) findViewById(R.id.unlockButton)).setSlideButtonListener(new SlideButtonListener() { 
     @Override 
     public void handleSlide() { 
      unlockScreen(); 
     } 
    }); 
+0

È signore sono sorprendenti, grazie –

+0

Questo funziona perfettamente. Grazie e +1 – Amir

+0

l'aggiunta di un pulsante rettangolo personalizzato sta creando un problema .. al punto di partenza il pulsante metà sinistra del rettangolo è fuori vista verso sinistra e dopo il trascinamento per terminare la parte a metà destra scompare verso destra. Inoltre, mentre si trascina l'effetto round della barra di ricerca è visibile. –

0

Per qualche ragione, non potevo 't disabilitare l'azione del tocco in modo che i taps accidentali siano ancora possibili
Mi è venuta in mente questa soluzione, in pratica non consentirà di cambiare il progresso di oltre 10 valori per cha ESN evento

int unlockLastSeekVal = 0; 
// there are skips btwn changes, use value greater than 1 
// 10 is great for seekbars with 100 values 
int unlockSeekSensitivity = 10; 
// final stage to "unlock"; 0.9 => 90% 
Double unlockFinalStage = 0.9; 
//........... 
unlock.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
     if (fromUser){ 
      if (Math.abs(unlockLastSeekVal - progress) > unlockSeekSensitivity){ 
       // too much delta, revert to last value 
       seekBar.setProgress(unlockLastSeekVal); 
      }else{ 
       unlockLastSeekVal = progress; 
      } 
     } 
    } 

    public void onStartTrackingTouch(SeekBar seekBar) { 
    } 

    public void onStopTrackingTouch(SeekBar seekBar) { 
     if (seekBar.getProgress() > seekBar.getMax() * unlockFinalStage){ 
      DoYourThing(); 
     } 
     unlockLastSeekVal = 0; 
     seekBar.setProgress(0);   
    } 
}); 
0

Partendo dalla risposta di Oskar (grazie per il tuo contributo) creo un semplice progetto di esempio per gestire Pulsante a scorrimento (orizzontale e verticale): https://github.com/rcaboni/AndroidSlideButton

Per una schermata: https://raw.githubusercontent.com/rcaboni/AndroidSlideButton/master/screenshot.jpg

Questo è il metodo principale:

public boolean onTouchEvent(MotionEvent event) { 
    if (!isEnabled()) { 
     return false; 
    } 
    if (orientation == ORIENTATION_HORIZONTAL) { 
     if (event.getAction() == MotionEvent.ACTION_DOWN) { 
      int x= (int) event.getX(); 
      int y= (int) event.getY(); 
      if (thumb.getBounds().contains((int) event.getX(), (int) event.getY())) { 
       super.onTouchEvent(event); 
      } else 
       return false; 
     } else if (event.getAction() == MotionEvent.ACTION_UP) { 
      if (getProgress() > 70) 
       handleSlide(); 

      setProgress(0); 
     } else 
      super.onTouchEvent(event); 
    }else{ 
     int i=0; 
     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       if (event.getAction() == MotionEvent.ACTION_DOWN) { 
        int x= (int) event.getX(); 
        int y= (int) event.getY(); 
        if (!thumb.getBounds().contains((int) event.getY(), (int) event.getX())) { 
         return false; 
        } 
       } 
      case MotionEvent.ACTION_MOVE: 
       i=getMax() - (int) (getMax() * event.getY()/getHeight()); 
       setProgress(100 - i); 
       onSizeChanged(getWidth(), getHeight(), 0, 0); 
       break; 
      case MotionEvent.ACTION_UP: 
       i=getMax() - (int) (getMax() * event.getY()/getHeight()); 
       if (i < 30) { 
        handleSlide(); 
       } 
       setProgress(0); 
       onSizeChanged(getWidth(), getHeight(), 0, 0); 
       break; 

      case MotionEvent.ACTION_CANCEL: 
       break; 
     } 
    } 
    return true; 
} 

XML per il tasto verticale:

<RelativeLayout 
    android:layout_width="75dp" 
    android:layout_height="130dp" 
    android:background="@drawable/slide_background_green" 
    android:id="@+id/lSlideButtonV" 
    android:layout_below="@+id/lSlideButton" 
    android:layout_marginTop="50dp"> 
    <TextView 
     android:layout_width="20dp" 
     android:layout_height="match_parent" 
     android:text="SOS" 
     android:id="@+id/tvSlideActionV" 
     android:gravity="center|bottom" 
     android:layout_alignParentRight="false" 
     android:layout_alignParentEnd="false" 
     android:layout_alignParentLeft="false" 
     android:layout_alignParentStart="false" 
     android:textSize="20dp" 
     android:textColor="@android:color/white" 
     android:layout_alignParentTop="false" 
     android:layout_centerHorizontal="true" 
     android:layout_alignParentBottom="false" 
     android:layout_marginBottom="15dp" /> 
    <it.aldea.android.widget.SlideButton 
     android:id="@+id/unlockButtonV" 
     android:layout_width="match_parent" 
     android:layout_height="150dp" 
     android:clickable="false" 
     android:max="100" 
     slideButton:orientation="vertical" 
     android:progressDrawable="@android:color/transparent" 
     android:thumb="@drawable/slide_track_red" 
     android:indeterminate="false" 
     android:layout_marginRight="5dp" 
     android:layout_marginTop="20dp" 
     android:layout_centerInParent="true" 
     android:layout_marginBottom="10dp" 
     android:thumbOffset="-2dp"> 
    </it.aldea.android.widget.SlideButton> 

</RelativeLayout> 

Non è un vero e proprio widget di completa perché è composta da due vista (TextView e SlideButton) in un layout, ma è una soluzione configurabile facile per Pulsante a scorrimento con il testo al suo interno. Spero che questo sia utile per qualcuno.

0

Forse è tardi, ma ho creato una piccola biblioteca per questo scopo. Ti permette di scorrere e personalizzare il comportamento del tuo pulsante da xml.Slide Button

In pratica si tratta di eseguire l'override dell'evento onTouch() e di apportare modifiche in base alle coordinate ricevute. Dopo tutto, è semplice impostare lo sfondo come desideri e personalizzare il testo.

0

È possibile utilizzare questa libreria in modo rapido e facile personalizzare il tuo sblocco.

https://github.com/cheekiat/SlideToUnlock

Usa questo codice su XML

<cheekiat.slideview.SlideView 
     android:id="@+id/slide_view" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     app:slideBackground="@drawable/orangesquarebutton" 
     app:slideSrc="@drawable/slide_image" 
     app:slideText="Slide to unlock" 
     app:slideTextColor="#ffffff" 
     app:slideTextSize="10dp" /> 

Slide to unlock screenshort

+1

Il link github punta a un tuo progetto? Se è così, per favore menziona chiaramente la tua affiliazione nella risposta; in caso contrario, potrebbe essere considerato spam. Per i dettagli, vedere ** [questa pagina del Centro assistenza] (http://stackoverflow.com/help/promotion) **. Grazie. – Pang

0

è possibile ricostruire il SeekBar normale di fare ciò che si vuole:

Con:

  • Punto di partenza (20)
  • Linea di attraversamento (90)
  • E ripristino automatico.

    seekBar.setOnSeekBarChangeListener ( nuova SeekBar.OnSeekBarChangeListener() { punto Integer = 0; Integer startPoint = 0; booleano iniziato = true;

    @Override 
        public void onProgressChanged(SeekBar seekBar, int i, boolean wasUserInput) { 
         point = i; 
    
         if (started && i > 0 && wasUserInput) { 
          startPoint = new Integer(i); 
          started = false; 
         } 
        } 
    
        @Override 
        public void onStartTrackingTouch(SeekBar seekBar) { 
        } 
    
        @Override 
        public void onStopTrackingTouch(SeekBar seekBar) { 
         if (point > 90 && startPoint < 20) { // slided to the right correctly. 
          // TODO:: 
    
         } else { // reset. 
          resetSeekBar(seekBar, point); 
         } 
    
         startPoint = 0; 
         started = true; 
        } 
    }); 
    

E:

/** 
* Resetting the seekbar, on point at a time. 
* @param seekBar       Reference to the seekbar made smaller. 
* @param oldPoint       The point where the dot is atm. 
*/ 
private void resetSeekBar(final SeekBar seekBar, final int oldPoint) { 
    if (oldPoint > 0) { 
     final int newPoint = oldPoint -1; 
     seekBar.setProgress(newPoint); 

     timer.schedule(new TimerTask() { 
      final SeekBar seekBar = seekBarBid; 
      @Override 
      public void run() { 
       resetSeekBar(seekBar, newPoint); 
      } 
     }, 3); 

    } else { 
     seekBar.setProgress(oldPoint); 
    } 
} 
Problemi correlati