Android Question Make progressBar like this

Emme Developer

Well-Known Member
Licensed User
Hi to all, i'm trying to achieve this progressbar, but without success

Screenshot_20190330_100801_b4a.example.jpg

Note that there is a panel background and another panel over it that simulates the progress. Issue in this code is that i must to know the background color of mask (white in this case), but i can't place this view over a not filled background.
I know there is the new view AnotherProgressBar made with bitmapcreator, but i don't understand how to achieve with this view a layout like mine.

This is the code, hope anyone can help me.
Thanks you

B4X:
Sub Activity_Create(FirstTime As Boolean)
    
    pnBackground.Initialize("")
    pnProgress.Initialize("")
    Activity.AddView(pnBackground,20dip,20dip,200dip,24dip)
    pnBackground.AddView(pnProgress,0,0,pnBackground.Width/2,pnBackground.Height)
    
    Dim cd As ColorDrawable
    cd.Initialize2(Colors.Transparent,24dip,2dip,Colors.Red)
    pnBackground.Background = cd
    
    pnProgress.Color = Colors.Red
    
    pnBackground.AddView(CreateMask(pnBackground, 35dip, Colors.White), 0, 0, pnBackground.Width, pnBackground.Height)
End Sub

Sub CreateMask (pnl As Panel, radius As Float, BackgroundColor As Int) As ImageView
    Dim bmp As Bitmap
    bmp.InitializeMutable(pnl.Width, pnl.Height)
    Dim cvs As Canvas
    cvs.Initialize2(bmp)
    cvs.DrawColor(BackgroundColor)
    Dim p As Path
    p.Initialize(0, 0)
    Dim jo As JavaObject = p
    Dim left = 0, top = 0, right = pnl.Width, bottom = pnl.Height As Float
    jo.RunMethod("addRoundRect", Array(left, top, right, bottom, radius, radius, "CW"))
    cvs.ClipPath(p)
    cvs.DrawColor(Colors.Transparent)
    Dim iv As ImageView
    iv.Initialize("")
    iv.Bitmap = bmp
    Return iv
End Sub
 

emexes

Well-Known Member
Licensed User
I did something similar, but just using plain old B4A stuff (four panels in the designer) and not using Java calls.

The four panels look like this (over the top of an olive-green background):

upload_2019-3-30_23-34-13.png


and when you layer them on top of each other, they look like this (with the olive-green background showing through at the corners):

upload_2019-3-30_23-37-33.png


I adjusted the colors so that you could see that the inner bit can be a different color to the outer border, but it is no problem if they are the same color as with your example.

The performance is great (just change the width of the inner rectangular panel) but you can't (easily) show super-low and super-high values, although you can show 0% (turn off both inner panels) and could show 100% (add another inner circular panel and put it on the righthand side).

I'm not proud of this kludge, but it works sufficiently well that I haven't gotten around to "doing it properly".

;-)
 

Emme Developer

Well-Known Member
Licensed User
Hi, thanks for answers.

@Erel i saw two crossplatform progres bar, but the first has not round border, and in the second i was not able to change progress effect, i want to achieve something like my first post
 

Emme Developer

Well-Known Member
Licensed User
You should use B4XCanvas or BitmapCreator to draw such progress bar. Should be quite simple.
Yes i tried with BitmapCreator, but without success. I can't make last part of bar when the border is rounded (for example at 97% value)
 

Jeffrey Cameron

Well-Known Member
Licensed User
Fill your bar with a rectangle to the correct percentage, then draw a circle (or a rounded rectangle with the corner radius = half your height) on the left-hand side of your bar on top of the rectangle; first in your back-ground color, then one final time with your fill color. This should give you your desired look to your left-hand edge.
 

Emme Developer

Well-Known Member
Licensed User
Fill your bar with a rectangle to the correct percentage, then draw a circle (or a rounded rectangle with the corner radius = half your height) on the left-hand side of your bar on top of the rectangle; first in your back-ground color, then one final time with your fill color. This should give you your desired look to your left-hand edge.
Sorry but i don't understand how to achieve what you write if the percentage is more than 98% (for example). At higher value, rectangle has a diagonal greater than circle radius if circle has same dimension as rectangle
 

Star-Dust

Expert
Licensed User
ezgif.com-crop.gif


B4X:
Sub Button1_Click
    For i=0 To 100
        SimpleProgressBar1.Value=i
        Sleep(30)
    Next
End Sub
CustomView XUI without BitmapCreator
B4X:
#DesignerProperty: Key: BooleanExample, DisplayName: Show Seconds, FieldType: Boolean, DefaultValue: True
#DesignerProperty: Key: TextColor, DisplayName: Text Color, FieldType: Color, DefaultValue: 0xFFFF0000, Description: Text color

Sub Class_Globals
    Private mEventName As String 'ignore
    Private mCallBack As Object 'ignore
    Private mBase As B4XView 'ignore
    Private xui As XUI 'ignore
 
    Private Vl As Int = 0
    Private Spessore As Int = 4dip
    Provate Can As B4XCanvas
    Private clr As Int
End Sub

Public Sub Initialize (Callback As Object, EventName As String)
    mEventName = EventName
    mCallBack = Callback
End Sub

'Base type must be Object
Public Sub DesignerCreateView (Base As Object, Lbl As Label, Props As Map)
    mBase = Base
    mBase.Color=xui.Color_Transparent
    clr = xui.PaintOrColorToColor(Props.Get("TextColor")) 'Example of getting a color value from Props
    Can.Initialize(mBase)
    Invalidate
End Sub

Private Sub Base_Resize (Width As Double, Height As Double)
    Invalidate
End Sub

' Set 0..100
Public Sub setValue(V As Int)
    Vl=Min(V,100)
    Invalidate
End Sub

Public Sub  getValue As Int
    Return Vl
End Sub

Public Sub Invalidate
    mBase.Color=xui.Color_Transparent
    'mBase.RemoveAllViews
    Dim Width As Int = Can.TargetView.Width-(2*Spessore)
    Dim Height As Int = Can.TargetRect.Height-(2*Spessore)
 
    Dim Rec As B4XRect
    Rec.Initialize(Spessore,Spessore,Width,Height)
    Dim Path As B4XPath
    Path.InitializeRoundedRect(Rec,Height/2)
    Can.DrawPath(Path,clr,False,Spessore/2)
    Can.ClipPath(Path)
    Rec.Initialize(Spessore,Spessore,Width*(Vl/100),Height)
    Can.DrawRect(Rec,clr,True,Spessore)
    Can.Invalidate
    'Can.Release
End Sub
 

Attachments

Last edited:
Top