Android Question Smooth Real-Time Blur Panel Over xCustomListView (Like Telegram)

hesam98

New Member
Licensed User
Longtime User
hello , Does anyone know how to make a panel over a xCustomListView blur very smoothly and without any lag, just like in Telegram? The idea is that the items in the ScrollView appear blurred inside/under that panel.


This design style has become very common lately and most modern apps use it in their UI.
I’ve already tested a lot of methods, many libraries that have been released so far, and even AI-generated solutions — but either they didn’t work properly, or they were laggy and nowhere near as smooth as Telegram (for example) .


I would really appreciate any help!
 

Attachments

  • blur-ex-image1.jpg
    blur-ex-image1.jpg
    40.4 KB · Views: 141

LucasHeer

Active Member
Licensed User
Longtime User
I have never tried this, but my first instinct would be to have an overlaying panel with visibility or alpha set to 0.

Then use XUI/B4XView to set alpha or visibility animated (SetVisibleAnimated, SetAlphaAnimated)

You might be able to get away with finding some kind of blur image filter PNG (with alpha transparency) -- And setting the blur panel background to this..

However, I believe the best results would come from copying the pixels from whatever is underneath the panel and using something like BitmapCreatorEffects to blur the copied bitmap.
 
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
For what you want:
First, you need to know which technique or algorithm to use for cropping the image behind the panel.

Gaussian Blur: The most common technique; it uses a mathematical function to smooth and even out the image.
Box Blur: A faster method than Gaussian blur that averages pixels into rectangular patterns, useful for quick previews.
Fast Blur: It is generally based on frame blur (frame defocus) applied in several passes (usually 3).

Second, you need to control the blur when scrolling.

ref,
 
Upvote 1

TILogistic

Expert
Licensed User
Longtime User
Another single:
 
Upvote 0

hesam98

New Member
Licensed User
Longtime User
Thank you for your reply dear @TILogistic
@LucasHeer

Unfortunately none of the topics mentioned above are optimized for this use case! Those methods are usually fine for blurring a single static item once, but when it comes to live / real-time blur over a scrolling view (ScrollView / xCustomListView) or over a video, they start lagging.
I’ve been trying to implement this properly for about a year now.


Note: I’ve already used library fsGlassmorphism(View with a blurred background) it works great for one-time / static blur, but it’s not suitable for real-time / live blur at all.


I believe Telegram is using something like RenderEffect.createBlurEffect (native Java API 31) for this — probably real-time blur, dynamic blur, or similar names for this technique.
So far I haven’t been able to find a proper library or working example of this method in B4A

I really hope @Erel or other experts in the community will find a good solution for this approach.

Thanks in advance for any help!
 
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
I've seen your replies; the solution for a smooth and quick blur is simple.

Reduce the size of the cropped image.
Apply the box blur technique to the image.

B4X:
Dim scale As Int = 16
Dim bmp As B4XBitmap = PanelBack.Snapshot
bmp = bmp.Resize(bmp.Width / scale, bmp.Height / scale, True)

ImageBlur.Bitmap = BoxBlurFast(bmp, 3)

This will give you a more realistic view of the scrolling by showing the blur of the overlaid panel.

B4X:
Sub BoxBlurFast(bmp As B4XBitmap, radius As Int) As B4XBitmap

Parámeters:
Scale: 1/8 – 1/16
Radius: 3 – 5


If you saw my solution, these techniques are applied where the parameters of blur, color, etc. are adjusted.

 
Last edited:
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
And finally, you can use this technique to add the blurred image to the top panel.
1770663745830.png
 
Last edited:
Upvote 0

zed

Well-Known Member
Licensed User
I'm not sure I understood your request correctly; I'm not familiar with how Telegram works.

This code blurs the CLV during scrolling. When scrolling stops, the blur disappears.

Add a panel above the clv

The example here works with an animation. The project also includes a version without animation.

If this isn't what you asked for, then I don't understand.

B4X:
'-----------------------------
' with animation
'-----------------------------

Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI

    Private CLV1 As CustomListView
    Private BlurPanel As Panel

    Private BlurRadiusStrong As Float = 25dip
    Private BlurRadiusWeak As Float = 0dip

    Private BlurTimer As Timer          ' detects end of scroll
    Private AnimTimer As Timer          ' animates the blur

    Private AnimStart As Float
    Private AnimEnd As Float
    Private AnimStartAlpha As Int
    Private AnimEndAlpha As Int
    Private AnimStartTime As Long
    Private AnimDuration As Int = 200   ' animation duration

    Private CurrentBlur As Float = 0
    Private CurrentAlpha As Int = 0
End Sub



Public Sub Initialize
'    B4XPages.GetManager.LogEvents = True
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
 
    For i = 1 To 50
        CLV1.AddTextItem("Élément " & i, "")
    Next
 
    BlurPanel.Color = Colors.ARGB(0, 0, 0, 0)

    ApplyBlur(BlurPanel, 0)

    BlurTimer.Initialize("BlurTimer", 120)
    AnimTimer.Initialize("AnimTimer", 16) ' ~60 FPS

End Sub

Sub ApplyBlur(v As View, radius As Float)
    Dim jo As JavaObject = Me
    jo.RunMethod("BlurEffect", Array(v, radius))
End Sub

Sub AnimateBlurAndAlpha(TargetRadius As Float, TargetAlpha As Int)
    AnimStart = CurrentBlur
    AnimEnd = TargetRadius

    AnimStartAlpha = CurrentAlpha
    AnimEndAlpha = TargetAlpha

    AnimStartTime = DateTime.Now
    AnimTimer.Enabled = True
End Sub

Sub AnimTimer_Tick
    Dim elapsed As Long = DateTime.Now - AnimStartTime
    Dim t As Float = elapsed / AnimDuration
    If t >= 1 Then
        t = 1
        AnimTimer.Enabled = False
    End If

    ' Blur interpolation
    CurrentBlur = AnimStart + (AnimEnd - AnimStart) * t
    ApplyBlur(BlurPanel, CurrentBlur)

    ' opacity Interpolation
    CurrentAlpha = AnimStartAlpha + (AnimEndAlpha - AnimStartAlpha) * t
    BlurPanel.Color = Colors.ARGB(CurrentAlpha, 255, 255, 255)
End Sub


Sub CLV1_ScrollChanged(Offset As Int)
    AnimateBlurAndAlpha(BlurRadiusStrong, 180)
    BlurTimer.Enabled = False
    BlurTimer.Enabled = True
End Sub

Sub BlurTimer_Tick
    BlurTimer.Enabled = False
    AnimateBlurAndAlpha(BlurRadiusWeak, 0)
End Sub

and JAVA

java:
public static void BlurEffect(android.view.View v, float radius) {
    if (android.os.Build.VERSION.SDK_INT >= 31) {
        android.graphics.RenderEffect effect =
            android.graphics.RenderEffect.createBlurEffect(
                radius, radius,
                android.graphics.Shader.TileMode.CLAMP
            );
        v.setRenderEffect(effect);
    }
}
 

Attachments

  • CLVBlur.zip
    15 KB · Views: 51
Last edited:
Upvote 0
I'm not sure I understood your request correctly; I'm not familiar with how Telegram works.
.........
}[/CODE]
Any idea Why I get 'java.lang.reflect.InvocationTargetException' ? I run the project as is. Thank you.

** Activity (main) Create (first time) **
Error occurred on line: 61 (B4XMainPage)
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:132)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:777)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:354)
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 b4a.example.b4xmainpage._b4xpage_created(b4xmainpage.java:147)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:318)
at anywheresoftware.b4a.debug.Debug.CallSubNew2(Debug.java:285)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.keywords.Common.CallSubDebug2(Common.java:1140)
at b4a.example.b4xpagesmanager._createpageifneeded(b4xpagesmanager.java:1068)
at b4a.example.b4xpagesmanager._showpage(b4xpagesmanager.java:425)
at b4a.example.b4xpagesmanager._addpage(b4xpagesmanager.java:245)
at b4a.example.b4xpagesmanager._addpageandcreate(b4xpagesmanager.java:259)
 
Upvote 0
Can you post the logs when running in release mode?
Thanks for looking into it. Here is the Log from release mode:

Logger connected to: Xiaomi 23076RN4BI
Logger connected to: Xiaomi 23076RN4BI
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create (first time) **
b4xmainpage_applyblur (java line: 97)
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:132)
at b4a.example.b4xmainpage._applyblur(b4xmainpage.java:97)
at b4a.example.b4xmainpage._b4xpage_created(b4xmainpage.java:121)
at b4a.example.b4xmainpage.callSub(b4xmainpage.java:195)
at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:1151)
at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:1122)
at b4a.example.b4xpagesmanager._createpageifneeded(b4xpagesmanager.java:528)
at b4a.example.b4xpagesmanager._showpage(b4xpagesmanager.java:865)
at b4a.example.b4xpagesmanager._addpage(b4xpagesmanager.java:199)
at b4a.example.b4xpagesmanager._addpageandcreate(b4xpagesmanager.java:206)
at b4a.example.b4xpagesmanager._initialize(b4xpagesmanager.java:716)
at b4a.example.main._activity_create(main.java:365)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:221)
at b4a.example.main.afterFirstLayout(main.java:105)
at b4a.example.main.access$000(main.java:17)
at b4a.example.main$WaitForLayout.run(main.java:83)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:224)
at android.os.Looper.loop(Looper.java:318)
at android.app.ActivityThread.main(ActivityThread.java:8772)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:561)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013)
Caused by: java.lang.IllegalArgumentException: nativePtr is null
at libcore.util.NativeAllocationRegistry.registerNativeAllocation(NativeAllocationRegistry.java:509)
at android.graphics.RenderEffect.<init>(RenderEffect.java:314)
at android.graphics.RenderEffect.createBlurEffect(RenderEffect.java:117)
at b4a.example.b4xmainpage.BlurEffect(b4xmainpage.java:201)
... 26 more
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create (first time) **
b4xmainpage_applyblur (java line: 97)
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:132)
at b4a.example.b4xmainpage._applyblur(b4xmainpage.java:97)
at b4a.example.b4xmainpage._b4xpage_created(b4xmainpage.java:121)
at b4a.example.b4xmainpage.callSub(b4xmainpage.java:195)
at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:1151)
at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:1122)
at b4a.example.b4xpagesmanager._createpageifneeded(b4xpagesmanager.java:528)
at b4a.example.b4xpagesmanager._showpage(b4xpagesmanager.java:865)
at b4a.example.b4xpagesmanager._addpage(b4xpagesmanager.java:199)
at b4a.example.b4xpagesmanager._addpageandcreate(b4xpagesmanager.java:206)
at b4a.example.b4xpagesmanager._initialize(b4xpagesmanager.java:716)
at b4a.example.main._activity_create(main.java:365)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:221)
at b4a.example.main.afterFirstLayout(main.java:105)
at b4a.example.main.access$000(main.java:17)
at b4a.example.main$WaitForLayout.run(main.java:83)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:224)
at android.os.Looper.loop(Looper.java:318)
at android.app.ActivityThread.main(ActivityThread.java:8772)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:561)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013)
Caused by: java.lang.IllegalArgumentException: nativePtr is null
at libcore.util.NativeAllocationRegistry.registerNativeAllocation(NativeAllocationRegistry.java:509)
at android.graphics.RenderEffect.<init>(RenderEffect.java:314)
at android.graphics.RenderEffect.createBlurEffect(RenderEffect.java:117)
at b4a.example.b4xmainpage.BlurEffect(b4xmainpage.java:201)
... 26 more
I tried shifting 'apply blur' function to B4x_Appear but I still get the error:

B4X:
Private Sub B4XPage_Appear
    Sleep(0)
    ApplyBlur(BlurPanel, 0)

    BlurTimer.Initialize("BlurTimer", 120)
    AnimTimer.Initialize("AnimTimer", 16) ' ~60 FPS
End Sub
 
Upvote 0

hesam98

New Member
Licensed User
Longtime User
Thanks for the reply @zed @TILogistic


I tested the code, but unfortunately the floating panel over the ScrollView doesn’t get blurred. It only appears blurred when there’s an item/content on the panel itself.
When the panel is empty and placed over the ScrollView, it doesn’t show a blurred version of the ScrollView content underneath it.
(Maybe the problem is with my SDK and it’s not showing the blur properly, but I tested it on Root1.GetView(0) and it worked fine there. What I actually want is for the floating panel itself to show the blurred content from behind it)

I explained what I mean in the attached screenshot in the topic.
I re-attached my more precise meaning.

Maybe the only practical way is to take a snapshot, blur it, and set it as the panel’s background inside the xCustomListView_ScrollChanged event.

But this method is very slow, causes noticeable lag, and disrupts the scrolling experience.

Thank you for your help.
 

Attachments

  • IMG_6954.jpeg
    IMG_6954.jpeg
    61.2 KB · Views: 82
  • IMG_6955.jpeg
    IMG_6955.jpeg
    62.5 KB · Views: 74
Upvote 0
I can't reproduce the error. Have you tested the project as it is?
I am using the code as is. May be it is brand specific .
Chat GPT says
Why this is Xiaomi-specific (but not a bug):
MIUI aggressively delays view attachment
Render pipeline initialized late
Google Pixel often works earlier
Samsung sometimes in between
I am not sure if it is hallucinating or saying the truth :( I will try with Samsung later.
 
Upvote 0
Top