Android Question Ripple effect on parent

Emme Developer

Well-Known Member
Licensed User
Longtime User
Hi everybody! Is possible to achieve a ripple effect on parent of button?
I've a list of panels, that have 2 buttons. I want to do a ripple effect on entire panel when i click one button.
I tried different libraries, but without any result..
Thanks!
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can use this code:
B4X:
Sub ActivateRipple(btn As Button)
   If GetType(btn.Background) = "android.graphics.drawable.RippleDrawable" Then
     Dim jo As JavaObject = btn.Background
     Dim x = btn.Width / 2, y = btn.Height / 2 As Float
     jo.RunMethod("setHotspot", Array(x, y))
     Dim sd As StateListDrawable 'ignore
     jo.RunMethod("setState", Array(Array As Int(sd.State_Pressed, sd.State_Enabled)))
     Sleep(200)
     jo.RunMethod("setState", Array(Array As Int(sd.State_Enabled)))
   End If
End Sub
 
Upvote 0

Emme Developer

Well-Known Member
Licensed User
Longtime User
You can use this code:
B4X:
Sub ActivateRipple(btn As Button)
   If GetType(btn.Background) = "android.graphics.drawable.RippleDrawable" Then
     Dim jo As JavaObject = btn.Background
     Dim x = btn.Width / 2, y = btn.Height / 2 As Float
     jo.RunMethod("setHotspot", Array(x, y))
     Dim sd As StateListDrawable 'ignore
     jo.RunMethod("setState", Array(Array As Int(sd.State_Pressed, sd.State_Enabled)))
     Sleep(200)
     jo.RunMethod("setState", Array(Array As Int(sd.State_Enabled)))
   End If
End Sub

Hi Erel, thanks for your answer. I'm trying to work with your code, but i have some issue.
To apply effect on panel, i worked in this way

Apply ripple
B4X:
Sub SetRipple (v As View)
    Dim P As Phone
    If P.SdkVersion < 21 Then
        'Android version < 5.0 Lollipop -> StateListDrawable
        Dim PressedCD As ColorDrawable
        PressedCD.Initialize(Colors.Blue, 0)
        Dim DefaultCD As ColorDrawable
        DefaultCD.Initialize(Colors.Gray, 0)
        Dim bStateList As StateListDrawable
        bStateList.Initialize
        bStateList.AddState(bStateList.State_Pressed, PressedCD)
        bStateList.AddCatchAllState(DefaultCD)
        v.Background = bStateList
    Else
        'Android version >= 5.0 Lollipop -> RippleDrawable
        Dim bRipple As RippleDrawable
        bRipple.Initialize(Colors.White, Colors.Red)
        v.Background = bRipple.Drawable
       
    End If
End Sub

Called ripple
B4X:
SetRipple(b.Parent)
ActivateRipple(b.Parent,3000, b.Top +b.Height/2)

Sub ActivateRipple(btn As View,x As Float, y As Float)
    If GetType(btn.Background) = "android.graphics.drawable.RippleDrawable" Then
        Dim jo As JavaObject = btn.Background
        jo.RunMethod("setHotspot", Array(x, y))
        Dim sd As StateListDrawable 'ignore
        jo.RunMethod("setState", Array(Array As Int(sd.State_Pressed, sd.State_Enabled)))
'        Sleep(200)
        jo.RunMethod("setState", Array(Array As Int(sd.State_Enabled)))
    End If
End Sub

But when i try to setHotspot (i think they are cordinate of where ripple is started) it starts from center. I tried also to set transition time, but without success.
RippleDrawable is library from @Informatix
 
Upvote 0

Emme Developer

Well-Known Member
Licensed User
Longtime User
The Sleep is required. If you use a version before 7.00 then you should move the last line to a different sub and call it with CallSubDelayed.

What is the problem? The hotspot?
Yes, i got the RippleEffect from center, but i want to choose the coordinate. I also want, if is possible, to set time of transition. Thanks for you patience
 
Upvote 0

Emme Developer

Well-Known Member
Licensed User
Longtime User
The coordinates you pass look wrong:
B4X:
ActivateRipple(b.Parent,3000, b.Top +b.Height/2)

I don't think that it is possible to change the animation duration.
I tried 3000 to see if chance anything, but before i tried more coordinate. Same issue, start from center
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I've tested it with this code on Android 7:
B4X:
Sub ActivateRipple(btn As Button)
   If GetType(btn.Background) = "android.graphics.drawable.RippleDrawable" Then
     Dim jo As JavaObject = btn.Background
     Dim x = 2dip, y = 2dip As Float
     jo.RunMethod("setHotspot", Array(x, y))
     Dim sd As StateListDrawable 'ignore
     jo.RunMethod("setState", Array(Array As Int(sd.State_Pressed, sd.State_Enabled)))
     Sleep(200)
     jo.RunMethod("setState", Array(Array As Int(sd.State_Enabled)))
   End If
End Sub
The ripple does start from the top left corner.

The hotspot is only a hint to the system so it is possible that it doesn't do anything on older versions.
 
Upvote 0

Emme Developer

Well-Known Member
Licensed User
Longtime User
I've tested it with this code on Android 7:
B4X:
Sub ActivateRipple(btn As Button)
   If GetType(btn.Background) = "android.graphics.drawable.RippleDrawable" Then
     Dim jo As JavaObject = btn.Background
     Dim x = 2dip, y = 2dip As Float
     jo.RunMethod("setHotspot", Array(x, y))
     Dim sd As StateListDrawable 'ignore
     jo.RunMethod("setState", Array(Array As Int(sd.State_Pressed, sd.State_Enabled)))
     Sleep(200)
     jo.RunMethod("setState", Array(Array As Int(sd.State_Enabled)))
   End If
End Sub
The ripple does start from the top left corner.

The hotspot is only a hint to the system so it is possible that it doesn't do anything on older versions.

Hi Erel, i tried it with 2dip, but for me doesn't work. Maybe because i use a libraries to achieve ripple effect, so in the librarie can be set the absolute coordinates (i think).
I tried also on Android 7, android 6, but same thing. But i solved the issue with your new nice code snippet, so thanks anyway
 
Upvote 0
Top