Get the Background of a Button

thedesolatesoul

Expert
Licensed User
Longtime User
Does anyone know how to get the background image of a button?

This does not work:
B4X:
   Dim bmdPressed As BitmapDrawable
   bmdPressed = cmdNew.Background

I get:
java.lang.ClassCastException: android.graphics.drawable.StateListDrawable

I have tried StateListDrawable and although that works in the assignment, it is useless since I cannot extract the image.

I am trying to extract the button background for enabled and pressed states.
 

thedesolatesoul

Expert
Licensed User
Longtime User
My intention is that i do not want to lose the original styles on the buttons i.e. ICS style or GB style.
I was trying to get the background image for various states, then draw the bitmap using a canvas on each state, and create a stratelistdrawable.

Sent from my GT-I9000 using Tapatalk
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
I cant seem to get the Drawable for the pressed state.
Everytime I force the button to 'pressed' and take that drawable, it is still the same (unpressed) one.

Here is the code I used:
B4X:
Sub CreateBitmapButton(cmd As Button, bmp As Bitmap, act As Activity)
   Dim c As Canvas 
   Dim r1 As Rect 
   Dim r2 As Rect 
   Dim sld As StateListDrawable 

   'Create a temporary button and draw on it
   Dim tmpbutton As Button 
   tmpbutton.Initialize("")
   act.AddView(tmpbutton,0,0,cmd.Width,cmd.Height)
   
   c.Initialize(tmpbutton)
   r1.Initialize(0,0,cmd.Width,cmd.Height)
   r2.Initialize(7,7,cmd.Width-7dip,cmd.height-7dip)
   sld.Initialize 
   
   c.DrawDrawable(cmd.Background,r1)
   c.DrawBitmap(bmp,Null,r2)
   sld.AddState(sld.State_Enabled,tmpbutton.Background)
   tmpbutton.RemoveView 
   
   'Force to pressed state
   SetPressed(cmd, True)
   tmpbutton.Initialize("")
   act.AddView(tmpbutton,0,0,cmd.Width,cmd.Height)
   c.Initialize(tmpbutton)
   c.DrawDrawable(cmd.Background ,r1)
   c.DrawBitmap(bmp,Null,r2)
   sld.AddState(sld.State_Pressed,tmpbutton.Background)

   tmpbutton.RemoveView 
   SetPressed(cmd, False)
   cmd.Background = sld

End Sub

Sub SetPressed(cmd As Button, Pressed As Boolean)
   Dim ref As Reflector 
   ref.Target = cmd
     ref.RunMethod2("setPressed", Pressed, "java.lang.boolean")
End Sub

Not sure how to get the 'pressed' drawable?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
It is a bit tricky as you need to wait for the button to redraw itself.

This code works:
B4X:
Sub Globals
   Dim b As Button
   Dim c As Canvas
End Sub

Sub Activity_Create(FirstTime As Boolean)
   b.Initialize("")
   Activity.AddView(b, 0, 0, 100dip, 100dip)
   Dim r As Reflector
   r.Target = b
   r.RunMethod2("setPressed", True, "java.lang.boolean")
   DoEvents
   c.Initialize(Activity)
   Dim re As Rect
   re.Initialize(0, 0, 100%x, 100%y)
   c.DrawDrawable(b.Background,re)
   Activity.Invalidate
End Sub

The DoEvents is required.
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
Thanks Erel. It does work!!! :D You are awesome :D
One more thing of note is that the order of adding to the statelistdrawable is important otherwise the 'enabled' state is triggered all the time.

For the sake of reference here is the code that works:
B4X:
Sub CreateBitmapButton(cmd As Button, bmp As Bitmap, act As Activity)
   Dim c As Canvas 
   Dim r1 As Rect 
   Dim r2 As Rect 
   Dim sld As StateListDrawable 

   'Create a temporary button and draw on it
   Dim tmpbutton As Button 
   tmpbutton.Initialize("")
   act.AddView(tmpbutton,0,0,cmd.Width,cmd.Height)
   
   SetPressed(cmd, True)
   DoEvents
   
   c.Initialize(tmpbutton)
   r1.Initialize(0,0,cmd.Width,cmd.Height)
   r2.Initialize(7,7,cmd.Width-7dip,cmd.height-7dip)
   sld.Initialize 
   
   c.DrawDrawable(cmd.Background,r1)
   c.DrawBitmap(bmp,Null,r2)
   tmpbutton.Invalidate 
   sld.AddState(sld.State_Pressed,tmpbutton.Background)
   
   tmpbutton.RemoveView 
   
   'Force to pressed state
   SetPressed(cmd, False)
   DoEvents
   tmpbutton.Initialize("")
   act.AddView(tmpbutton,0,0,cmd.Width,cmd.Height)
   c.Initialize(tmpbutton)
   c.DrawDrawable(cmd.Background ,r1)
   c.DrawBitmap(bmp,Null,r2)
   tmpbutton.Invalidate 
   sld.AddState(sld.State_Enabled,tmpbutton.Background)
   
   tmpbutton.RemoveView 
   SetPressed(cmd, False)
   cmd.Background = sld

End Sub

Sub SetPressed(cmd As Button, Pressed As Boolean)
   Dim ref As Reflector 
   ref.Target = cmd
     ref.RunMethod2("setPressed", Pressed, "java.lang.boolean")
End Sub
 
Upvote 0
Top