Android Question Changing progress bar colour?

Andrew Montgomery-Fox

Member
Licensed User
Longtime User
Hi guys,

I'm new to B4A - for a work unit at college we have to work in groups to create an Android app using B4A, my group have decided on a game....

And for this game we need a countdown fuel meter - I have tried using different coloured labels changing at different time points using a countdown timer, but I decided a progress bar would be more efficient, I have the progress bar implemented for testing it, and it does change progress when its set too, however I would like it to change colour too (green, orange and red) I found an tutorial on this and tested it, and it did set one colour but my attempts at changing its colour as well as progress bar size at time points is failing, can anyone help me with this?

This is my program so far:
B4X:
'Activity module
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim Timer1 As Timer
    Dim CountDown As Int
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 lblCoundown As Label
    Dim btnStartStop As Button
    Dim lblCountdown As Label
    Private lblFuel As Label
    Private lblFuel1 As Label
    Private lblFuel2 As Label
    Private prbFuel As ProgressBar
    Private btnAdd As Button
    Dim gd As GradientDrawable
   
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout(1)
   
    'Activity.AddView(prbFuel, 25%x, 80%y, 42%x, 20%y)
   
    Timer1.Initialize("Timer1", 1000)
    CountDown = 30
   
    lblFuel.Color = Colors.RGB(0,255,34)
    lblFuel.SetLayout(25%x, 86%y, 50%x, 10%y)
    lblFuel1.Color = Colors.RGB(255,192,0)
    lblFuel1.Visible = False
    lblFuel1.SetLayout(25%x, 86%y, 46%x, 10%y)
    lblFuel2.Color = Colors.RGB(255,0,0)
    lblFuel2.Visible = False
    lblFuel2.SetLayout(25%x, 86%y, 42%x, 10%y)
    prbFuel.Progress = 100
   
   
    gd.Initialize("TOP_BOTTOM", Array As Int(Colors.Green, Colors.Green))
    SetProgressDrawable(prbFuel, gd)
       
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub SetProgressDrawable(p As ProgressBar, drawable As Object)

  Dim r As Reflector
  Dim clipDrawable As Object
  clipDrawable = r.CreateObject2("android.graphics.drawable.ClipDrawable", _
      Array As Object(drawable, Gravity.LEFT, 1), _
      Array As String("android.graphics.drawable.Drawable", "java.lang.int", "java.lang.int"))
  r.Target = p
  r.Target = r.RunMethod("getProgressDrawable") 'Gets the layerDrawable
  r.RunMethod4("setDrawableByLayerId", _
      Array As Object(r.GetStaticField("android.R$id", "progress"), clipDrawable), _
      Array As String("java.lang.int", "android.graphics.drawable.Drawable"))
     
      Timer1_Tick
End Sub

Sub Timer1_Tick

    CountDown = CountDown -1
    lblFuel.Text = CountDown
    If CountDown = 0 Then
        ToastMessageShow("Out of fuel",True)
        CountDown = 30
        SetProgressDrawable(prbFuel, gd)
    End If
   
    If CountDown = 30 Then
        lblFuel.Visible = True
        prbFuel.Progress = 100
        'prbFuel.Progress = Colors.RGB(0,255,34)
    Else If CountDown = 25 Then
        lblFuel.Visible = False
        lblFuel1.Visible = True
        prbFuel.Progress = 83
        'prbFuel.Progress = Colors.RGB(255,192,0)
    Else If CountDown = 20 Then
        lblFuel1.Visible = False
        lblFuel2.Visible = True
        prbFuel.Progress = 66
    Else If CountDown = 15 Then
        prbFuel.Progress = 49
    Else If CountDown = 10 Then
        lblFuel1.Visible = False
        lblFuel2.Visible = True
        prbFuel.Progress = 32
    Else If CountDown = 5 Then
        lblFuel1.Visible = False
        lblFuel2.Visible = True
        prbFuel.Progress = 15
    Else If CountDown = 0 Then
        prbFuel.Progress = 0
    End If
   
'    If btnAdd.Text = "Add" Then
        'CountDown = CountDown + 5
'        btnAdd_Click
'    End If
   
End Sub

'Sub btnAdd_Click
   
'    CountDown = CountDown + 5
'    Return
'End Sub

Sub btnStartStop_Click
    Select Case btnStartStop.Text
        Case "Start"
            Timer1.Enabled = True
            btnStartStop.Text="Stop"
        Case "Stop"
            Timer1.Enabled = False
            btnStartStop.Text = "Start"
            CountDown = 30
        Case Else
    End Select
End Sub
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Seems like you can only change the color before the progress is set. This example removes the bar and adds a new one instead:
B4X:
Sub Globals
   Dim pb As ProgressBar
End Sub

Sub Activity_Create(FirstTime As Boolean)
  pb.Initialize("pb")
  Activity.AddView(pb, 10dip, 10dip, 300dip, 50dip)
   Activity_Click
End Sub

Sub SetProgressDrawable(p As ProgressBar, drawable As Object)
  Dim r As Reflector
  Dim clipDrawable As Object
  clipDrawable = r.CreateObject2("android.graphics.drawable.ClipDrawable", _
  Array As Object(drawable, Gravity.LEFT, 1), _
  Array As String("android.graphics.drawable.Drawable", "java.lang.int", "java.lang.int"))
  r.Target = p
  r.Target = r.RunMethod("getProgressDrawable") 'Gets the layerDrawable
  r.RunMethod4("setDrawableByLayerId", _
  Array As Object(r.GetStaticField("android.R$id", "progress"), clipDrawable), _
  Array As String("java.lang.int", "android.graphics.drawable.Drawable"))
End Sub

Sub Activity_Click
   Dim progress As Int = pb.Progress
   pb.RemoveView
   pb.Initialize("pb")
   Activity.AddView(pb, 10dip, 10dip, 300dip, 50dip)
   Dim gd As GradientDrawable
   gd.Initialize("TOP_BOTTOM", Array As Int(Rnd(0x80000001, 0), Rnd(0x80000001, 0)))
   gd.CornerRadius = 3dip
   SetProgressDrawable(pb, gd)
   pb.Progress = progress + 10
End Sub
 
Upvote 0

Andrew Montgomery-Fox

Member
Licensed User
Longtime User
Seems like you can only change the color before the progress is set. This example removes the bar and adds a new one instead:
B4X:
Sub Globals
   Dim pb As ProgressBar
End Sub

Sub Activity_Create(FirstTime As Boolean)
  pb.Initialize("pb")
  Activity.AddView(pb, 10dip, 10dip, 300dip, 50dip)
   Activity_Click
End Sub

Sub SetProgressDrawable(p As ProgressBar, drawable As Object)
  Dim r As Reflector
  Dim clipDrawable As Object
  clipDrawable = r.CreateObject2("android.graphics.drawable.ClipDrawable", _
  Array As Object(drawable, Gravity.LEFT, 1), _
  Array As String("android.graphics.drawable.Drawable", "java.lang.int", "java.lang.int"))
  r.Target = p
  r.Target = r.RunMethod("getProgressDrawable") 'Gets the layerDrawable
  r.RunMethod4("setDrawableByLayerId", _
  Array As Object(r.GetStaticField("android.R$id", "progress"), clipDrawable), _
  Array As String("java.lang.int", "android.graphics.drawable.Drawable"))
End Sub

Sub Activity_Click
   Dim progress As Int = pb.Progress
   pb.RemoveView
   pb.Initialize("pb")
   Activity.AddView(pb, 10dip, 10dip, 300dip, 50dip)
   Dim gd As GradientDrawable
   gd.Initialize("TOP_BOTTOM", Array As Int(Rnd(0x80000001, 0), Rnd(0x80000001, 0)))
   gd.CornerRadius = 3dip
   SetProgressDrawable(pb, gd)
   pb.Progress = progress + 10
End Sub


Thank you so much, that might be just what I need! If I can get it to remove and recreate the progress bar smoothly each time the countdown gets to a 5 second interval then it might just work! Thank you again :)

Edit: One other thing; is there an onClick event I can use with button to do an IF loop? I know that you can do a Sub btn_Click, so I guess it must exists?
 
Last edited:
Upvote 0

Andrew Montgomery-Fox

Member
Licensed User
Longtime User
Just wondered if that could be used in an if look in a sub to detect button events? Maybe having a btn_Click sub is the only way....

Also thanks for the code, that does seem to solve the problem! :)
 
Upvote 0

Andrew Montgomery-Fox

Member
Licensed User
Longtime User
You might have a look at the attached test program.
Perhaps not exactly your need but as an inspiration.

Thanks, I really like that, I don't suppose you could extract the code of the bar with each of the individual panels? (The one with bargraph0 and bargraph1 images linked to it) I like that and might do a variation on it, but I can't work out which code governs specifically that so my attempts to extract it haven't worked
 
Upvote 0
Top