Android:扩展小部件和画布边界 - 扩展Button

时间:2011-09-01 12:21:22

标签: android canvas widget bounds

我想要的只是创建一个按钮,在某些情况下会包含一个'v'图像来标记它是活动的。不是真正的复选框,因为不是每次按下按钮都会改变它的状态。

但这个想法是这样的。 我需要一个简单的按钮,我有另一个'v'的小图像,如果我在该按钮上使用toggle()方法按钮将足够扩展,所以'v'图像可以很好地挤压到它的右上角。

这是我的代码:

public class ButtonWithV extends Button {
    private Drawable mVImageDrawable;
    private int mImageWidth;
    private boolean mIsMarked;

    public ButtonWithV(Context context) {
        this(context, null);
    }

    public ButtonWithV(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.ButtonWithVStyle);
    }

    public ButtonWithV(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mImageWidth = 0;
        TypedArray a = context.obtainStyledAttributes(
                attrs, R.styleable.ButtonWithV, defStyle, 0);
        Drawable d = a.getDrawable(R.styleable.ButtonWithV_button_v_drawable);
        if( d != null){
            setVImageDrawable(d);
        }
//      setPadding(getPaddingLeft(), getPaddingTop(),
//              getPaddingRight(), getPaddingBottom());
        mIsMarked = false;
    }

    public void setMarked(boolean marked){
        if( marked != mIsMarked){
            mIsMarked = marked;
            requestLayout();
//          invalidate();
        }
    }

    private void setVImageDrawable(Drawable d) {
        mVImageDrawable = d;
        mImageWidth = mVImageDrawable.getIntrinsicWidth();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Rect temp = canvas.getClipBounds();
        System.out.println(String.format("top: %d, bottom: %d, left: %d, right: %d",
                temp.top, temp.bottom, temp.left, temp.right));
        super.onDraw(canvas);
        System.out.println(String.format("top: %d, bottom: %d, left: %d, right: %d",
                temp.top, temp.bottom, temp.left, temp.right));

        if( mVImageDrawable != null && mIsMarked){
            Rect bounds = canvas.getClipBounds();
            int right = bounds.right - 5;
            int left = right - mImageWidth;
            int top = bounds.top + 2;
            int bottom = top + mVImageDrawable.getIntrinsicHeight();
            mVImageDrawable.setBounds(left, top, right, bottom);
            mVImageDrawable.draw(canvas);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if( mIsMarked ){
            setMeasuredDimension(getMeasuredWidth() + mImageWidth, getMeasuredHeight());
        }
    }

    public void toggle(){
        setMarked(! mIsMarked );
    }

}

请注意-5和+2(它们不能保持原样我只想看到确切的数字)。 我在这里发现的问题,可能会有问题,在所有小部件中我都不能使用小部件的getRight(),getLeft()等......

因为他们给我画布上的REAL小部件位置,然而(在onDraw中)当我得到画布时它被剪裁并翻译成(0,0)。

如果我正确地理解并且我想知道小部件最右边的角落,我需要得到夹子最右角或测量宽度。同样适合身高。

另一个问题是我不知道背景是如何被淹的但是我知道因为我必须从小部件右侧移除5个像素才能到达它的正确位置它意味着内边距或填充。

这不是常规的填充,我查了一下。那有什么用呢?我怎样才能,总是包括用户设置填充和边距右上方的相对坐标?我需要画画。

1 个答案:

答案 0 :(得分:0)

最终我使用填充来解决问题,我只需要在右边添加更多填充所需按钮的宽度,这样我就可以绘制叠加图像了。 这是固定代码快照:

public void setMarked(boolean marked){
        if( marked != mIsMarked){
            mIsMarked = marked;
            requestLayout();
        }
    }


    private void setVImageDrawable(Drawable d) {
        mVImageDrawable = d;
        mImageWidth = mVImageDrawable.getIntrinsicWidth();
    }

    @Override
    public int getCompoundPaddingRight() {
        int orig = super.getCompoundPaddingRight();
        int res = orig;
        if( mIsMarked ){
            res += mImageWidth;
        }
        return res;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if( mVImageDrawable != null && mIsMarked){
            Rect bounds = canvas.getClipBounds();
            int right = bounds.right;
            int left = right - mImageWidth;
            int top = bounds.top;
            int bottom = top + mVImageDrawable.getIntrinsicHeight();
            mVImageDrawable.setBounds(left, top, right, bottom);
            mVImageDrawable.draw(canvas);
        }
    }

    public void toggle(){
        setMarked(! mIsMarked );
    }