Share My Creation Button Draw (Draw text and image on a button)

epR6P0.png





B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim obj As Reflector
    Dim buttonpic As ImageView
    Dim buttonlabel As Label
    Dim myfont As Typeface
    Dim c As Canvas
 
    Dim Button1 As Button
 
    Dim button2 As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("Layout1")
    myfont = Typeface.LoadFromAssets("ardelaney.ttf")
 
    buttonpic.Left=3000
    buttonlabel.Left=3000
    Buttondraw(Button1,"Basic4Android",30,Colors.Blue)
  'Usage : Buttondraw(Button name ,Button Text,Font size,Font color)
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub


Sub Buttondraw(btn As Button,btntxt As String,fns As Int,cl As Int)
    Dim bx,by As Int
    Dim bdwEnabled As BitmapDrawable
    buttonlabel.Text=btntxt
    buttonlabel.TextSize=fns
 
    Dim Height_, Width_ As Int
    buttonlabel.Width = -2
    buttonlabel.Height = -2
    DoEvents 
 
    obj.Target = buttonlabel
    Width_ = obj.RunMethod("getWidth")
    Height_ = obj.RunMethod("getHeight")
    buttonpic.Width=btn.Width
    buttonpic.Height=btn.Height
    buttonpic.Bitmap = LoadBitmap(File.Dirassets,"btn.png")
    c.Initialize(buttonpic)
    bx=(btn.Width-Width_)/2
    by=(btn.Height+fns)/2
    c.DrawText(btntxt,bx,by,myfont, fns, cl, "LEFT")
    bdwEnabled.Initialize(buttonpic.Bitmap)
    Dim bdwPressed As BitmapDrawable
    buttonpic.Bitmap = LoadBitmap(File.Dirassets,"btn-down.png")
    c.Initialize(buttonpic)
    c.DrawText(btntxt,bx,by,myfont, fns, cl, "LEFT")
    bdwPressed.Initialize(buttonpic.Bitmap)
 
    Dim bdwdisabled As BitmapDrawable
    buttonpic.Bitmap = LoadBitmap(File.Dirassets,"btn-disabled.png")
    c.Initialize(buttonpic)
    c.DrawText(btntxt,bx,by,myfont, fns, Colors.Gray, "LEFT")
    bdwdisabled.Initialize(buttonpic.Bitmap)
    Dim stdBitmap As StateListDrawable
    stdBitmap.Initialize
 
    Dim states(2) As Int
    states(0) = stdBitmap.state_enabled
    states(1) = -stdBitmap.state_pressed
    stdBitmap.addState2(states, bdwEnabled)
 
    Dim states(1) As Int
    states(0) = stdBitmap.state_enabled
    stdBitmap.addState2(states, bdwPressed)

    Dim states(1) As Int
    states(0) = stdBitmap.state_disabled
    stdBitmap.addState2(states, bdwdisabled)
 
    btn.background=stdBitmap
End Sub


Sub button2_Click
    If Button1.Enabled= True Then
        Button1.Enabled=False
        button2.Text="Disabled"
    Else
        Button1.Enabled=True
        button2.Text="Enabled"
    End If
End Sub

You can add text and image on a button by using this code. Any suggestion or ideas are appreciated. I changed font because of the file size exceeded.
 

Attachments

  • ButtonDraw.zip
    276.5 KB · Views: 1,177
  • epR6P0.png
    epR6P0.png
    50.3 KB · Views: 5,756
Last edited:

luisftv

Member
Licensed User
Longtime User
Thanks for your code!

I was able to adapt it to my needs. Everything works fine.

However, I need help understanding how a section of the code works.

Here is the situation. I have 5 buttons:

Help Button (Button)
Exit Button (Button)
Button1 (Button)
Button2 (Button)
Text Button (Edit Text)

Not to complicate my explanation, I only need to understand the section that applies to Button1 and Button2, which are the only two buttons using the code.

With those two buttons (Button1, Button2), I need them to have: Focused - Enabled - Pressed - Disabled

I have four images, one for each state.

For Focused: Metal_Red_Brushed_01_1.jpg <---red copper
For Enabled: Brushed_Copper.jpg <---brown copper
For Pressed: Brushed_Steel_Blue_01.jpg <---blue copper
For Disabled: Brushed_Steel_Black_09.jpg <---black copper

On a phone or tablet, the default state for buttons is Enabled and it will show the corresponding brown copper image. If you tap (Pressed state) on that same button, then it will flicker for a moment with another image (blue copper). If the button is Disabled, then the black copper image will be shown.

On an Android TV, in order to see where the "cursor" is, I need the Focused state, which is the red copper image.

The code I need to understand how it works is this:

B4X:
    Dim states(4) As Int
    states(0) = stdBitmap.state_Focused
    states(1) = stdBitmap.state_Enabled
    states(2) = -stdBitmap.state_Pressed
    states(3) = -stdBitmap.state_Disabled
    stdBitmap.addState2(states, bdwFocused)

    Dim states(2) As Int
    states(0) = stdBitmap.state_Enabled
    states(1) = -stdBitmap.state_Pressed
    stdBitmap.addState2(states, bdwEnabled)

    Dim states(1) As Int
    states(0) = stdBitmap.state_Pressed
    stdBitmap.addState2(states, bdwPressed)

    btn.background=stdBitmap


Which is found at the bottom of this code:

B4X:
Sub Buttondraw(btn As Button,btntxt As String,fns As Int,cl As Int)

   Dim bx,by As Int

   Dim bdwFocused As BitmapDrawable

   Dim bdwEnabled As BitmapDrawable

   Dim bdwPressed As BitmapDrawable

   Dim bdwDisabled As BitmapDrawable

   buttonlabel.Text=btntxt
   buttonlabel.TextSize=fns

   Dim Height_, Width_ As Int
   buttonlabel.Width = -2
   buttonlabel.Height = -2
   DoEvents

   obj.Target = buttonlabel
   Width_ = obj.RunMethod("getWidth")
   Height_ = obj.RunMethod("getHeight")
   buttonpic.Width=btn.Width
   buttonpic.Height=btn.Height

'================This will show text on the button
'   buttonpic.Bitmap = LoadBitmap(File.Dirassets,"Brushed_Steel_Blue_01.jpg") '?????? Not needed
   c.Initialize(buttonpic)
   bx=(btn.Width-Width_)/2
   by=(btn.Height+fns)/2
   c.DrawText(btntxt,bx,by,myfont, fns, cl, "LEFT")
'================

'This section inludes: FOCUSED, ENABLED, PRESSED, & DISABLED

   bdwEnabled.Initialize(buttonpic.Bitmap) 'It will not work without this code HERE.

   Dim Focused As BitmapDrawable
   buttonpic.Bitmap = LoadBitmap(File.Dirassets,"Metal_Red_Brushed_01_1.jpg")
   c.Initialize(buttonpic)
   c.DrawText(btntxt,bx,by,myfont, fns, cl, "LEFT")
   bdwFocused.Initialize(buttonpic.Bitmap)

   bdwEnabled.Initialize(buttonpic.Bitmap)  'It will not work without this code HERE.

   Dim bdwEnabled As BitmapDrawable
   buttonpic.Bitmap = LoadBitmap(File.Dirassets,"Brushed_Copper_06.jpg")
   c.Initialize(buttonpic)
   c.DrawText(btntxt,bx,by,myfont, fns, cl, "LEFT")
   bdwEnabled.Initialize(buttonpic.Bitmap)

   Dim bdwPressed As BitmapDrawable
   buttonpic.Bitmap = LoadBitmap(File.Dirassets,"Brushed_Steel_Blue_01.jpg")
   c.Initialize(buttonpic)
   c.DrawText(btntxt,bx,by,myfont, fns, cl, "LEFT")
   bdwPressed.Initialize(buttonpic.Bitmap)

   Dim bdwDisabled As BitmapDrawable
   buttonpic.Bitmap = LoadBitmap(File.Dirassets,"Brushed_Steel_Black_09.jpg")
   c.Initialize(buttonpic)
   c.DrawText(btntxt,bx,by,myfont, fns, Colors.Gray, "LEFT")
   bdwDisabled.Initialize(buttonpic.Bitmap)

   Dim stdBitmap As StateListDrawable
   stdBitmap.Initialize

   Dim states(4) As Int
   states(0) = stdBitmap.state_Focused
   states(1) = stdBitmap.state_Enabled
   states(2) = -stdBitmap.state_Pressed
   states(3) = -stdBitmap.state_Disabled
   stdBitmap.addState2(states, bdwFocused)

   Dim states(2) As Int
   states(0) = stdBitmap.state_Enabled
   states(1) = -stdBitmap.state_Pressed
   stdBitmap.addState2(states, bdwEnabled)

   Dim states(1) As Int
   states(0) = stdBitmap.state_Pressed
   stdBitmap.addState2(states, bdwPressed)

   btn.background=stdBitmap

End Sub

FYI: You call upon the Sub BottonDraw in the Sub Activity_Create(FirstTime As Boolean) with this other code that puts it onto the button:

B4X:
Sub Activity_Create(FirstTime As Boolean)

    Activity.LoadLayout("myappmain")

'==========This section calls the "Sub BottonDraw..."
    myfont = Typeface.LoadFromAssets("ardelaney.ttf")
    buttonpic.Left=3000
    buttonlabel.Left=3000
    Buttondraw(Button1,"",18,Colors.Black) 'NOTE: This button's tile was added in the designer as an alternative
    Buttondraw(Button2,"B2",18,Colors.Black)
   'Usage : Buttondraw(Button_name ,Button Text,Font size,Font color)
'==========

End Sub


Also, why is it that this code will not work on an exit routine button like this one:

B4X:
Sub Exit_Click
    ExitApplication
End Sub


If the button is called "Exit", the "Sub Buttondraw" will work, but the Exit button does nothing, it will not exit the app... but the bottom has to be called "Exit" for the "ExitApplication" to execute properly!!! Don't apply the Sub Buttondraw to the Exit button and it works as intended, it exits the app. Why?

Also, with this code, how do you go on adding a border, of any color, to the buttons?

Can you please help me understand this? Any one?

Thanks in advance.
 
Last edited:

strat

Active Member
Licensed User
Longtime User
First, you can try Activity.Finish to exit application.

B4X:
Sub Exit_Click
    Activity.Finish
End Sub


It's better to post your full code to help you complete your project. With only codes, its hard to understand where the error is.
 

luisftv

Member
Licensed User
Longtime User
There are no errors!!!!

I am simply trying to understand how this part of your code works, the logic of it (with my modifications):

B4X:
Dim states(4) As Int
    states(0) = stdBitmap.state_Focused
    states(1) = stdBitmap.state_Enabled
    states(2) = -stdBitmap.state_Pressed
    states(3) = -stdBitmap.state_Disabled
    stdBitmap.addState2(states, bdwFocused)

    Dim states(2) As Int
    states(0) = stdBitmap.state_Enabled
    states(1) = -stdBitmap.state_Pressed
    stdBitmap.addState2(states, bdwEnabled)

    Dim states(1) As Int
    states(0) = stdBitmap.state_Pressed
    stdBitmap.addState2(states, bdwPressed)

    btn.background=stdBitmap



Also, I was wondering (this is not an error) why the EXIT Sub Button won't compile if your code is applied to it. There are two ways to end an app: "Activity.Finish" or the "ExitApplication". They both work. That is not the question or an error.

If you simply copy and paste your entire code and then apply it to a basic project containing just one button, the Exit button, then it will not compile. The only way is to rename that button to something else like Quit or Stop or Exit2... What's going on with "Exit"? It's fine if the button is called something else... it will still work. I just want to understand why it won't work if the button is called "Exit".
 
Last edited:

luisftv

Member
Licensed User
Longtime User
By the way...

Thank you so much for your code... My apps now work beautifully on the Android TVs. Now I have two ways for buttons to show status on the TVs, for those that are just plain colors and for those using images (your code).

Thanks!
 

strat

Active Member
Licensed User
Longtime User
Ok.
I got this code from Users Guide Section 10.1.4. Actually I didn't fully understand how its work. I think button's statelist is related to Java, it's not related to B4A.


By the way...

Thank you so much for your code... My apps now work beautifully on the Android TVs. Now I have two ways for buttons to show status on the TVs, for those that are just plain colors and for those using images (your code).

Thanks!

I'm glad to see it works.
 

luisftv

Member
Licensed User
Longtime User
It is related to B4A because... wait for it... wait for it... it is being coded with B4A. That the feature is Java, is one thing, that B4A is going to transla it to Java, that's another thing. Also remember, everything you do in B4A will become Java code when compiled. Everything!

So, if I go to Java, then there are no "Buts"... the sky is the limit, because Android's app language is Java. If I type it with B4A, then it all depends if B4A has the required way of translating it into Java. For example, in Java there is "Icon Elevation", a way to bring focus into the current button menu by enlarging the icon giving the effect of growing. Does B4A uses that technique yet? I have not found it. If you know let me know, please. In Java, Icon Elevation is made of two images, one smaller than the other but using the same button, imposed onto the same button; not two buttons, or two imageview, etc.

We come to B4A because it is a simpler and faster way to learn programming and to code your apps for Android... in Java, to make x app will take you one month, with B4A it will take you two days or so...

Butoons statelists, colordrawable, bitmapdrawable, subs, activities, if-then-else, etc., are old terms from other programming languages... B4A has it's own way of using them, that's all. Other languages call them differently, but they point to the same idea.

I love B4A. It's the best. It is more direct and easier to understand... but, it is a baby.

Version one was not oop. Now it is. B4A is evolving... and in the process, it will become and it is becoming the standard and official RAD.

Thank you Erel.
 
Last edited:
Top