2013-09-04 6 views
12

Grundsätzlich muss ich erkennen, wenn sich der Fortschritt in der SeekBar ändert, und eine Textansicht über dem Daumen zeichnen, die den Fortschrittswert angibt.Erkennung der Daumenposition in SeekBar vor der API-Version 16

ich dies tun, indem Sie eine OnSeekBarChangeListener und auf dem public void onProgressChanged(SeekBar seekBar, int progress, boolean b) Verfahren implementiert, nenne ich Rect thumbRect = seekBar.getThumb().getBounds();, um zu bestimmen, wo der Daumen positioniert ist.

Das funktioniert einwandfrei, aber anscheinend getThumb() ist nur in API-Ebene 16+ (Android 4.1), verursacht eine NoSuchMethodError auf früheren Versionen.

Haben Sie eine Idee, wie Sie dieses Problem umgehen können?

Antwort

28

konnte ich meine eigene Klasse verwenden, um die Daumen zu bekommen:

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

} 

In der Aktivität funktioniert diese perfekt:

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

Funktioniert perfekt, danke! (Ich muss 20 Stunden warten, um Ihnen das Kopfgeld zu senden) – Henrique

+1

Warten Sie 7 Tage, falls jemand eine bessere Antwort gibt. Obwohl ich es hasse, die Reflexion zu verwenden, könnte man das durch Reflexion zeichnen. Geben Sie eine Chance, dass weitere Antworten gepostet werden. –

0

eine herrliche Lösung ! Vielen Dank. Es ist nur nessesary hinzufügen, dass benutzerdefinierte verwenden seekbar Sie Ihre 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 ändern müssen: thumbOffset = „8DP“ - ist eine Hälfte eines Daumens es besser ist, spesify so wird es keine Inkongruenz von der sein Text-Center und der Daumen

Positionierung wie folgt aussehen:

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

Hoffentlich sonst einige Stunden für jemanden retten kann!

habe ich diese Methode anstelle eines benutzerdefinierten seekBar:

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 Antwort ist groß, aber hat den Nachteil, eine Kopie des Daumens von Cachen auch auf API> = 16. Ich habe es so verbessert, dass es nur den Thumb Drawable auf API < = 15 zwischenspeichert und überschreibt die Methode in SeekBar.java, um zu vermeiden, dass zwei Methoden das gleiche für API> = 16 tun. Einziger Wermutstropfen: Es muss SDK-Ziel> 16 sein, was in den meisten Apps heutzutage der Fall sein sollte.

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