2011-09-01 59 views
0

我想要的只是创建一个按钮,在某些情况下会包含一个'v'图像来标记它是活动的。不是真的复选框,因为不是每次按下按钮它都会改变它的状态。Android:扩展小部件和画布边界 - 扩展Button

但这个想法是这样的。 我需要一个普通的按钮,我有另一个'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()等...

因为他们给我的真实部件位置上的canvase (在onDraw),当我得到它的画布剪辑和翻译(0,0)。

如果我得到它正确,我想知道小工具的最重要的角落我需要得到剪辑最重要的角落或测量的宽度。身高也一样。

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

这是不正常的填充,我检查。那它会是什么?我怎样才能得到,总是包括当用户设置填充和边距的右上角相对坐标?我需要在那里画画。

+0

它看起来像Android的简单9补丁按钮图像有一定量的图像本身的内部空间。在onDraw方法中使用no +或 - 的相同代码对于我自己从我们的设计器按钮图像创建的9补丁非常适用... – codeScriber

回答

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