Style a SW button from a designer button

Bas Hamstra

Member
Licensed User
Longtime User
I need 26 sweet image buttons for a keyboard in Hangman game. Therefore I created 1 dummy StateListDrawable dummy button with nice images in the designer. Now I want to create 26 new buttons in software by copying the dummy button from the designer. Seems not possible?

dim Letter(27) as Button

For n=1 to 26
..Letter(n) = DesignerButton
Next

It seems only the reference is assigned, which I can understand with my C background. But in C/C++ you could dereference an object by *Letter(n) = *DesignerButton effectively making a copy of the source object. Is such a thing possible in B4A?

Thanks in advance for your patience,

Bas Hamstra
 

Bas Hamstra

Member
Licensed User
Longtime User
Nope

You should use Letter(n).Background = DesignerButton.Background.

Tried that already, doesn't work. Because all buttons then use the same sld reference, so when I press the first buttton the last button is visually presed :)

Seems there is no way around writing a short routine with the tedious stuff with Dim bitmap, then Dim sld, adding states, assigning bitmaps etc (the actual bitmaps can be reused, the rest not).

I much appreciated you responded anyway,

Bas Hamstra
 
Upvote 0

Bas Hamstra

Member
Licensed User
Longtime User
Code not working - WHY?

Wrote a routine to create imgButton, however the STATE_PRESSED image is not shown when pressed. The rest works as intended.

Why doesn't the following code work:

B4X:
Sub CreateImgButton(Img1 As String, Img2 As String, Handler As String) As Button

   Dim ImgEnabled As BitmapDrawable
   Dim ImgPressed As BitmapDrawable
   Dim sld As StateListDrawable
   Dim Bt As Button
   
   Bt.Initialize(Handler)
   
   ImgEnabled.Initialize(LoadBitmap(File.DirAssets, Img1))
   ImgPressed.Initialize(LoadBitmap(File.DirAssets, Img2))

   sld.Initialize
   'sld.AddCatchAllState(ImgPressed)
   sld.AddState(sld.State_Enabled, ImgEnabled)
   sld.AddState(sld.State_Pressed, ImgPressed)
   
   Bt.Background = sld
            
   Return Bt

End Sub
 
Upvote 0

Bas Hamstra

Member
Licensed User
Longtime User
Yes Yes Yes Yes Yes (solved)

Cool! Problem solved! I am REALLY glad I do not need that weird AddState2 code that I don't WANT to understand :)

Bas



The order is important. The first matching state is chosen. You should therefore add Pressed state before Enabled.
 
Upvote 0

metrick

Active Member
Licensed User
Longtime User
I try to swap image with the code your post and is not working.
I did tried to reorder post code and still not working.
Can you show me the working codes?
Thank you.

Cool! Problem solved! I am REALLY glad I do not need that weird AddState2 code that I don't WANT to understand :)

Bas
 
Upvote 0

metrick

Active Member
Licensed User
Longtime User
Erel:
I still can not get swap images to work on buttons.
sub csvParse is grabbing the right name and all the file are in their correct case.
The code look correct to me.

B4X:
For j = 0 To pnlKeyboard.NumberOfViews - 1
If pnlKeyboard.GetView(j) Is Button Then 
btnTemp   =   pnlKeyboard.GetView(j)               
strVal = csvParse(",",btnTemp,5)
strPos = strVal.IndexOf("=")      
If strPos <> -1 Then
strVal =  strVal.SubString(1 + strPos)            
strImg1 = strVal & ".png" 
strImg2 = "img2.png" 
btnName = "btn" & strVal.ToUpperCase

   Select Case strVal
   Case "____" 
   strImg1 = "space.png"
   btnName = "btnSpace"
   Case "Enter"
   strImg1 = "enter.png"
   btnName = "btnEnter"
   Case "SHIFT"
   strImg1 = "shift.png"
   btnName = "btnShift"                     
   'etc
        End Select
                        
Else
btnName = "btnEq"
End If

   CreateImgButton(strImg1, strImg2, btnName)

End If

Next
End If

Sub CreateImgButton(Img1 As String, Img2 As String, Handler As String) As Button

    Dim ImgEnabled As BitmapDrawable
    Dim ImgPressed As BitmapDrawable
    Dim sld As StateListDrawable
    Dim Bt As Button
    
    Bt.Initialize(Handler)
    
    ImgEnabled.Initialize(LoadBitmap(File.DirAssets, Img1))
    ImgPressed.Initialize(LoadBitmap(File.DirAssets, Img2))

    sld.Initialize
    
    sld.AddState(sld.State_Pressed, ImgPressed)
    sld.AddState(sld.State_Enabled, ImgEnabled)
          
    Bt.Background = sld     
   
 Return Bt
End Sub
 
Last edited:
Upvote 0

metrick

Active Member
Licensed User
Longtime User
Thank you for quick reply. Still not working with the AddCatchAllState line deleted and in the last line before return.
The image files are in DirAssests, should I copy to DirInternal?
:BangHead:
 
Upvote 0

metrick

Active Member
Licensed User
Longtime User
Erel:
Please see attached project zip file.
Thanks in advance
 

Attachments

  • swapbuttons.zip
    54.4 KB · Views: 221
Upvote 0

klaus

Expert
Licensed User
Longtime User
Here you are.
As Erel already mentioned in CreateImgButton you create a new buttons and do nothing with them.
In the attached project I added a new routine SetStateDrawable that changes the SateDrawable of the buttons which do already exist.

Best regards.
 

Attachments

  • swapbuttons1.zip
    54.3 KB · Views: 251
Upvote 0
Top