2013-09-04 11 views
12

Fondamentalmente, devo rilevare quando il progresso cambia in SeekBar e tracciare una vista di testo sopra il pollice che indica il valore di avanzamento.Rilevamento della posizione del pollice in SeekBar prima dell'API versione 16

faccio questo implementando un OnSeekBarChangeListener e sul metodo public void onProgressChanged(SeekBar seekBar, int progress, boolean b), chiamo Rect thumbRect = seekBar.getThumb().getBounds(); per determinare dove il pollice sia posizionato.

Questo funziona perfettamente, ma apparentemente getThumb() è disponibile solo in livello API 16+ (Android 4.1), causando un NoSuchMethodError su versioni precedenti.

Qualche idea su come aggirare questo problema?

risposta

28

sono stato in grado di usare la mia classe per ottenere il pollice:

MySeekBar.java

package mobi.sherif.seekbarthumbposition; 

import android.content.Context; 
import android.graphics.drawable.Drawable; 
import android.util.AttributeSet; 
import android.widget.SeekBar; 

public class MySeekBar extends SeekBar { 

    public MySeekBar(Context context) { 
     super(context); 
    } 
    public MySeekBar(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 
    public MySeekBar(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    Drawable mThumb; 
    @Override 
    public void setThumb(Drawable thumb) { 
     super.setThumb(thumb); 
     mThumb = thumb; 
    } 
    public Drawable getSeekBarThumb() { 
     return mThumb; 
    } 

} 

Nell'attività questo funziona perfettamente:

package mobi.sherif.seekbarthumbposition; 

import android.app.Activity; 
import android.graphics.Rect; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.SeekBar; 
import android.widget.SeekBar.OnSeekBarChangeListener; 

public class MainActivity extends Activity implements OnSeekBarChangeListener { 
    MySeekBar mSeekBar; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     mSeekBar = (MySeekBar) findViewById(R.id.seekbar); 
     mSeekBar.setOnSeekBarChangeListener(this); 
    } 
    @Override 
    public void onProgressChanged(SeekBar seekBar, int progress, boolean b) { 
     Rect thumbRect = mSeekBar.getSeekBarThumb().getBounds(); 
     Log.v("sherif", "(" + thumbRect.left + ", " + thumbRect.top + ", " + thumbRect.right + ", " + thumbRect.bottom + ")"); 
    } 
    @Override 
    public void onStartTrackingTouch(SeekBar seekBar) { 
     // TODO Auto-generated method stub 

    } 
    @Override 
    public void onStopTrackingTouch(SeekBar seekBar) { 
     // TODO Auto-generated method stub 

    } 
} 
+1

Funziona perfettamente, grazie! (Ho bisogno di aspettare 20 ore per inviarti la taglia) – Henrique

+1

Attendi 7 giorni nel caso qualcuno dia una risposta migliore. Anche se odio usare il riflesso ma si potrebbe ottenere il drawable per riflessione. Dai la possibilità di pubblicare più risposte. –

0

Una splendida soluzione ! Grazie. E 'nessesary solo aggiungere che per usare personalizzata SeekBar è necessario modificare l'XML

<com.example.MySeekBar 
     android:id="@+id/..." 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_vertical" 
     android:layout_weight="1" 
     android:minHeight="3dp" 
     android:maxHeight="3dp" 
     android:progressDrawable="@drawable/seek_bar_2" 
     android:thumb="@drawable/thumbler_seekbart_circle" 
     android:thumbOffset="8dp" /> 

android: thumbOffset = "8DP" - è una metà di un pollice è meglio spesify, quindi non ci sarà mismatching del il centro del testo e il pollice

posizionamento può assomigliare a questo:

int possition = (int) (seekBar.getX() //the beginning of the seekbar 
+ seekBar.getThumbOffset()/2  //the half of our thumb - the text to be above it's centre 
+ ((MySeekBar) seekBar).getSeekBarThumb().getBounds().exactCenterX()); //position of a thumb inside the seek bar 
0

Speriamo che questo può salvare qualche ora per qualcun altro!

Ho creato questo metodo al posto di un seekBar personalizzato: la risposta di

public int getSeekBarThumbPosX(SeekBar seekBar) { 
    int posX; 
    if (Build.VERSION.SDK_INT >= 16) { 
     posX = seekBar.getThumb().getBounds().centerX(); 
    } else { 
     int left = seekBar.getLeft() + seekBar.getPaddingLeft(); 
     int right = seekBar.getRight() - seekBar.getPaddingRight(); 
     float width = (float) (seekBar.getProgress() * (right - left))/seekBar.getMax(); 
     posX = Math.round(width) + seekBar.getThumbOffset(); 
    } 
    return posX; 
} 
0

@Sherif elKhatib è grande, ma ha lo svantaggio di memorizzazione nella cache una copia del pollice anche su API> = 16. L'ho migliorato in modo che memorizza nella cache il Thumb Drawable sull'API < = 15 in più sostituisce il metodo in SeekBar.java per evitare che due metodi facciano lo stesso su API> = 16. Unico inconveniente: è necessario che l'SDK obiettivo sia> = 16, il che dovrebbe essere il caso nella maggior parte delle app al giorno d'oggi.

public class ThumbSeekBar extends AppCompatSeekBar { 

    private Drawable thumb; 

    public ThumbSeekBar(Context context) { 
     super(context); 
    } 

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

    public ThumbSeekBar(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @Override 
    public Drawable getThumb() { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 
      return super.getThumb(); 
     } 
     return thumb; 
    } 

    @Override 
    public void setThumb(Drawable thumb) { 
     super.setThumb(thumb); 
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { 
      this.thumb = thumb; 
     } 
    } 
} 
Problemi correlati