3

In an attempt to create a checkbox on the right side I was looking at the code in Android. But I was puzzled at where android was measuring the width for the checkbox icon/drawable.

The Checkbox extends the CompoundButton class and only overrides the onPopulateAccessibilityEvent method. The CompoundButton class has a little more code (100 lines), and it extends the Button class. The button class has very little extra code and extends the TextView class. The TextView class has the largest amount of code (10,000 lines).

Here are links to the source code

Checkbox http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.0.3_r1/android/widget/CheckBox.java/?v=source

CompoundButton Web -Syntax Highlighting http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.3_r1/android/widget/CompoundButton.java?av=f

Raw (faster Viewing) http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.0.3_r1/android/widget/CompoundButton.java/?v=source

TextView Web -Syntax Highlighting http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.3_r1/android/widget/TextView.java?av=f

Raw (faster Viewing) http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/widget/TextView.java/?v=source

TextView has a feature called compound drawables where you can place drawables on the left, right, bottom or top of the text. So I assumed this is where CompoundButton is setting the checkbox drawable for the left compound drawable. But in the CompoundButton code I could not find this.

However when I created a custom class by extending CompoundButton, and called getCompoundPaddingLeft() it gave the width approximately equal to the size of the checkbox. But when you run getCompoundDrawables() result is an array of nulls even at the point of onDraw(). In the textView the variables holding all the dimension data are private so I am not sure how CompoundButton is setting these values. Here is an example of getCompoundPaddingLeft() in TextView

 public int getCompoundPaddingLeft() {
    final Drawables dr = mDrawables;
    if (dr == null || dr.mDrawableLeft == null) {
        return mPaddingLeft;
    } else {
        return mPaddingLeft + dr.mDrawablePadding + dr.mDrawableSizeLeft;
    }
} 

Here is the code in CompoundButton where the checkbox drawable is set, there doesn't seem to anyway of passing on to TextView that there is now an drawable image on the left.

public void setButtonDrawable(Drawable d) {
    if (d != null) {
        if (mButtonDrawable != null) {
            mButtonDrawable.setCallback(null);
            unscheduleDrawable(mButtonDrawable);
        }
        d.setCallback(this);
        d.setState(getDrawableState());
        d.setVisible(getVisibility() == VISIBLE, false);
        mButtonDrawable = d;
        mButtonDrawable.setState(null);
        setMinHeight(mButtonDrawable.getIntrinsicHeight());
    }

    refreshDrawableState();
}

So my question is how is CompoundButton setting the width of the left compound drawable? Note I am not interested in a hack to have the checkbox on the right as I already have one.

Upon Further Inspection

I created a custom textview class by extending the textview class, and had my custom compoundButton class extend that, to try and pin point where the spacing for the checkbox was being created by overriding some of the methods.

It was not compoundLeft but paddingLeft which was creating the space for the checkbox. As when I overrode the setPadding() method a paddingLeft was being sent to it. This makes sence as if you place a background without padding on checkbox, the checkbox is not drawn.

The padding is being read from the default styles in the textView constructor code

a = theme.obtainStyledAttributes( attrs, com.android.internal.R.styleable.TextView, defStyle, 0);

    int n = a.getIndexCount();
    for (int i = 0; i < n; i++) {
        int attr = a.getIndex(i);

        switch (attr) {
        case com.android.internal.R.styleable.TextView_editable:
            editable = a.getBoolean(attr, editable);
            break;
         .............

Since we have no access to the com.android.internal.R.styleable being used I don't know how to inspect further.

pt123
  • 2,146
  • 1
  • 32
  • 57

1 Answers1

0

The onDraw() Method of CompoundButton seems to draw mButtonDrawable darwable on to Canvas. The code shows it is being drawn on left side adjusting the height for gravity, drawable's intrinsic width is used as is:

buttonDrawable.setBounds(0, y, buttonDrawable.getIntrinsicWidth(), y + height);
buttonDrawable.draw(canvas);
S.D.
  • 29,290
  • 3
  • 79
  • 130
  • It draws it on a canvas, the width of canvas is incorporating the width of the compound drawable on the left, anyway in the question I mentioned I am not after a hack. I was hoping someone would show me how the width of left compound drawable is being set. – pt123 Jan 14 '13 at 07:27
  • @pt123 Mistakenly had linked to wrong `onDraw()` method. Edited answer. – S.D. Jan 14 '13 at 07:39