Android Code Snippet Animated Border

Erel

Administrator
Staff member
Licensed User


The CircularProgressBar class includes a generic animation code that you can use to create all kinds of animations.

We only need to implement the DrawValue sub. In this case we will draw a border around the view.
The value will be between 0 to 100. The top and bottom borders will be drawn between 0 to 50 and the other borders between 50 to 100.

B4X:
Private Sub DrawValue(View As View, cvs As Canvas, Value As Float)
   Dim clr As Int = Colors.White
   Dim strokewidth As Int = 4dip
   Dim cx = View.Width / 2 As Float
   Dim width As Float = View.Width / 50 * Min(50, Value)
   cvs.DrawLine(cx - width / 2, 0, cx + width / 2, 0, clr, strokewidth)
   cvs.DrawLine(cx - width / 2, View.Height, cx + width / 2, View.Height, clr, strokewidth)
   If Value > 50 Then
     Dim height As Float = View.Height / 50 * (Value - 50)
     cvs.DrawLine(0, 0, 0, height / 2, clr, strokewidth)
     cvs.DrawLine(0, View.Height, 0,  View.Height - height / 2, clr, strokewidth)
     cvs.DrawLine(View.Width, 0, View.Width, height / 2, clr, strokewidth)
     cvs.DrawLine(View.Width, View.Height, View.Width, View.Height - height / 2, clr, strokewidth)
   End If
   View.Invalidate
End Sub
 

Attachments

Emme Developer

Well-Known Member
Licensed User
Another animation of border based on @Erel example :)

B4X:
Private Sub DrawValueProgressive(view As View, cvs As Canvas, value As Float,clr As Int)

 
    Select Floor(value/25)
        Case 0
            Dim width As Float = view.Width / 25 * Min(25, value)
            cvs.DrawLine(0,0,width,0,Colors.White,4dip)
        Case 1
            Dim height As Float = view.Height / 25 * (value-25)
            cvs.DrawLine(view.width,0,view.width,height,Colors.White,4dip)
            cvs.DrawLine(0,0,view.Width,0,Colors.White,4dip)
        Case 2
            Dim width As Float = view.Width / 25 * (value-50)
            cvs.DrawLine(view.Width,view.Height,view.Width-width,view.Height,Colors.White,4dip)
            cvs.DrawLine(0,0,view.Width,0,Colors.White,4dip)
            cvs.DrawLine(view.Width,0,view.Width,view.Height,Colors.White,4dip)
        Case 3
            Dim height As Float = view.Height / 25 * (value-75)
            cvs.DrawLine(0,view.Height,0,view.Height-height,Colors.White,4dip)
            cvs.DrawLine(0,0,view.Width,0,Colors.White,4dip)
            cvs.DrawLine(view.Width,0,view.Width,view.Height,Colors.White,4dip)
            cvs.DrawLine(view.Width,view.Height,0,view.Height,Colors.White,4dip)
    End Select
    view.Invalidate
End Sub

Private Sub AnimateBorderProgressive(view As View)
    Dim n As Long = DateTime.Now
    Dim duration As Int = 250
    Dim start As Float = 0
    Dim tempValue As Float
    Dim cvs As Canvas
    cvs.Initialize(view)
    cvs.DrawColor(Colors.Transparent)
    Do While DateTime.Now < n + duration
        tempValue = ValueFromTimeLinear(DateTime.Now - n, start, 100 - start, duration)
        DrawValueProgressive(view,cvs,tempValue,Colors.White)
        Sleep(10)
    Loop
    DrawValue(view, cvs, 100,Colors.White)
End Sub
 

Emme Developer

Well-Known Member
Licensed User
Another one :)
B4X:
Private Sub ABProgressiveMeet (view As View)
    Dim n As Long = DateTime.Now
    Dim duration As Int = 500
    Dim start As Float = 0
    Dim tempValue As Float
    Dim cvs As Canvas
    cvs.Initialize(view)
    cvs.DrawColor(Colors.Transparent)
    Do While DateTime.Now < n + duration
        tempValue = ValueFromTimeLinear(DateTime.Now - n, start, 100 - start, duration)
        DWProgressiveMeet(view,cvs,tempValue,Colors.White)
        Sleep(10)
    Loop
    DrawValue(view, cvs, 100,Colors.White)
End Sub

Private Sub DWProgressiveMeet(view As View, cvs As Canvas, value As Float,clr As Int)
    Dim strokewidth As Int = 4dip
    Dim width As Float = view.Width / 50 * Min(50, value)
    Dim height As Float = view.Height / 50 * Min(50, value)
    cvs.DrawLine(0, 0, width, 0, clr, strokewidth)
    cvs.DrawLine(0,0,0,height, clr, strokewidth)
    If value > 50 Then
        Dim width As Float = view.Width / 50 * (value-50)
        Dim height As Float = view.Height / 50 *  (value-50)
        cvs.DrawLine(0, 0, 0, view.height, clr, strokewidth)
        cvs.DrawLine(0, 0,  view.Width, 0,clr, strokewidth)
        cvs.DrawLine(0, view.Height, width,view.Height,  clr, strokewidth)
        cvs.DrawLine(view.Width, 0, view.Width, height, clr, strokewidth)
    End If
    view.Invalidate
End Sub
 

Erel

Administrator
Staff member
Licensed User
This code will create a rounded rect border that is animated a bit differently:

B4X:
Private Sub AnimateBorder(View As View)
   Dim n As Long = DateTime.Now
   Dim duration As Int = 500
   Dim start As Float = 0
   Dim tempValue As Float
   Dim cvs As Canvas
   cvs.Initialize(View)
   cvs.DrawColor(Colors.Transparent)
   cvs.AntiAlias = True
   Do While DateTime.Now < n + duration
     tempValue = ValueFromTimeLinear(DateTime.Now - n, start, 360 - start, duration)
     DrawValue(View, cvs, tempValue)
     Sleep(10)
   Loop
   DrawValue(View, cvs, 360)
End Sub

Private Sub DrawValue(View As View, cvs As Canvas, Value As Float)
   Dim clr As Int = Colors.White
   cvs.DrawColor(Colors.Transparent)
   Dim strokewidth As Int = 2dip
   Dim cx = View.Width / 2, cy = View.Height / 2 As Float
   
   Dim r As Rect
   r.Initialize(-100dip, -100dip, View.Width + 200dip, View.Height + 200dip)
   Dim ArcRect As JavaObject
   ArcRect.InitializeNewInstance("android.graphics.RectF", Array(r))
   Dim p As Path
   p.Initialize(cx, cy)
   Dim jo As JavaObject = p
   Dim start As Float = -90
   jo.RunMethod("arcTo", Array(ArcRect, start, Value))
   If Value < 360 Then cvs.ClipPath(p)
   DrawRoundRect(cvs, 1dip, 1dip, View.Width - 2dip, View.Height - 2dip, 10dip, clr, False, strokewidth)
   If Value < 360 Then cvs.RemoveClip
   View.Invalidate
End Sub


Sub DrawRoundRect (TheCanvas As Canvas, fLeft As Float, fTop As Float, fRight As Float, fBottom As Float, Rx As Float, Color As Int, Filled As Boolean, StrokeWidth As Float)
   Dim CnvJO As JavaObject = TheCanvas
   Dim RealCanvas As JavaObject = CnvJO.GetField("canvas")
   Dim RectF As JavaObject
   RectF.InitializeNewInstance("android.graphics.RectF", Null)
   RectF.RunMethodJO("set", Array(fLeft, fTop, fRight, fBottom))
   Dim Paint As JavaObject
   Paint.InitializeNewInstance("android.graphics.Paint", Array(1))
   Paint.RunMethodJO("setStrokeWidth", Array(StrokeWidth))
   Paint.RunMethodJO("setColor", Array(Color))
   If Filled = True Then
     Paint.RunMethodJO("setStyle", Array("FILL"))
   Else
     Paint.RunMethodJO("setStyle", Array("STROKE"))
   End If
   RealCanvas.RunMethod("drawRoundRect", Array(RectF, Rx, Rx, Paint))
End Sub
 

Syd Wright

Well-Known Member
Licensed User
Nice work! It would be nice if a "Speech Cloud" border could be added. Something like this:

upload_2017-12-10_21-8-59.png
 
Top