2012-02-14 13 views
11

Sto lavorando in Android. Voglio fare un SeekBar. Con il pollice di SeekBar voglio mostrare il progresso (probabilmente su un TextView allineato sul pollice che si muove insieme al pollice).Come aggiungere TextView in mezzo a SeekBar thumb?

Questo è il mio XML per SeekBar e TextView.

<SeekBar 
    android:id="@+id/ProgressBar01" 
    android:layout_width="fill_parent" 
    android:paddingLeft="10px" 
    android:paddingRight ="10px" 
    android:layout_height="70dp" 
    android:layout_below="@+id/incentives_textViewBottemLeft" 
    android:max="10" 
    android:progressDrawable="@drawable/incentive_progress" 
    android:secondaryProgress="0" 
    android:thumb="@drawable/incentives_progress_pin" 
    android:focusable="false" /> 

<TextView 
    android:id="@+id/incentives_textViewAbove_process_pin" 
    android:layout_width="fill_parent" 
    android:layout_height="20dp" 
    android:layout_below="@+id/incentives_textViewBottemLeft" 
    android:layout_marginTop="11dp" 
    android:text="" 
    android:textStyle="bold" 
    android:textColor="#FFe4e1" 
    android:textSize="15sp" /> 

e questo il mio codice per fare align per il testo

int xPos = ((mSkbSample.getRight() - mSkbSample.getLeft())/mSkbSample.getMax()) * mSkbSample.getProgress(); 
v1.setPadding(xPos+m,0,0,0); 
v1.setText(String.valueOf(progress).toCharArray(), 0, String.valueOf(progress).length()); 

Ma il testo non visualizza in centro di quel pollice. Per favore suggeriscimi cosa dovrei fare per questo.

+0

controllare questo link http://www.anddev.org/decorated_and_animated_seekbar_tutorial-t10937.html spero che tu abbia l'idea di risolvere il tuo problema. –

risposta

23

Se ho capito la tua domanda giusta, si desidera inserire il testo all'interno del pollice su un SeekBar in questo modo:

enter image description here

SeekBar Android non espone alcun metodi pubblici o protetti che consente per impostare un testo nel pollice. Quindi non è possibile implementare una soluzione con Android SeekBar così com'è.

Come soluzione, è possibile scrivere la propria CustomSeekBar.

L'Android SeekBar estende AbsSeekBar. E 'in AbsSeekBar che la posizione del pollice è impostato, in questo modo:

private void setThumbPos(int w, Drawable thumb, float scale, int gap) { 
    int available = w - mPaddingLeft - mPaddingRight; 
    int thumbWidth = thumb.getIntrinsicWidth(); 
    int thumbHeight = thumb.getIntrinsicHeight(); 
    available -= thumbWidth; 

    // The extra space for the thumb to move on the track 
    available += mThumbOffset * 2; 

    //Determine horizontal position 
    int thumbPos = (int) (scale * available); 

    //Determine vertical position 
    int topBound, bottomBound; 
    if (gap == Integer.MIN_VALUE) { 
     Rect oldBounds = thumb.getBounds(); 
     topBound = oldBounds.top; 
     bottomBound = oldBounds.bottom; 
    } else { 
     topBound = gap; 
     bottomBound = gap + thumbHeight; 
    } 

    //Set the thumbs position 
    thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound); 
} 

e in OnDraw di AbsSeekBar metodo(), il pollice è tratto:

mThumb.draw(canvas); 

Per implementare il proprio SeekBar, per prima cosa creare un Classe CustomSeekBar che estende AbsSeekBar. Quindi si sostituisce il metodo setThumPos() di AbsSeekBar nella classe CustomSeekBar e si imposta la posizione del proprio pollice personalizzato.

Il pollice personalizzato sarebbe una vista o un gruppo di vista, ad es. LinearLayout, con un background drawable e un TextView per il testo di avanzamento percentuale.

È quindi necessario decidere come scrivere l'avanzamento percentuale sul pollice personalizzato. Puoi scrivere il testo di avanzamento percentuale sul pollice in un nuovo metodo writeTextOnThumb() chiamato all'interno di setThumbPos(), oppure potresti esporlo come metodo pubblico nell'API di CustomSeekBar.

+0

i cosa posizionare il testo su seekbar thumb.Io non riesco a ottenere il tuo punto per favore inviami il codice sorgente a [email protected] favore aiutami grazie in adavance. – sai

+0

@Gunnar Karlsson puoi aggiornare la tua risposta con la soluzione completa plz? –

+2

Questa risposta ha i suoi meriti - ma setThumbPos() è un metodo privato. Non è possibile sovrascrivere i metodi privati ​​in Java. – SheedySheedySheedy

6

Prima di entrare nei dettagli di una soluzione, menzionerò solo qualcosa che probabilmente avete già preso in considerazione: l'utente, quando muove SeekBar, di solito ha il dito posizionato sopra il pollice, e quindi probabilmente coprirebbe qualsiasi testo potresti metterlo lì, almeno mentre il Seekbar viene spostato. Ora, forse stai spostando il SeekBar a livello di codice, o forse sei abbastanza felice che l'utente possa visualizzare SeekBar una volta che ha finito di spostarlo e ha rimosso il dito, o forse puoi contare sul tuo utente per far scorrere il dito sotto il SeekBar dopo che inizia a farlo scorrere, in modo da rivelare il pollice. Ma se questo non è il caso, allora si potrebbe desiderare di posizionare il testo da qualche parte che il dito dell'utente è probabile che sia non.

L'approccio descritto di seguito dovrebbe consentire di posizionare il testo in qualsiasi punto della SeekBar che si desidera, anche sopra il pollice. Per consentire ciò, sovrascrive il metodo onDraw() di base di SeekBar, piuttosto che sovrascrivere un metodo che si occupa specificamente del disegno del pollice.

Ecco una versione grezza di una classe che disegna il testo su un SeekBar utilizzando l'approccio di cui sopra:

public class SeekBarWithText extends SeekBar { 

    private static final int textMargin = 6; 
    private static final int leftPlusRightTextMargins = textMargin + textMargin; 
    private static final int maxFontSize = 18; 
    private static final int minFontSize = 10; 

    protected String overlayText; 
    protected Paint textPaint; 

    public SeekBarWithText(Context context) { 
    super(context); 
    Resources resources = getResources(); 

    //Set up drawn text attributes here 
    textPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    textPaint.setTypeface(Typeface.DEFAULT_BOLD); 
    textPaint.setTextAlign(Align.LEFT); 
    } 

    //This attempts to ensure that the text fits inside your SeekBar on a resize 
    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    super.onSizeChanged(w, h, oldw, oldh); 
    setFontSmallEnoughToFit(w - leftPlusRightTextMargins))); 
    } 

    //Finds the largest text size that will fit 
    protected void setFontSmallEnoughToFit(int width) { 
    int textSize = maxTextSize; 
    textPaint.setTextSize(textSize); 
    while((textPaint.measureText(sampleText) > width) && (textSize > minTextSize)) { 
     textSize--; 
     textPaint.setTextSize(textSize); 
    } 
    } 

    //Clients use this to change the displayed text 
    public void setOverlayText(String text) { 
    this.overlayText = text; 
    invalidate(); 
    } 

    //Draws the text onto the SeekBar 
    @Override 
    protected synchronized void onDraw(Canvas canvas) { 
    //Draw everything else (i.e., the usual SeekBar) first 
    super.onDraw(canvas); 

    //No text, no problem 
    if(overlayText.length() == 0) { 
     return; 
    } 

    canvas.save(); 

    //Here are a few parameters that could be useful in calculating where to put the text 
    int width = this.getWidth() - leftPlusRightTextMargins; 
    int height = this.getHeight(); 

    //A somewhat fat finger takes up about seven digits of space 
    // on each side of the thumb; YFMV 
    int fatFingerThumbHangover = (int) textPaint.measureText("1234567"); 

    float textWidth = textPaint.measureText(overlayText); 

    int progress = this.getProgress(); 
    int maxProgress = this.getMax(); 
    double percentProgress = (double) progress/(double) maxProgress; 
    int textHeight = (int) (Math.abs(textPaint.ascent()) + textPaint.descent() + 1); 

    int thumbOffset = this.getThumbOffset(); 

    //These are measured from the point textMargin in from the left of the SeekBarWithText view. 
    int middleOfThumbControl = (int) ((double) width * percentProgress); 
    int spaceToLeftOfFatFinger = middleOfThumbControl - fatFingerThumbHangover; 
    int spaceToRightOfFatFinger = (width - middleOfThumbControl) - fatFingerThumbHangover; 

    int spaceToLeftOfThumbControl = middleOfThumbControl - thumbOffset; 
    int spaceToRightOfThumbControl = (width - middleOfThumbControl) - thumbOffset; 

    int bottomPadding = this.getPaddingBottom(); 
    int topPadding = this.getPaddingTop(); 

    //Here you will use the above and possibly other information to decide where you would 
    // like to draw the text. One policy might be to draw it on the extreme right when the thumb 
    // is left of center, and on the extreme left when the thumb is right of center. These 
    // methods will receive any parameters from the above calculations that you need to 
    // implement your own policy. 
    x = myMethodToSetXPosition(); 
    y = myMethodToSetYPosition(); 

    //Finally, just draw the text on top of the SeekBar 
    canvas.drawText(overlayText, x, y, textPaint); 

    canvas.restore(); 
    } 
} 
+0

Grazie una domanda: è il testo posizionato esattamente nella parte centrale del pollice da questa riga: 'int middleOfThumbControl = (int) ((double) width * percentProgress); '. Per la mia barra di ricerca verticale non lo è, perché 100% (percentProgress) si trova nella parte superiore della barra di ricerca, ma il pollice non si sposta con il centro verso l'alto (solo la parte superiore del pollice tocca il top of the sekbar) Sai cosa intendo: non riesco a trovare una buona soluzione per tutte le dimensioni dello schermo, ogni aiuto sarebbe fantastico –

+1

@Simon Schubert: il mio codice è per SeekBar orizzontale, non ho provato a farlo un problema verticale, tuttavia il problema che stai descrivendo sembra richiedere una compensazione pari a metà dell'altezza del pollice: getThumbOffset() potrebbe restituire il valore necessario. In caso contrario, potresti provare getThumb() (che restituisce un Drawable) e quindi recuperare l'altezza di quel Drawable per ottenere l'altezza del pollice. – Carl

+0

Grazie Carl. Ho fatto esattamente (credo) quello che hai detto ma mi ha fatto impazzire. Le coordinate erano un po 'sbagliate tutto il tempo. Ho finito per sovrascrivere il metodo setProgressAndThumb e disegnare il testo nel mezzo del drawable. Grazie per l'attenzione. –

-4
check this put trees of relative layout to put text on top of seekbar 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:id="@+id/relativeLayout0" > 

    <Button 
     android:id="@+id/button2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignBaseline="@+id/button1" 
     android:layout_alignBottom="@+id/button1" 
     android:layout_alignParentRight="true" 
     android:text="Button" /> 

    <RelativeLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignBottom="@+id/button1" 
     android:layout_marginBottom="0dp" 
     android:layout_toRightOf="@+id/button1" > 

     <SeekBar 
      android:id="@+id/seekBar1" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_alignParentLeft="true" 
      android:layout_alignParentTop="true" /> 

     <TextView 
      android:id="@+id/textView1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignParentLeft="true" 
      android:layout_centerVertical="true" 
      android:text="Large Text" 
      android:textAppearance="?android:attr/textAppearanceLarge" /> 

     <TextView 
      android:id="@+id/textView2" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignBottom="@+id/seekBar1" 
      android:layout_alignParentRight="true" 
      android:text="Large Text" 
      android:textAppearance="?android:attr/textAppearanceLarge" /> 

     <RelativeLayout 
      android:id="@+id/relativeLayout1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerHorizontal="true" 
      android:layout_centerVertical="true" > 
     </RelativeLayout> 

     <TextView 
      android:id="@+id/textView3" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignTop="@+id/relativeLayout1" 
      android:layout_centerHorizontal="true" 
      android:text="Large Text" 
      android:textAppearance="?android:attr/textAppearanceLarge" /> 
    </RelativeLayout> 
    enter code here 
    <Button 
     android:id="@+id/button1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"`enter code here` 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" 
     android:layout_marginLeft="24dp" 
     android:text="Button" /> 

</RelativeLayout> 
+0

Spiega anche cosa fai e come questo risolve il problema. Basta incollare del codice potrebbe essere fonte di confusione per alcuni lettori –

Problemi correlati