自定义ProgressBar小部件

Mac*_*rse 7 iphone android progress-bar

我试图做类似的东西这个,但是在Android中.

替代文字

在Android中我可以扩展ProgressBar但我怀疑如何添加TextViews顶部.在iPhone中它很容易,因为我可以使用绝对位置,但不是在这里.

有任何想法吗?

编辑:我决定使用SeekBar而不是ProgressBar添加拇指drawable.我在下面评论过.有些要注意的要点:

  • 我使用硬编码的值,实际上是三个,但它可以更多或更少.
  • 当拇指移动时,它移动到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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Ret*_*ier 8

你已经压倒了onDraw,为什么不自己画文字串呢?而不是通过添加TextViews和搞乱填充的开销,只需用于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);
Run Code Online (Sandbox Code Playgroud)

通过在该Paint对象上使用measureText方法获取精确定位,以查找在画布上绘制时特定字符串的宽度:

textWidth = (int)textPaint.measureText(mTexts[i]);
Run Code Online (Sandbox Code Playgroud)

然后,您可以迭代文本字符串数组并在正确的位置绘制每个字符串.

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

您可能希望在onMeasure而不是onDraw中进行测量,并且您应该只在更改文本或绘制时测量每个字符串的宽度,但我将它们全部放在一个地方(希望如此)它更容易遵循.