定制进度窗口小部件部件、进度、窗口

2023-09-05 00:05:27 作者:裸奔的跳蚤

我试图做同样的这但在Android的东西。

在Android的,我可以延长进度但我怀疑的如何添加 TextViews 在上面。在iphone很容易,因为我可以使用的绝对位置,而不是在这里。

任何想法?

编辑: 我决定使用搜索栏,而不是进度的补充拇指绘制。我评论如下。有几点需要注意:

在我使用的硬codeD值,实际上有三个,但也可以是更多或更少。 当拇指移至其移动到50,但它应该移动到不同的选项。 在我使用的像素,而不是dpi的。我应该解决这个问题。 我需要解决缺乏动画时拇指移动。

我迄今取得的进展:

 公共类SliderFrameLayout扩展的FrameLayout实现OnSeekBarChangeListener {
    私人搜索栏mSlider;
    私人语境mContext;
    私人诠释MSIZE = 3;
    私人TextView的[] mTextViews;
    私有String [] mTexts = {北美自由贸易协定,气,瓦斯油};

    公共SliderFrameLayout(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);

        mContext =背景;
        setWillNotDraw(假);
        mTextViews =新的TextView [MSIZE]
        addSlider();
        addTextViews();
    }

    私人无效addTextViews(){
        的for(int i = 0; I< MSIZE;我++){
            TextView的电视;
            电视=新的TextView(mContext);
            tv.setLayoutParams(新的LayoutParams(LayoutParams.WRAP_CONTENT,
                    LayoutParams.WRAP_CONTENT));
            tv.setText(mTexts [I]);
            mTextViews [我] =电视;
            addView(电视);
        }
    }

    私人无效addSlider(){
        的FrameLayout FL =新的FrameLayout(mContext,NULL);
        的LayoutParams PARAMS =新的LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
        fl.setLayoutParams(PARAMS);
        fl.setPadding(30,30,30,0);


        mSlider =新的搜索栏(mContext,NULL);
        的LayoutParams LP =新的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(本);
        // addView(mSlider);

        fl.addView(mSlider);
        addView(FL);

    }

    @覆盖
    保护无效的OnDraw(帆布油画){
        super.onDraw(画布);


        矩形rectf =新的矩形();
        mSlider.getLocalVisibleRect(rectf);

    Log.d(WIDTH,将String.valueOf(rectf.width()));
    Log.d(高度:,将String.valueOf(rectf.height()));
    Log.d(左,将String.valueOf(rectf.left));
    Log.d(右,将String.valueOf(rectf.right));
    Log.d(顶,将String.valueOf(rectf.top));
    Log.d(底,将String.valueOf(rectf.bottom));

        INT sliderWidth = mSlider.getWidth();

        INT填充= sliderWidth /(MSIZE-1);

        的for(int i = 0; I< MSIZE;我++){
            TextView的电视= mTextViews [I]
            tv.setPadding(I *填充,0,0,0);
        }
    }

    @覆盖
    公共无效onProgressChanged(搜索栏搜索栏,INT进步,
            布尔FROMUSER){
        // TODO自动生成方法存根

    }

    @覆盖
    公共无效onStartTrackingTouch(搜索栏搜索栏){
        // TODO自动生成方法存根

    }

    @覆盖
    公共无效onStopTrackingTouch(搜索栏搜索栏){
        Log.d(寻求,值+ seekBar.getProgress());
        seekBar.setProgress(50);
    }
}
 

解决方案

你已经覆盖的OnDraw ,为什么不直接绘制文本字符串自己呢?而不是通过增加TextViews和填充搞乱的开销,只需使用 canvas.drawText 物理绘制文本字符串在正确的地方。

定制时钟客户端下载 定制时钟下载V4.3.0 安卓版 当易网

您可以使用油漆指定文本的样式和颜色目标:

 油漆textPaint =新的油漆(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(r.getColor(R.color.text_color));
textPaint.setFakeBoldText(真正的);
textPaint.setSubpixelText(真正的);
textPaint.setTextAlign(Align.LEFT);
 

和通过使用画图对象的measureText方法来查找宽度一个特定的字符串将在画布上绘制时得到确切的定位:

 输出textWidth =(INT)textPaint.measureText(mTexts [I]);
 

然后你可以遍历文本字符串数组,并绘制每个字符串在正确的地方。

  @覆盖
保护无效的OnDraw(帆布油画){
  INT myWidth = getMeasuredWidth() -  LEFT_PADDING-RIGHT_PADDING;
  INT分离= myWidth /(MSIZE-1);

  的for(int i = 0;我++; I< MSIZE){
    INT输出textWidth =(int)的textPaint.measureText(mTexts [I]);
    canvas.drawText(mTexts [I]中,
                    LEFT_PADDING +(I *分离) - (int)的(输出textWidth / 2),
                    TOP_PADDING,
                    textPaint);
  }
}
 

您可能会想在onMeasure代替OnDraw中的测量,你可能只能测量每个字符串的宽度当您更改文本或油漆,但我已经把它在一个地方(希望是)更容易理解。

I am trying to do something similar to this but in Android.

In Android I can extend the ProgressBar but I am doubting of how to add the TextViews on top. In iphone it was easy because I can use absolute positions, but not here.

Any ideas?

EDIT: I decided to use SeekBar instead of ProgressBar to add the thumb drawable. I commented below. Some points to notice:

I am using hardcoded values, actually three but it can be more or less. When the thumb is moved it moves to 50 but it should move to the different options. I am using pixels instead of dpi. I should fix that. I need to solve the lack of animation when the thumb moves.

My progress so far:

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);
    }
}

解决方案

You're already overriding onDraw, why not just draw the text strings yourself? Rather than go through the overhead of adding TextViews and messing with the padding, just use canvas.drawText to physically draw the text strings in the right place.

You can specify the style and color of the text using a Paint object:

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);

And get the exact positioning by using the measureText method on that Paint object to find what width a particular string would be when drawn on a canvas:

textWidth = (int)textPaint.measureText(mTexts[i]);

Then you can iterate over your array of text strings and draw each string in the right place.

@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);
  }
}

You'll probably want to do the measurements in onMeasure instead of onDraw, and you should probably only measure the width of each string when you change the text or the paint, but I've put it all in one place to (hopefully) make it easier to follow.