Where'd padding go, when setting background Drawable?

I have this issue on my EditText and Button views, where I have a nice padding for them to space away from the text, but when I change the background with setBackgroundDrawable or setBackgroundResource that padding is lost forever.


Solution 1:

What I found was adding a 9 patch as a background resource reset the padding - although interestingly if I added a color, or non-9 patch image, it didn't. The solution was to save the padding values before the background gets added, then set them again afterwards.

private EditText value = (EditText) findViewById(R.id.value);

int pL = value.getPaddingLeft();
int pT = value.getPaddingTop();
int pR = value.getPaddingRight();
int pB = value.getPaddingBottom();

value.setBackgroundResource(R.drawable.bkg);
value.setPadding(pL, pT, pR, pB);

Solution 2:

I was able to wrap the element inside another layout, in this case, a FrameLayout. That enabled me to change the background on the FrameLayout without destroying the padding, which is on the contained RelativeLayout.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/commentCell"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:background="@drawable/comment_cell_bg_single" >

    <RelativeLayout android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:padding="20dp" >

    <ImageView android:id="@+id/sourcePic"
               android:layout_height="75dp"
               android:layout_width="75dp"
               android:padding="5dp"
               android:background="@drawable/photoframe" 
     />
...

The other option is to set it programmatically after setting the background Drawable as suggested above. Just make sure to calculate the pixels to correct for the resolution of the device.

Solution 3:

I had this problem in a TextView, so I subclassed TextView and made an Override method of the TextView.setBackgroundResource(int resid) method. Like this:

@Override
public void setBackgroundResource(int resid) {
    int pl = getPaddingLeft();
    int pt = getPaddingTop();
    int pr = getPaddingRight();
    int pb = getPaddingBottom();

    super.setBackgroundResource(resid);

    this.setPadding(pl, pt, pr, pb);
}

This way, it gets the padding of the item before it sets the resource, but doesn't actually mess with the original functionality of the method, other than keeping the padding.