B4A Library [B4X] [XUI] B4XProgressBar - cross platform progress bar

B4XProgressBar.gif


A cross platform progress bar with built-in animation. Similar to: https://www.b4x.com/android/forum/threads/b4x-xui-custom-view-circularprogressbar.81604/#content

You can change the colors, thickness and orientation.
 

Attachments

  • B4XProgressBar.zip
    10.3 KB · Views: 1,903

incendio

Well-Known Member
Licensed User
Longtime User
Error when compiled :

Object reference not set to an onstance of an object.

B4A 7.8
 

IlCasti

Active Member
Licensed User
Longtime User
Hi Erel,
How can we add % over progress bar?

I mean directly in the custom view
Thank you.
 

abilio486software

Active Member
Licensed User
B4XProgressBar.gif


A cross platform progress bar with built-in animation. Similar to: https://www.b4x.com/android/forum/threads/b4x-xui-custom-view-circularprogressbar.81604/#content

You can change the colors, thickness and orientation.
B4XProgressBar.gif


A cross platform progress bar with built-in animation. Similar to: https://www.b4x.com/android/forum/threads/b4x-xui-custom-view-circularprogressbar.81604/#content

You can change the colors, thickness and orientation.

Hi,

I'm trying to add this progress bar to a scrollview, trough "scrollview.Panel.AddView(..." but I'm getting an error from the
 

abilio486software

Active Member
Licensed User
Hi,

I'm trying to add this progressbar trough "scrollview.Panel.Addview(..." but the compiler reports an error telling that this object is not convertible to a view.

Ho to add it without the designer? I build my interface adding the objects in code.

Can someone help?

Kind regards,
Abilio
 

abilio486software

Active Member
Licensed User
This is a common mistake.

You must add custom views with the designer. You can create a layout file with a single progress bar and load it whenever you need to add one.

Hi, Thank you for your quick help.

Sorry but it's not a mistake.

We prefeer to build the interface at runtime with commands. It's a developer decision.

It is possible to use this progress bar without the designer?

Kind Regards,
Abilio
 

Jerryk

Active Member
Licensed User
Longtime User
It works well. But it crashes on my son's low-end Redmi smartphone. Here is the extract from Crashlytics:
B4X:
 Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'anywheresoftware.b4a.objects.B4XCanvas$B4XRect anywheresoftware.b4a.objects.B4XCanvas.getTargetRect()' on a null object reference
       at cz.flashcards3000.b4xprogressbar._drawvalue(b4xprogressbar.java:206)
       at cz.flashcards3000.b4xprogressbar$ResumableSub_AnimateValueTo.resume(b4xprogressbar.java:105)
       at cz.flashcards3000.b4xprogressbar._animatevalueto(b4xprogressbar.java:52)
       at cz.flashcards3000.b4xprogressbar._setprogress(b4xprogressbar.java:258)
       at cz.flashcards3000.plearn._displayrecordl(plearn.java:421)
       at cz.flashcards3000.plearn$ResumableSub_LoadDataLern.resume(plearn.java:648)
       at anywheresoftware.b4a.keywords.Common$14.run(Common.java:1748)
       at android.os.Handler.handleCallback(Handler.java:883)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       at android.os.Looper.loop(Looper.java:227)
       at android.app.ActivityThread.main(ActivityThread.java:7822)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1026)
Gemini analyzed
B4X:
Crash Summary:

A NullPointerException occurred in the _drawvalue method of the b4xprogressbar.java file, specifically on line 206. The exception message indicates that B4XCanvas.getTargetRect() was called on a null B4XCanvas object. This crash is related to a custom progress bar component ( b4xprogressbar ). The crash only manifests on OnePlus devices, suggesting a potential device-specific issue or incompatibility. The stack trace shows the crash originated within an animation routine ( _animatevalueto calling ResumableSub_AnimateValueTo ). NullPointerExceptions are very common in Android development, often stemming from improper initialization or unexpected null values passed between methods.

Potential Causes:

Uninitialized B4XCanvas : The most likely cause is that the B4XCanvas object used in _drawvalue is not properly initialized before getTargetRect() is called. This could be due to a logic error in the b4xprogressbar component's initialization or lifecycle management. The component might not be fully initialized when the animation starts.

Timing Issues: The animation ( _animatevalueto ) might be triggered before the B4XCanvas is ready. This is especially possible if the B4XCanvas is linked to a UI element that hasn't yet been drawn or laid out.

OnePlus Device-Specific Issue: The fact that the crash only occurs on OnePlus devices suggests a potential incompatibility with a specific aspect of the OnePlus device's Android implementation (possibly related to canvas initialization, drawing, or timing). This could involve a timing difference in the drawing process or a variation in how the UI elements are handled compared to other devices.

Android 11 Specific Behavior: While not explicitly stated, there might be a difference in behavior on Android 11 compared to other Android versions that could be influencing the B4XCanvas initialization. Specific changes in Android 11's rendering or lifecycle might affect the timing of the canvas initialization.

Debugging Recommendations:

Verify B4XCanvas Initialization: Carefully examine the b4xprogressbar code, specifically focusing on the initialization of the B4XCanvas object. Ensure that it is definitely initialized before getTargetRect() is called in _drawvalue . Add logging statements to verify that the B4XCanvas object is not null before accessing its methods. Consider null checks before accessing the B4XCanvas object. Example:

if (canvas != null) {
    B4XCanvas.B4XRect rect = canvas.getTargetRect();
    // ... use rect ...
} else {
    Log.e("B4XProgressBar", "B4XCanvas is null in _drawvalue");
    // Handle the null case appropriately (e.g., skip drawing or show an error)
}
Examine Animation Timing: Check the timing of the animation ( _animatevalueto ). Ensure it’s triggered only after the b4xprogressbar and its associated B4XCanvas are fully initialized and ready for drawing. Consider using a View.post() or similar mechanism to delay the animation start until after the view's onDraw has been called at least once.

Device-Specific Debugging: If possible, test on multiple OnePlus devices running Android 11 to confirm the issue is reproducible. Compare the behavior with other device manufacturers to pinpoint specific differences.

Android 11 Specific Checks: Research any changes in Android 11 that might impact canvas initialization or drawing timing. Check the official Android documentation for potential changes relevant to the B4XCanvas library you are using (although this was explicitly excluded from the question).

Preventive Measures:

Robust Null Checks: Consistently add null checks before using any object that could potentially be null. This is a fundamental best practice for preventing NullPointerExceptions .

Defensive Programming: Anticipate potential errors, such as delayed initialization or unexpected null values, and handle them gracefully. Implement error handling for critical parts of your code.

Thorough Testing: Test your application on a wide variety of devices and Android versions to uncover potential compatibility issues early.
 

Jerryk

Active Member
Licensed User
Longtime User
I'm turning to you Erel because it's your code. As we already wrote on my OnePlus B4XProgressBar works fine, but on my son's tablet and smartphone it crashes. So I uploaded the debug code to the tablet and the program crashed on the line -> cvs.ClearRect(cvs.TargetRect):
B4XProgressBar:
 Private Sub DrawValue(Value As Float)
    cvs.ClearRect(cvs.TargetRect)  <<<<<<<<<<<< crashed here
    If vertical Then
        cvs.DrawLine(cvs.TargetRect.CenterX, 0, cvs.TargetRect.CenterX, cvs.TargetRect.Bottom, bcolor, thickness)
        cvs.DrawLine(cvs.TargetRect.CenterX, 0, cvs.TargetRect.CenterX,  Value / 100 * cvs.TargetRect.Bottom, pcolor, thickness)
    Else
        cvs.DrawLine(0, cvs.TargetRect.CenterY, cvs.TargetRect.Right, cvs.TargetRect.CenterY, bcolor, thickness)
        cvs.DrawLine(0, cvs.TargetRect.CenterY, Value / 100 * cvs.TargetRect.Right, cvs.TargetRect.CenterY, pcolor, thickness)
    End If
    cvs.Invalidate
End Sub

B4X:
Error occurred on line: 83 (B4XProgressBar)
java.lang.NullPointerException: null receiver
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
    at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262)
    at cz.flashcards3000.plearn._displayrecordl(plearn.java:724)
    at cz.flashcards3000.plearn$ResumableSub_LoadDataLern.resume(plearn.java:311)
    at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)
    at anywheresoftware.b4a.keywords.Common$14.run(Common.java:1748)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:236)
    at android.app.ActivityThread.main(ActivityThread.java:8164)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
 
Top