Question

I have a button. The button is constructed from the StateListDrawable (made of 3 9-patch images). I need to add an extra drawable that will reside on the button's right side, and i need it to be aligned with the button's right side. I tried to use the following:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/blue_back_button_drawable" />
    <item>
      <bitmap android:src="@drawable/filter_by_button_v_mark" android:gravity="right"/>
    </item>
</layer-list>

it didn't work and the V image is indeed aligned right but it has a diff from the button's right side. here's a snapshot: alt text

I want the image to be aligned with the button's left, the only way right now i think i can do it is:

  1. inherit button, in onLayout AFTER the width has been set get the right edge.
  2. get the background drawable (layerDrawable)
  3. calc the button's width minus the v image width and set it as left margin in the drawable.

I should not mention this sounds horrid :-) i hoped there's a better way. Oh the reason it's not part of the image is that i need to know it's width so i can calc the text padding so it wont be hidden by the button's text and because it's not so nice looking as a 9-patch.

Was it helpful?

Solution

Seems like there was no proper solution to this. layer is for static and not 9-patch images apparently, or so it seems. So i extended Button, changed it's on Draw, i have to use Canvas.restore() to break out of the margins that pushed my edges down and put my image in the upper right corner... here's the code:

 @Override
public void setPadding(int left, int top, int right, int bottom) {
    right += mImageWidth;
    super.setPadding(left, top, right, bottom);
}

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

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if( mVImageDrawable != null && mIsMarked){
        //for some reason the clip binds us to position with margins, which is not so good for us.
        //we need to save the clip, restore the canvas to pre clipping mode, do what we need then
        //put the canvas back to it's previous clipping state.
        Rect bounds = canvas.getClipBounds();
        canvas.restore();
        int right = getRight();
        int left = right - mImageWidth;
        int top = getTop();
        int bottom = top + mVImageDrawable.getIntrinsicHeight();
        mVImageDrawable.setBounds(left, top, right, bottom);
        mVImageDrawable.draw(canvas);
        canvas.save();
        canvas.clipRect(bounds);
    }
}

If i don't break out the original canvas iget 'pushed down' by any margins i add, it may also be fixed i think using xml property that specifies if children should be clipped on the layout containing this button, but i find that lame solution as it makes my button dependent on our conditions. The image itself i get from XML using new attributes and style and theme i declare.

Hope it'll help some ppl out there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top