Android 如何在SeekBar拇指中间添加TextView?
我在安卓系统工作。我想做一个Android 如何在SeekBar拇指中间添加TextView?,android,android-layout,view,textview,seekbar,Android,Android Layout,View,Textview,Seekbar,我在安卓系统工作。我想做一个SeekBar。在SeekBar的thumb中我想显示进度(可能在TextView上与thumb对齐,thumb随thumb一起移动) 这是我的XML,用于SeekBar和TextView <SeekBar android:id="@+id/ProgressBar01" android:layout_width="fill_parent" android:paddingLeft="10px" android:paddingRigh
SeekBar
。在SeekBar的thumb中
我想显示进度(可能在TextView上
与thumb对齐,thumb随thumb一起移动)
这是我的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" />
但文本并没有显示在拇指的中央。请建议我该怎么做。如果我正确理解您的问题,您希望将文本放在一个搜索杆上的拇指内侧,如下所示: Android Seekbar不公开任何公共或受保护的方法,允许您在拇指中设置文本。因此,您无法按原样使用Android SeekBar实现解决方案 作为解决方案,您可以编写自己的CustomSeekBar Android扩展了。拇指的位置是在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,首先创建一个扩展AbsSeekBar的CustomSeekBar类。然后在CustomSeekBar类中重写AbsSeekBar的setThumps()方法,并在其中设置自定义thumb的位置
您的自定义拇指将是一个视图或视图组,例如LinearLayout,具有可绘制的背景和进度百分比文本的文本视图
然后,您必须决定如何将进度百分比写入自定义thumb。您可以使用一个名为inside setThumbPos()的新writeTextOnThumb方法()在thumb上编写进度百分比文本,也可以在CustomSeekBar的API中将其作为公共方法公开。在深入了解解决方案的细节之前,我只想提一件您可能已经考虑过的事情:用户,移动SeekBar时,通常将她的手指放在拇指上,因此可能会掩盖您可能放在那里的任何文本,至少在移动SeekBar时是这样。现在,您可能正在以编程方式移动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();
}
}
选中此项,将相对布局的树放置在seekbar的顶部
在这里输入代码
查看此链接,希望您能找到解决问题的方法。谢谢。有一个问题:文本是否正好位于拇指的中间位置:intmiddleofthumbcontrol=(int)((double)width*percentProgress)代码>。对于我的垂直搜索杆,它不是。因为100%(百分进度)在seekbar的顶部,但大拇指的中间位置不到顶部(只有大拇指的顶部接触sekbar的顶部),你知道我的意思。我找不到一个适合所有屏幕大小的解决方案,任何帮助都会很棒。@Simon Schubert:我的代码是针对水平搜索杆的;我没试过做垂直的。然而,您描述的问题似乎要求您偏移拇指高度的一半。getThumbOffset()可能会返回所需的值。如果没有,您可以尝试getThumb()(它返回一个Drawable),然后检索该Drawable的高度以获得拇指的高度。谢谢Carl。我完全按照你说的做了(我相信),但这让我抓狂。坐标一直有点错。最后,我改写了StestPraseStand方法,并在可绘制的中间绘制文本。感谢您的关注。我在我的应用程序中使用了一种不同的方法,它似乎工作得很好,所以也许你只需要调整一下:我想在seekbar拇指上放置文本。我不能理解你的观点,请将源代码发送给我saiyadamreddy@gmail.com.Please感谢您的帮助。@Gunnar Karlsson您能用完整的解决方案plz更新您的答案吗?这个答案确实有它的优点-但是setThumbPos()是一个私有方法。你不能在Java中重写私有方法。我做不到。。。似乎更复杂:(请同时解释你做了什么以及这是如何解决问题的。仅仅粘贴一些代码可能会让一些读者感到困惑
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();
}
}
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>