2012-02-14 10 views
11

Estoy trabajando en Android. Quiero hacer un SeekBar. En el pulgar de SeekBar quiero mostrar el progreso (probablemente en un TextView alineado sobre el pulgar que se mueve junto con el pulgar).¿Cómo agregar TextView en medio del pulgar de SeekBar?

Este es mi XML para SeekBar y 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" /> 

y esto mi código para hacer que se alinean para el texto

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()); 

Pero el texto no se muestra en el centro de de ese pulgar. Por favor, sugiérame qué debo hacer para esto.

+0

verificación de este enlace http://www.anddev.org/decorated_and_animated_seekbar_tutorial-t10937.html Espero que tenga una idea para resolver su problema. –

Respuesta

23

Si entiendo su pregunta correcta, la que desea colocar el texto dentro del pulgar en una barra de búsqueda de este modo:

enter image description here

SeekBar Android no expone ningún método público o protegido que permite para establecer un texto en el pulgar. Entonces no puedes implementar una solución con Android SeekBar como está.

Como solución, puede escribir su propia CustomSeekBar.

El Android SeekBar se extiende AbsSeekBar. Está en AbsSeekBar que la posición del pulgar se establece, de este 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); 
} 

y en onDraw de AbsSeekBar método(), el pulgar se dibuja:

mThumb.draw(canvas); 

para implementar su propia SeekBar, primero debe crear una Clase CustomSeekBar que extiende AbsSeekBar. A continuación, reemplaza el método setThumPos() de AbsSeekBar en su clase CustomSeekBar y establece la posición de su propio pulgar personalizado.

Su pulgar personalizado sería una vista o grupo de visualización, por ejemplo. LinearLayout, con un fondo dibujable y un TextView para el texto de porcentaje de progreso.

Luego debe decidir cómo escribir el porcentaje de avance en el pulgar personalizado. Podría escribir el texto del porcentaje de progreso en el pulgar en un nuevo método writeTextOnThumb() llamado dentro de setThumbPos(), o podría exponerlo como un método público en la API de CustomSeekBar.

+0

i qué colocar texto en seekbar thumb. No entiendo tu punto, por favor envíame el código fuente a [email protected] Por favor, ayúdame, gracias de antemano. – sai

+0

@Gunnar Karlsson puede actualizar su respuesta con una solución completa por favor? –

+2

Esta respuesta tiene sus ventajas, pero setThumbPos() es un método privado. No puede anular los métodos privados en Java. – SheedySheedySheedy

6

Antes de entrar en los detalles de una solución, mencionaré algo que probablemente ya haya considerado: al mover el SeekBar, el usuario generalmente tiene el dedo sobre el pulgar y, por lo tanto, es probable que cubra cualquier texto puedes poner allí, al menos mientras Seekbar se mueve. Ahora, quizás esté moviendo el SeekBar programáticamente, o tal vez esté lo suficientemente contento para que el usuario vea el SeekBar una vez que haya terminado de moverlo y se haya quitado el dedo, o tal vez pueda contar con que su usuario deslice su dedo debajo de el SeekBar después de que ella comienza a deslizarlo, a fin de revelar el pulgar. Pero si ese no es el caso, entonces es posible que desee colocar el texto en algún lugar donde sea probable que el dedo del usuario no esté.

El enfoque que se describe a continuación debería permitir colocar el texto en cualquier lugar de la barra de búsqueda que desee, incluso sobre el pulgar. Para permitir esto, reemplaza el método onDraw() básico de SeekBar, en lugar de anular un método que trata específicamente de dibujar el pulgar.

Aquí es una versión aproximada de una clase que se basa en un texto SeekBar usando el enfoque anterior:

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

Gracias. Una pregunta: el texto está exactamente en el medio del pulgar en esta línea: 'int middleOfThumbControl = (int) ((double) ancho * porcentajeProgreso); '. Para mi barra de búsqueda vertical no lo es. Porque 100% (porcentaje de progreso) está en la parte superior de la barra de búsqueda pero el pulgar no va con su centro hacia arriba (solo la parte superior del pulgar está tocando el parte superior de la sekbar) Ya sabes a qué me refiero. No puedo encontrar una buena solución para todo el tamaño de pantalla, cualquier ayuda sería increíble. –

+1

@Simon Schubert: Mi código es para una SeekBar horizontal; no he intentado hacer uno vertical. Sin embargo, el problema que está describiendo parece requerir que se compense con la mitad de la altura del pulgar. getThumbOffset() puede devolver el valor que necesita. De lo contrario, podría intentar con getThumb() (que devuelve un Drawable) y luego recuperar la altura de ese Drawable para obtener la altura del pulgar. – Carl

+0

Gracias Carl. Hice exactamente (creo) lo que dijiste, pero me estaba asustando. Las coordenadas estaban un poco mal todo el tiempo. Terminé sobrescribiendo el método setProgressAndThumb y dibujé el texto en el medio del dibujante. Gracias por su atención. –

-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

Explique también qué hace y cómo resuelve el problema. Solo pegar algún código puede ser confuso para algunos lectores –

Cuestiones relacionadas