iphone - 自定义 ProgressBar 小部件

标签 iphone android progress-bar

我正在尝试做类似于 this 的事情但在 Android 中。

alt text

在 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/

相关文章:

iOS - Dropbox API : How to have a UIProgressView which displays the average value of datas sended to Dropbox?

iphone - 数据库列中的最大值

ios - OCMock3 与 IOS 的集成问题

iphone - ios 核心数据无法使用此代码找到实体名称 'Cartdetail' 的 NSManagedObjectModel

ios - UISearchDisplayController 表格框架

java - 使用 fragment 从其他应用程序接收数据

java - Android 错误

Android Studio webview 调用链接只工作一次

.net - 如何确定 .NET 中进度条的增量步骤?

c# - C#中长时间运行任务的进度条