Android Question Multiple buttons evenly distributed

Sergio Haurat

Active Member
Licensed User
Longtime User
Using this example from @Erel

I am trying to draw on the screen 32 buttons in 4 rows and 8 columns.
In the designer there is only one panel to contain the buttons.
1692370246026.png


[CODE lang="b4x" title="This is the code" highlight="38-39"]Sub Class_Globals
Private Root As B4XView
Private xui As XUI
Private pnlButtons As B4XView
Type btnObj (Text As String, Tag As Object)
End Sub

Private Sub B4XPage_Appear
Dim intCnt As Int = 0
Dim intSize As Int = ButtonSize
For col = 0 To 3
For row = 0 To 7
Dim btnProp As btnObj
btnProp.Initialize
btnProp.Text = col.As (String) & "," & row.As (String)
btnProp.Tag = intCnt
pnlButtons.AddView(ButtonsCreator(btnProp), row * intSize, col * intSize, intSize, intSize)
intCnt = intCnt + 1
Next
Next
End Sub

Private Sub B4XPage_Created (RootMain As B4XView)
Root = RootMain
Root.LoadLayout("MainPage")
End Sub

Private Sub ButtonsCreator(btnProp As btnObj) As Button
Dim b As Button
b.Initialize("btn")
b.Text = btnProp.Text
b.Tag = btnProp.Tag
Return b
End Sub

Private Sub ButtonSize() As Int
Dim intSize As Int = 0
'This is where I should calculate the width and height of the button, according to the width and height of the device the size that suits each button
intSize = 200
Return intSize
End Sub

Private Sub btn_Click
ToastMessageShow(Sender.As (Button).Tag,False)
End Sub[/CODE]
 
Last edited:
[CODE lang="b4x" title="This is the best way?"]Private Sub ButtonSize() As Int
Dim intSize As Int = 0
Dim intWidth As Int = (pnlButtons.Width / 8)
Dim intHeight As Int = (pnlButtons.Height / 4)
If intHeight > intWidth Then
intSize = intWidth
Else
intSize = intHeight
End If
Return intSize
End Sub[/CODE]
 
Upvote 0
[CODE lang="b4x" title="Final Code"]Sub Class_Globals
Private Root As B4XView
Private xui As XUI
Private pnlButtons As B4XView
Type btnObj (Text As String, Tag As Object)
Private intCols As Int = 6
Private intRows As Int = 3
End Sub

Public Sub Initialize
B4XPages.GetManager.LogEvents = True
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Appear
Dim intCnt As Int = 0
Dim intSize As Int = ButtonSize
For row = 0 To intRows - 1
For col = 0 To intCols - 1
Dim btnProp As btnObj
btnProp.Initialize
btnProp.Text = col.As (String) & "," & row.As (String)
btnProp.Tag = intCnt
pnlButtons.AddView(ButtonsCreator(btnProp), col * intSize, row * intSize, intSize, intSize)
intCnt = intCnt + 1
Next
Next
End Sub

Private Sub B4XPage_Created (RootMain As B4XView)
Root = RootMain
Root.LoadLayout("MainPage")
End Sub

Private Sub ButtonsCreator(btnProp As btnObj) As Button
Dim b As Button
b.Initialize("btn")
b.Text = btnProp.Text
b.Tag = btnProp.Tag
Return b
End Sub

Private Sub ButtonSize() As Int
Dim intSize As Int = 0
Dim intWidth As Int = (pnlButtons.Width / intCols)
Dim intHeight As Int = (pnlButtons.Height / intRows)
If intHeight > intWidth Then
intSize = intWidth
Else
intSize = intHeight
End If
Return intSize
End Sub

Private Sub btn_Click
ToastMessageShow(Sender.As (Button).Tag,False)
End Sub[/CODE]
 
Upvote 0
Using this example from @Erel
Why are you referring to and using a very old thread that is over 12 years old. Have you considered an xClv which can fit on one screen and has 8 columns and four rows of buttons in a panel set up in the designer. I think it will be a lot more up to date and more versatile and modern. Maybe something that looks like this.

1692379117979.png

Since you already chose your code as a solution, can you at least show a snapshot of what it looks like.
 
Upvote 0
Take a look to this, too

 
Upvote 0
Why are you referring to and using a very old thread that is over 12 years old. Have you considered an xClv which can fit on one screen and has 8 columns and four rows of buttons in a panel set up in the designer. I think it will be a lot more up to date and more versatile and modern. Maybe something that looks like this.

View attachment 144906
Since you already chose your code as a solution, can you at least show a snapshot of what it looks like.
I had not seen since when the post was, 12 years old is a lot. I only saw the code. And it's not the first time this has happened to me either (take an example from an old post, to be honest)

@Mahares, can you share your code? I'm struggling with "my old code base" to set the font, borders, images and other properties.

By mistake I marked the post as solved.
 
Upvote 0
Although I've known B4A originally since 2014, I remember getting "angry" when the screen would rotate, the activity would lose the value of the objects and you had to save the values doing Chinese juggling with other components or something like that (bad decision to stay away for so long). . Thanks to all of you, help sort my knowledge with today.
 
Upvote 0
There is a small problem in your source code: it will create and add new buttons every time the page appears (B4XPage_Appear!).

I remember getting "angry" when the screen would rotate
Did you know that in a B4XPage project you can only have one orientation, vertical or horizontal (unless you create another Activity in addition to the Main)?
 
Upvote 0
There is a small problem in your source code: it will create and add new buttons every time the page appears (B4XPage_Appear!).


Did you know that in a B4XPage project you can only have one orientation, vertical or horizontal (unless you create another Activity in addition to the Main)?
Yes, I know, but my problem was a long time ago, before B4XPage's existed.
There is a small problem in your source code: it will create and add new buttons every time the page appears (B4XPage_Appear!).

The variables (IntCols and IntRows) should actually be a user option, ie you can decide how many buttons to show.

For example
5x3
8x4

[CODE lang="b4x" title="Last version of my code"]Sub Class_Globals
Private Root As B4XView
Private xui As XUI
Private pnlButtons As B4XView
Type btnObj (Text As String, Tag As Object, Picture As Bitmap, Padding As Int, Font As B4XFont)
Private intCols As Int = 8
Private intRows As Int = 4
End Sub

Public Sub Initialize
B4XPages.GetManager.LogEvents = True

End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Appear

End Sub

Private Sub B4XPage_Created (RootMain As B4XView)
Root = RootMain
Root.LoadLayout("MainPage")
B4XPages.SetTitle(Me, Main.loc.Localize("app_name"))
ButtonShow
End Sub

Private Sub ButtonsCreator(btnProp As btnObj) As Button
Dim b As Button
b.Initialize("btn")
b.Text = btnProp.Text
b.TextSize = btnProp.Font.Size
b.Tag = btnProp.Tag
b.SingleLine =False
b.Padding = Array As Int (btnProp.Padding, btnProp.Padding, btnProp.Padding, btnProp.Padding)
If btnProp.Picture.IsInitialized Then
b.SetBackgroundImage(btnProp.Picture)
End If
Return b
End Sub

Private Sub ButtonShow()
Dim intSize As Int = ButtonSize(200, 40)
pnlButtons.SetLayoutAnimated(0, (Root.Width - (intSize * intCols)) / 2, (Root.Height - (intSize * intRows)) / 2, (intSize * intCols), (intSize * intRows))
Dim intCnt As Int = 0
For row = 0 To intRows - 1
For col = 0 To intCols - 1
Dim btnProp As btnObj
btnProp.Initialize
btnProp.Text = row.As (String) & "," & col.As (String)
btnProp.Tag = intCnt
btnProp.Padding = 2
btnProp.Picture = LoadBitmap(File.DirAssets, "logo.png").Resize(intSize, intSize, True)
pnlButtons.AddView(ButtonsCreator(btnProp), col * intSize, row * intSize, intSize, intSize)
intCnt = intCnt + 1
Next
Next
End Sub

Private Sub ButtonSize(SafeAreaW As Int, SafeAreaH As Int) As Int
Dim intSize As Int = 0
Dim intWidth As Int = (Root.Width / intCols) - (SafeAreaW / intCols)
Dim intHeight As Int = (Root.Height / intRows) - (SafeAreaH / intRows)
If intHeight > intWidth Then
intSize = intWidth
Else
intSize = intHeight
End If
Return intSize
End Sub

Private Sub btn_Click
ToastMessageShow("Acción: " & Sender.As (Button).Tag, False)
End Sub

Private Sub btn_LongClick
ToastMessageShow("Configuración: " & Sender.As (Button).Tag, False)
End Sub[/CODE]
 
Upvote 0
One way that might be simpler than the way you are trying to do it is to create a layout with one panel and inside it 8 evenly spaced buttons horizontally using the designer as outlined to you by Jose in, post #5. Then clone that panel 3 times to obtain the look you want. I still prefer the xClv way, but this cloning is in line with what you are trying to achieve. Here is a teaser:
1692490174719.png











45
 
Upvote 0
?
1692556202525.png


 
Upvote 0
Back
Top