Как добавить TextView в середине большого пальца SeekBar?

Я работаю в Android. Я хочу сделать SeekBar. В палец SeekBar я хочу показать прогресс (возможно, на TextView, выровненном над большим пальцем, который перемещается вместе с большим пальцем).

Это мой XML для SeekBar и 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" />

и этот мой код для выравнивания текста

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

Но текст не отображается в центре этого большого пальца. Пожалуйста, предложите мне, что я должен сделать для этого.

Ответ 1

Если я правильно понимаю ваш вопрос, вы хотите поместить текст внутри большого пальца на стрелку так:

enter image description here

Android Seekbar не предоставляет публичных или защищенных методов, которые позволяют вам устанавливать текст в большом пальце. Таким образом, вы не можете реализовать решение с Android SeekBar, как есть.

В качестве решения вы можете написать свой собственный CustomSeekBar.

Android SeekBar расширяет AbsSeekBar. В AbsSeekBar установлено положение большого пальца:

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

и в методе AbsSeekBar onDraw() большой палец рисуется:

mThumb.draw(canvas);

Чтобы реализовать собственный SeekBar, вы сначала создаете класс CustomSeekBar, который расширяет AbsSeekBar. Затем вы переопределяете метод AbsSeekBar setThumPos() в вашем классе CustomSeekBar и устанавливаете положение своего собственного большого пальца.

Ваш пользовательский палец будет представлять собой View или ViewGroup, например. LinearLayout, с выделенным фоном и TextView для процентного текста прогресса.

Затем вам нужно решить, как записать процентный прогресс в пользовательский палец. Вы можете написать процентный текст прогресса большого пальца в новом методе writeTextOnThumb(), вызванном внутри setThumbPos(), или вы можете опубликовать его как открытый метод в вашем API CustomSeekBar.

Ответ 2

Прежде чем вдаваться в детали решения, я просто упомянул то, что вы, вероятно, уже рассмотрели: пользователь, перемещая SeekBar, обычно имеет свой палец, расположенный над большим пальцем, и поэтому, вероятно, будет скрывать любой текст, который вы можно поместить туда, по крайней мере, в то время как Seekbar перемещается. Теперь, возможно, вы перемещаете SeekBar программно, или, может быть, вы достаточно счастливы, чтобы пользователь мог просмотреть SeekBar, как только она закончила его перемещение и удалила свой палец, или, может быть, вы можете рассчитывать на то, что ваш пользователь будет скользить пальцем под SeekBar после того как она начнет скользить по нему, чтобы открыть большой палец. Но если это не так, тогда вам может захотеть разместить текст где-нибудь, что, вероятно, не будет пальцем пользователя.

Подход, описанный ниже, должен позволять вам размещать текст в любом месте SeekBar, который вам нравится, в том числе над большим пальцем. Чтобы это разрешить, он переопределяет базовый метод onDraw() SeekBar, вместо того, чтобы переопределять метод, специально предназначенный для рисования большого пальца.

Вот грубая версия класса, который рисует текст в SeekBar, используя описанный выше подход:

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

Ответ 3

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>