2011-09-01 80 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); 
    }