我正在尝试做类似于 this 的事情但在 Android 中。
在 Android 中,我可以扩展 ProgressBar
,但我怀疑如何在顶部添加 TextViews
。在 iphone 中这很容易,因为我可以使用绝对位置,但这里不行。
有什么想法吗?
编辑:
我决定使用 SeekBar
而不是 ProgressBar
来添加拇指可绘制对象。我在下面评论。一些注意事项:
- 我使用的是硬编码值,实际上是三个,但可能更多或更少。
- 移动拇指时,它会移动到 50,但它应该移动到不同的选项。
- 我使用的是像素而不是 dpi。我应该解决这个问题。
- 我需要解决拇指移动时缺少动画的问题。
到目前为止我的进步:
public class SliderFrameLayout extends FrameLayout implements OnSeekBarChangeListener {
private SeekBar mSlider;
private Context mContext;
private int mSize = 3;
private TextView[] mTextViews;
private String[] mTexts = {"Nafta", "Gas", "Gasoil"};
public SliderFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setWillNotDraw(false);
mTextViews = new TextView[mSize];
addSlider();
addTextViews();
}
private void addTextViews() {
for ( int i=0 ; i < mSize ; i++ ) {
TextView tv;
tv = new TextView(mContext);
tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
tv.setText(mTexts[i]);
mTextViews[i] = tv;
addView(tv);
}
}
private void addSlider() {
FrameLayout fl = new FrameLayout(mContext, null);
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
fl.setLayoutParams(params);
fl.setPadding(30, 30, 30, 0);
mSlider = new SeekBar(mContext, null);
LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
//lp.setMargins(30, 30, 30, 0);
//mSlider.setPadding(30, 30, 30, 0);
mSlider.setLayoutParams(lp);
//mSlider.setMax(mSize-1);
mSlider.setThumbOffset(30);
//mSlider.setProgressDrawable(mContext.getResources().getDrawable(R.drawable.slider_track));
//mSlider.setThumb(mContext.getResources().getDrawable(R.drawable.slider_thumb));
mSlider.setOnSeekBarChangeListener(this);
//addView(mSlider);
fl.addView(mSlider);
addView(fl);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect rectf = new Rect();
mSlider.getLocalVisibleRect(rectf);
Log.d("WIDTH :",String.valueOf(rectf.width()));
Log.d("HEIGHT :",String.valueOf(rectf.height()));
Log.d("left :",String.valueOf(rectf.left));
Log.d("right :",String.valueOf(rectf.right));
Log.d("top :",String.valueOf(rectf.top));
Log.d("bottom :",String.valueOf(rectf.bottom));
int sliderWidth = mSlider.getWidth();
int padding = sliderWidth / (mSize-1);
for ( int i=0 ; i < mSize ; i++ ) {
TextView tv = mTextViews[i];
tv.setPadding(i* padding, 0, 0, 0);
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
Log.d("SEEK", "value: " + seekBar.getProgress());
seekBar.setProgress(50);
}
}
最佳答案
您已经覆盖了 onDraw
,为什么不自己绘制文本字符串呢?无需经历添加 TextView 和弄乱填充的开销,只需使用 canvas.drawText
在正确的位置物理绘制文本字符串。
您可以使用 Paint
对象指定文本的样式和颜色:
Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(r.getColor(R.color.text_color));
textPaint.setFakeBoldText(true);
textPaint.setSubpixelText(true);
textPaint.setTextAlign(Align.LEFT);
然后通过对该 Paint 对象使用 measureText 方法来确定在 Canvas 上绘制时特定字符串的宽度,从而获得精确定位:
textWidth = (int)textPaint.measureText(mTexts[i]);
然后您可以遍历文本字符串数组并在正确的位置绘制每个字符串。
@Override
protected void onDraw(Canvas canvas) {
int myWidth = getMeasuredWidth()-LEFT_PADDING-RIGHT_PADDING;
int separation = myWidth / (mSize-1);
for (int i = 0; i++; i < mSize) {
int textWidth = (int)textPaint.measureText(mTexts[i]);
canvas.drawText(mTexts[i],
LEFT_PADDING+(i*separation)-(int)(textWidth/2),
TOP_PADDING,
textPaint);
}
}
您可能希望在 onMeasure 而不是 onDraw 中进行测量,并且您可能应该只在更改文本或绘画时测量每个字符串的宽度,但我已将它们全部放在一个地方以 (希望)让它更容易理解。
关于iphone - 自定义 ProgressBar 小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3841231/