android - Strange behavior of inflated buttons when changing one's color -
i trying implement dynamic button inflation android application, based on input specified user in real time. when clicked, button changes color blue red.
the code responsible goes follows:
layoutinflater layoutsinflater = (layoutinflater) getsystemservice(context.layout_inflater_service); linearlayout linearlayout = (linearlayout) findviewbyid(r.id.layout_for_buttons); // let's need 3 buttons: (int = 0; < 3; i++) { relativelayout buttonlayout = (relativelayout) layoutsinflater .inflate(r.layout.button_layout, linearlayout, false); button button = (button) buttonlayout.getchildat(0); button.settext("button " + i); button.setonclicklistener(new onclicklistener() { @override public void onclick(view buttonview) { button button = (button) buttonview; gradientdrawable gradientdrawable = (gradientdrawable) button .getbackground(); gradientdrawable.setcolor(color.red); gradientdrawable.invalidateself(); } }); linearlayout.addview(buttonlayout); linearlayout.invalidate(); }
layout append buttons simple linearlayout
:
<linearlayout android:id="@+id/layout_for_buttons" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > </linearlayout>
inflated button_layout
relativelayout
consisting of button
, textview
:
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginbottom="10sp" > <button android:id="@+id/button_view" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/button_bg" android:gravity="left" android:paddingbottom="7dip" android:paddingleft="50sp" android:paddingtop="7dip" android:textcolor="#ffffff" android:textsize="20sp" /> <textview android:id="@+id/label_view" android:layout_width="24dip" android:layout_height="24dip" android:layout_marginleft="13dip" android:layout_margintop="8dip" android:gravity="center" android:text="hi" android:textcolor="#ffffff" android:textsize="20sp" android:textstyle="bold" /> </relativelayout>
@drawable/button_bg
shape
in blue color:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:padding="10dp" android:shape="rectangle" > <solid android:color="#0000ff" /> <corners android:radius="10dp" /> </shape>
now, when run application seems fine. after being clicked, first button unsurprisingly turns red:
when close , re-run application every single button blue, , behavior matches expectations. problem is, when re-run application second time, every button turns red (as if has been clicked):
as written in documentation, inflate
method should inflate new view hierarchy based on given xml, responsible this? thought same gradientdrawable
might shared among every inflated button, debugger shows each button has own gradientdrawable
instance.
it seems i've solved problem. gradientdrawable.mutate()
method had called prevent such behavior:
button button = (button) buttonview; gradientdrawable gradientdrawable = (gradientdrawable) button.getbackground(); gradientdrawable.mutate(); // needed line gradientdrawable.setcolor(color.red); gradientdrawable.invalidateself();
it guarantees initialized drawable won't share state drawables inflated same xml, stated in documentation:
make drawable mutable. operation cannot reversed. mutable drawable guaranteed not share state other drawable. useful when need modify properties of drawables loaded resources. default, drawables instances loaded same resource share common state; if modify state of 1 instance, other instances receive same modification. calling method on mutable drawable have no effect.
Comments
Post a Comment