Android Code Snippet adding Material icons to text

Dave O

Active Member
Licensed User
The MaterialIcons font is handy for creating icon-only buttons. You can do this right in the Designer.

If, however, you want to add an icon to some existing button text (say, a "Save" button with a checkmark before the "Save" text), you can't do this directly in the Designer because the Material font only offers uppercase letters.

So here's a subroutine that takes any existing button with any existing text (e.g. "Save") and prefixes it with a Material icon. It uses CSBuilder to build a CharSequence containing both parts, then assigns that as the button's new text.

B4X:
'prefixes the given text with the given Material icon (with a space between).
'relativeSize is usually around 1.2 for 18-point text, smaller for larger text.
'shiftDown is usually around 5 (non-dip) for 18-point text, larger for larger text
Sub addIconToButton(buttonArg As Button, materialIconCode As Int, relativeSize As Float, shiftDown As Int)
   Dim cs1, cs2 As CSBuilder
   cs1.Initialize.Typeface(Typeface.MATERIALICONS)
   cs1.Size(buttonArg.TextSize).RelativeSize(relativeSize)
   cs1.VerticalAlign(DipToCurrent(shiftDown))
   cs1.Append(Chr(materialIconCode)).PopAll
   cs1.Typeface(Typeface.DEFAULT).Append(" " & buttonArg.Text).PopAll
   cs2.Initialize.VerticalAlign(-DipToCurrent(shiftDown - 2)).Append(cs1).PopAll
   buttonArg.Text = cs2
End Sub
You would then set up a normal button with button text using the DEFAULT typeface, and call the sub like this:

B4X:
addIconToButton(saveButton, 0xE5CA, 1.2, 5)     'checkmark icon
I couldn't figure out an easy way to match the sizes between the two fonts, so I've added a parameter for relative sizing (where 1.0 is the same point size, but often doesn't turn out to be the same actual size).

Similarly, it's hard to get two different fonts to align vertically, so I had to add a parameter for shifting the icon down.

(If you have any ideas about auto-sizing or auto-shifting that will kill off these last 2 parameters, that would be great - let me know.)

Hope you find this useful. Cheers!
 

Attachments

Last edited:

Dave O

Active Member
Licensed User
If you're trying to add a Material icon to other visible text (e.g. a toast message, label, etc.), you can use this variation of the code above:

B4X:
'prefixes the given text with the given Material icon (with a space between).
'relativeSize is usually around 1.2 for 18-point text, smaller for larger text.
'shiftDown is usually around 5 (non-dip) for 18-point text, larger for larger text
Sub addIconToText(normalText As String, materialIconCode As Int, relativeSize As Float, shiftDown As Int) As CSBuilder
    Dim cs1, cs2, cs3 As CSBuilder
    cs1.Initialize
    cs1.Typeface(Typeface.MATERIALICONS)
    cs1.RelativeSize(relativeSize).VerticalAlign(DipToCurrent(shiftDown))
    cs1.Append(Chr(materialIconCode)).PopAll
    cs2.Initialize
    cs2.Typeface(Typeface.DEFAULT).Append(" " & normalText).PopAll
    cs3.Initialize.VerticalAlign(-DipToCurrent(shiftDown - 2)).Append(cs1).Append(cs2).PopAll
    Return cs3
End Sub
This is a more general solution, because you can apply it to buttons, labels, toasts, etc. For the Save button above, you would code it as:

B4X:
saveButton.Text = c.addIconToText(saveButton.Text, 0xE5CA, 1.2, 5)
...which is more flexible in the long run.
 

Dave O

Active Member
Licensed User
For adding icons to button text, here's a more general sub that lets you put the icon on the left (prefix) or the right (suffix) of the button text:

B4X:
'prefixes or suffixes the given text with the given Material icon (with a space between).
'relativeSize is usually around 1.3 for 18-point text, smaller for larger text.
'shiftDown is usually around 5 for 18-point text, larger for larger text
Sub addIconToButton(button As Button, materialIconCode As Int, relativeSize As Float, shiftDown As Int, prefixFlag As Boolean)
    Dim iconCS, textCS, fullCS As CSBuilder
  
    iconCS.Initialize.Typeface(Typeface.MATERIALICONS)
    iconCS.RelativeSize(relativeSize)
    iconCS.VerticalAlign(DipToCurrent(shiftDown))
    iconCS.Append(Chr(materialIconCode)).PopAll
  
    textCS.Initialize.Typeface(Typeface.DEFAULT)
    textCS.VerticalAlign(-DipToCurrent(shiftDown - 2))
    textCS.Append(button.Text).PopAll
  
    fullCS.Initialize
    If prefixFlag = True Then
        fullCS.Append(iconCS).Append(" ").Append(textCS)
    Else
        fullCS.Append(textCS).Append(" ").Append(iconCS)
    End If
    button.Text = fullCS.PopAll
End Sub
You would then call this by adding the new argument at the end:

B4X:
addIconToButton(saveButton, 0xE5CA, 1.2, 5, false)     'add checkmark icon after text
Also, this code could adapted to the addIconToText sub above pretty much as is.
 
Top