如何在SeekBar thumb中间添加TextView?

Pus*_*tal 13 android view textview seekbar android-layout

我在Android工作.我想做一个SeekBar.SeekBar我想要显示进度的拇指(可能是TextView拇指上移动的拇指对齐).

这是我的XMLSeekBarTextView.

<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" />
Run Code Online (Sandbox Code Playgroud)

这是我的代码,使文本对齐

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());  
Run Code Online (Sandbox Code Playgroud)

但是文字没有显示在那个拇指的中心.请建议我该怎么做.

Gun*_*son 23

如果我理解你的问题,你想将文本放在拇指内的搜索栏上,如下所示:

在此输入图像描述

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);
}
Run Code Online (Sandbox Code Playgroud)

在AbsSeekBar的onDraw()方法中,绘制了拇指:

mThumb.draw(canvas);
Run Code Online (Sandbox Code Playgroud)

要实现自己的SeekBar,首先要创建一个扩展AbsSeekBar的CustomSeekBar类.然后,在CustomSeekBar类中覆盖AbsSeekBar的setThumPos()方法,并设置自己的自定义拇指的位置.

您的自定义拇指将是View或ViewGroup,例如LinearLayout,具有背景可绘制和用于百分比进度文本的TextView.

然后,您必须决定如何将百分比进度写入自定义拇指.您可以在setThumbPos()内部调用的新writeTextOnThumb方法()中在拇指上编写百分比进度文本,或者可以在CustomSeekBar的API中将其公开为公共方法.

  • 这个答案确实有其优点 - 但setThumbPos()是一个私有方法.您无法在Java中覆盖私有方法. (2认同)

Car*_*arl 6

在深入了解解决方案的细节之前,我将提到您可能已经考虑过的一些事情:用户在移动SeekBar时,通常将手指放在拇指上,因此可能会覆盖您可能放在那里的任何文本,至少在Seekbar被移动的时候.现在,也许你正在以编程方式移动SeekBar,或者你很高兴用户在移动它并移除她的手指后查看SeekBar,或者你可以指望你的用户将她的手指滑到SeekBar 下面在她开始滑动之后,露出拇指.但如果情况并非如此,那么您可能希望将文本放置在用户手指可能不在的位置.

下面介绍的方法应该允许您将文本放在SeekBar中您喜欢的任何位置,包括通过拇指.为了实现这一点,它会覆盖SeekBar的基本onDraw()方法,而不是覆盖专门用于绘制拇指的方法.

这是使用上述方法将文本绘制到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();
  }
}
Run Code Online (Sandbox Code Playgroud)