Android Question Get Left or Right Swipe From Panel Over Webview?

margret

Well-Known Member
Licensed User
Longtime User
OK. I sort of have this working with the Gesture Detector Lib. It works fine until I zoom the webview. Once I zoom, even if I unzoom, the
GestureListener stops working. If I don't zoom everything works like it should, but zooming breaks it. Once the webview has been zoomed, it then consumes the touch events to display the zoom icons on the display of the device and the GestureListenser never sees the touch events after that.
 
Last edited:
Upvote 0

warwound

Expert
Licensed User
Longtime User
Here's a modified version of the b4a WebView that i've created for Rick Harris.
It's a drop in replacement for the b4a WebView, the only modification being that the FlingableWebView raises a new event:

Fling (MovementX As Float, VelocityX As Float, MovementY As Float, VelocityY As Float) As Boolean

MovementX - the length of the swipe in pixels along the X axis measured in pixels.
VelocityX - the speed of the swipe along the X axis measured in pixels per second.

MovementY - the length of the swipe in pixels along the Y axis measured in pixels.
VelocityY - the speed of the swipe along the Y axis measured in pixels per second.

Change all instances of WebView to instances of FlingableWebView and implement the Fling Sub.
If you're using the Designer to add a WebView to your project then you'll have to make more changes and add the FlingableWebView using code not the Designer.

This is FlingableWebView version 0.01, it may or may not work as you both expect...
My simple demo logs the movement and velocity values and my Fling Sub returns False, so the WebView takes whatever default action it would take on a touch.

Can you update the demo to detect a minimum horizontal movement (MovementX) of +/- 200dip and if detected return True from the Fling Sub and take whatever action you want to take?

B4X:
Sub Process_Globals

End Sub

Sub Globals
   Dim FlingableWebView1 As FlingableWebView
End Sub

Sub Activity_Create(FirstTime As Boolean)
   FlingableWebView1.Initialize("FlingableWebView1")
   Activity.AddView(FlingableWebView1, 32dip, 32dip, 100%x-64dip, 100%y-64dip)

   FlingableWebView1.LoadUrl("http://www.b4x.com/android/forum/threads/get-left-or-right-swipe-from-panel-over-webview.32611/")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub FlingableWebView1_Fling(MovementX As Float, VelocityX As Float, MovementY As Float, VelocityY As Float) As Boolean
   Log("FlingableWebView1_Fling "&MovementX&" "&VelocityX&" | "&MovementY&" "&VelocityY)

   '   this Sub must return a Boolean value

   '   return False to indicate that you have not handled the event
   '   the WebView will take it's default action

   '   return True to indicate that you have handled the event
   '   the WebView will take no action

   Return False
End Sub

Sub FlingableWebView1_PageFinished (Url As String)
   Log("FlingableWebView1_PageFinished Url="&Url)
End Sub

Demo attached.
Library files now updated and can be found here: http://www.b4x.com/android/forum/threads/flingablewebview.33406/.

Martin.
 

Attachments

  • FlingableWebView_demo.zip
    6 KB · Views: 926
Last edited:
Upvote 0

margret

Well-Known Member
Licensed User
Longtime User
Before changing to Martins Lib, I wanted to try an idea that thedesolatesoul had told me about. Seems he(thedesolatesoul(awesome)) was right on the money about what the issue was. The webview brings another view to the front during a zoom. Bringing the webview back to the front after any zoom activity, does allow it to continue to work. However, the view still acts strange from time to time and bringing the view back to the front after the zoom is a bit cumbersome.

The new lib above posted by Martin, seems to correct all the issues. I have it in my app and working fine, just need to do a little more testing! Martin, you are awesome!!!
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
Very nice flingable webview.
Just tried it out.
It does however act a little weird since I tried to use it as an onScroll method. (the use the getScrollY to update the scrollbar).
But on a 'big' fling as the webview keeps scrolling it doesnt update the scrollbar. I guess once it thinks the gesture is registered the event stops firing.
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
@ldb68 I think you're referring to the new version of WebViewExtras.
I've not yet actually uploaded this new version 'properly' to the forum.
I've posted a link to it occasionally though...

Anyway you can find the current new version here: http://android.martinpearman.co.uk/b4a/temp/WebViewExtras2_20130728.zip
Take a look at the WebViewExtras.html file included.

The WebViewClient is now named DefaultWebViewClient.
Here's an example:

B4X:
Sub Process_Globals

End Sub

Sub Globals
   Dim WebView1 As WebView
   Dim WebViewExtras1 As WebViewExtras
End Sub

Sub Activity_Create(FirstTime As Boolean)
   WebView1.Initialize("")
   Activity.AddView(WebView1, 0, 0, 100%x, 100%y)
  
   WebViewExtras1.Initialize(WebView1)
  
   Dim WebViewClient1 As DefaultWebViewClient
   WebViewClient1.Initialize("WebViewClient1")
  
   WebViewExtras1.SetWebViewClient(WebViewClient1)
  
   WebViewExtras1.LoadUrl("http://google.co.uk/")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub WebViewClient1_ScaleChanged(OldScale As Float, NewScale As Float)
   Log("WebViewClient1_ScaleChanged from "&OldScale&" to "&NewScale)
End Sub

That example will detect a zoom change but only when the zoom is changed using the WebView's built in zoom controller.
It won't detect a zoom change from a pinch zoom.

I looked into this a while back and it's a known issue - whether it's a bug (that might one day be fixed) or whether it's the intended behaviour i don't know.

The FlingableWebView uses a GestureDetector to detect flings and as you've found out, adding an additional GestureDetector using b4a overwrites the FlingableWebView's GestureDetector.

Martin.
 
Upvote 0

ldb68

Member
Licensed User
Longtime User
@ldb68 I think you're referring to the new version of WebViewExtras.
I've not yet actually uploaded this new version 'properly' to the forum.
I've posted a link to it occasionally though...

Anyway you can find the current new version here: http://android.martinpearman.co.uk/b4a/temp/WebViewExtras2_20130728.zip
Take a look at the WebViewExtras.html file included.

The WebViewClient is now named DefaultWebViewClient.
Here's an example:

B4X:
Sub Process_Globals

End Sub

Sub Globals
   Dim WebView1 As WebView
   Dim WebViewExtras1 As WebViewExtras
End Sub

Sub Activity_Create(FirstTime As Boolean)
   WebView1.Initialize("")
   Activity.AddView(WebView1, 0, 0, 100%x, 100%y)
 
   WebViewExtras1.Initialize(WebView1)
 
   Dim WebViewClient1 As DefaultWebViewClient
   WebViewClient1.Initialize("WebViewClient1")
 
   WebViewExtras1.SetWebViewClient(WebViewClient1)
 
   WebViewExtras1.LoadUrl("http://google.co.uk/")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub WebViewClient1_ScaleChanged(OldScale As Float, NewScale As Float)
   Log("WebViewClient1_ScaleChanged from "&OldScale&" to "&NewScale)
End Sub

That example will detect a zoom change but only when the zoom is changed using the WebView's built in zoom controller.
It won't detect a zoom change from a pinch zoom.

I looked into this a while back and it's a known issue - whether it's a bug (that might one day be fixed) or whether it's the intended behaviour i don't know.

The FlingableWebView uses a GestureDetector to detect flings and as you've found out, adding an additional GestureDetector using b4a overwrites the FlingableWebView's GestureDetector.

Martin.

Thanks Martin
Is there a way to trap a "double tap" inside a FlingableWebView?
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
The FlingableWebView uses a GestureDetector.SimpleOnGestureListener to detect gestures.
If you look at that link you'll see the various gestures that are available.
I have implemented some of these extras gestures:

FlingableWebView
Version:
0.02

  • Events:
    • DoubleTap (X As Float, Y As Float) As Boolean
    • Fling (MovementX As Float, VelocityX As Float, MovementY As Float, VelocityY As Float) As Boolean
    • LongPress (X As Float, Y As Float)
    • OverrideUrl (Url As String)) As Boolean
    • PageFinished (Url As String)
    • SingleTap (X As Float, Y As Float)) As Boolean
    • UserAndPasswordRequired (Host As String, Realm As String) As String()

    And here's an example project:

    B4X:
    Sub Process_Globals
    
    End Sub
    
    Sub Globals
       Dim FlingableWebView1 As FlingableWebView
    End Sub
    
    Sub Activity_Create(FirstTime As Boolean)
       FlingableWebView1.Initialize("FlingableWebView1")
       Activity.AddView(FlingableWebView1, 32dip, 32dip, 100%x-64dip, 100%y-64dip)
       
       FlingableWebView1.LoadUrl("http://www.b4x.com/android/forum/threads/get-left-or-right-swipe-from-panel-over-webview.32611/")
    End Sub
    
    Sub Activity_Resume
    
    End Sub
    
    Sub Activity_Pause (UserClosed As Boolean)
    
    End Sub
    
    Sub FlingableWebView1_DoubleTap(X As Float, Y As Float) As Boolean
       Log("FlingableWebView1_DoubleTap "&X&", "&Y)
       
       '   this Sub must return a Boolean value
       
       '   return False to indicate that you have not handled the event
       '   the WebView will take it's default action
       
       '   return True to indicate that you have handled the event
       '   the WebView will take no action
       
       Return False
    End Sub
    
    Sub FlingableWebView1_Fling(MovementX As Float, VelocityX As Float, MovementY As Float, VelocityY As Float) As Boolean
       Log("FlingableWebView1_Fling "&MovementX&" "&VelocityX&" | "&MovementY&" "&VelocityY)
       
       '   this Sub must return a Boolean value
       
       '   return False to indicate that you have not handled the event
       '   the WebView will take it's default action
       
       '   return True to indicate that you have handled the event
       '   the WebView will take no action
       
       Return False
    End Sub
    
    Sub FlingableWebView1_LongPress(X As Float, Y As Float)
       Log("FlingableWebView1_LongPress "&X&", "&Y)
       '   note this event has no return value
    End Sub
    
    Sub FlingableWebView1_PageFinished (Url As String)
       Log("FlingableWebView1_PageFinished Url="&Url)
    End Sub
    
    Sub FlingableWebView1_SingleTap(X As Float, Y As Float) As Boolean
       Log("FlingableWebView1_SingleTap "&X&", "&Y)
       
       '   this Sub must return a Boolean value
       
       '   return False to indicate that you have not handled the event
       '   the WebView will take it's default action
       
       '   return True to indicate that you have handled the event
       '   the WebView will take no action
       
       Return False
    End Sub

    The example works mostly as expected but i did notice once that the WebView went into a cycle of zooming in until it was fully zoomed in.
    That may have been because one of the gesture handling subs was returning False so the WebView was also actioning the gesture, or because one or more gestures conflict with the default WebView behaviour - i'm not sure.

    So can you give the updated FlingableWebView a thorough test before deciding whether or not the extra events are useable?

    Example project attached, library files can be found here: http://www.b4x.com/android/forum/threads/flingablewebview.33406/.

    Martin.
 

Attachments

  • FlingableWebView_20131008.zip
    6.1 KB · Views: 557
Last edited:
Upvote 0

ldb68

Member
Licensed User
Longtime User
The FlingableWebView uses a GestureDetector.SimpleOnGestureListener to detect gestures.
If you look at that link you'll see the various gestures that are available.
I have implemented some of these extras gestures:

FlingableWebView
Version:
0.02

  • Events:
    • DoubleTap (X As Float, Y As Float) As Boolean
    • Fling (MovementX As Float, VelocityX As Float, MovementY As Float, VelocityY As Float) As Boolean
    • LongPress (X As Float, Y As Float)
    • OverrideUrl (Url As String)) As Boolean
    • PageFinished (Url As String)
    • SingleTap (X As Float, Y As Float)) As Boolean
    • UserAndPasswordRequired (Host As String, Realm As String) As String()

    And here's an example project:

    B4X:
    Sub Process_Globals
    
    End Sub
    
    Sub Globals
       Dim FlingableWebView1 As FlingableWebView
    End Sub
    
    Sub Activity_Create(FirstTime As Boolean)
       FlingableWebView1.Initialize("FlingableWebView1")
       Activity.AddView(FlingableWebView1, 32dip, 32dip, 100%x-64dip, 100%y-64dip)
       
       FlingableWebView1.LoadUrl("http://www.b4x.com/android/forum/threads/get-left-or-right-swipe-from-panel-over-webview.32611/")
    End Sub
    
    Sub Activity_Resume
    
    End Sub
    
    Sub Activity_Pause (UserClosed As Boolean)
    
    End Sub
    
    Sub FlingableWebView1_DoubleTap(X As Float, Y As Float) As Boolean
       Log("FlingableWebView1_DoubleTap "&X&", "&Y)
       
       '   this Sub must return a Boolean value
       
       '   return False to indicate that you have not handled the event
       '   the WebView will take it's default action
       
       '   return True to indicate that you have handled the event
       '   the WebView will take no action
       
       Return False
    End Sub
    
    Sub FlingableWebView1_Fling(MovementX As Float, VelocityX As Float, MovementY As Float, VelocityY As Float) As Boolean
       Log("FlingableWebView1_Fling "&MovementX&" "&VelocityX&" | "&MovementY&" "&VelocityY)
       
       '   this Sub must return a Boolean value
       
       '   return False to indicate that you have not handled the event
       '   the WebView will take it's default action
       
       '   return True to indicate that you have handled the event
       '   the WebView will take no action
       
       Return False
    End Sub
    
    Sub FlingableWebView1_LongPress(X As Float, Y As Float)
       Log("FlingableWebView1_LongPress "&X&", "&Y)
       '   note this event has no return value
    End Sub
    
    Sub FlingableWebView1_PageFinished (Url As String)
       Log("FlingableWebView1_PageFinished Url="&Url)
    End Sub
    
    Sub FlingableWebView1_SingleTap(X As Float, Y As Float) As Boolean
       Log("FlingableWebView1_SingleTap "&X&", "&Y)
       
       '   this Sub must return a Boolean value
       
       '   return False to indicate that you have not handled the event
       '   the WebView will take it's default action
       
       '   return True to indicate that you have handled the event
       '   the WebView will take no action
       
       Return False
    End Sub

    The example works mostly as expected but i did notice once that the WebView went into a cycle of zooming in until it was fully zoomed in.
    That may have been because one of the gesture handling subs was returning False so the WebView was also actioning the gesture, or because one or more gestures conflict with the default WebView behaviour - i'm not sure.

    So can you give the updated FlingableWebView a thorough test before deciding whether or not the extra events are useable?

    Updated library and example project attached.

    Martin.
thank you vary much

tested on my Nexus 7 and seems works.
I use it to show html page as book (jpeg image with js an link) with zoom disabled.
Use "Fling" event to change page (prior - next).
Use "Double Tap" event to zoom image inside onther webview with zoom enabled.
 
Last edited:
Upvote 0

freedom2000

Well-Known Member
Licensed User
Longtime User
Hi,

I have tested this lib and it works really well.

I use it to display a serie of html pages as an intro to my App whrn I press the "ShowHelp" button. The fling gesture being used to change page.

Basically it works very well but when I reach the "last logical page" I just want to make the webview unvisible.
Here is the code with a trick to avoid the app crashing...

B4X:
Sub ShowHelp_click
    HelpShown = True
    MyW.Visible = True
    DisplayHtmlHelp
End Sub
Sub DisplayHtmlHelp
    Select CurrentHelpPage
    Case 1
        MyW.LoadURL("file:///android_asset/index1.html")
    Case 2
        MyW.LoadURL("file:///android_asset/index2.html")
    Case 3
        MyW.LoadURL("file:///android_asset/index3.html")
    Case Else
        CurrentHelpPage = 1
        MyW.visible = False
    End Select
End Sub
Sub HideHelp
    Dim result As Int
    result = Msgbox2("Show Help next time ?","","Yes","", "No", Null)
    If result = DialogResponse.Positive Then
        'unlock.manager.SetBoolean("help", True)
    Else
        'unlock.manager.SetBoolean("help", False)
    End If

End Sub
Sub timer1_Tick
    timer1.enabled  = False
    HideHelp
    CurrentHelpPage = 0
    DisplayHtmlHelp
End Sub
Sub WithoutTimer
    HideHelp
    CurrentHelpPage = 0
    DisplayHtmlHelp
End Sub

Sub MyW_Fling(MovementX As Float, VelocityX As Float, MovementY As Float, VelocityY As Float) As Boolean

    'Log("FlingableWebView1_Fling "&MovementX&" "&VelocityX&" | "&MovementY&" "&VelocityY)
    '  this Sub must return a Boolean value

      If (MovementX < 0) Then CurrentHelpPage = CurrentHelpPage +1
      If (MovementX > 0) Then CurrentHelpPage = CurrentHelpPage -1
      If CurrentHelpPage < 1 OR CurrentHelpPage > NbHelpPages Then
        timer1.Enabled = True 'needed to allow hidding the webview after exiting this sub (a direct call to HideHelps crashes the app
    Else
        DisplayHtmlHelp
    End If

      Return True '  return False to indicate that you have not handled the event the WebView will take it's default action
                '  return True to indicate that you have handled the event the WebView will take no action
End Sub

I have been obliged to add a timer to introduce a short delay before hiding my webview.
If not (just replace the "timer.enabled = true" by a direct call to "WithoutTimer") and you will see that the app crashes.
The crash occurs systematically at the End Sub of the flingable event routine.

I know that my trick is working but I really would like a cleaner way to exit whitout crashing.

Do you have any idea ?
Thank you in advance
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
Upvote 0

freedom2000

Well-Known Member
Licensed User
Longtime User
Search the forum for "CallSubDelayed":
http://www.b4x.com/android/forum/th...teract-between-activities-and-services.18691/


It might allow you to do something like:

B4X:
      If CurrentHelpPage < 1 OR CurrentHelpPage > NbHelpPages Then
        CallSubDelayed(Main, "WithoutTimer")
    Else
        DisplayHtmlHelp
    End If

Martin.

Thank you Martin,

I already tried to do it, but I didn't succeed with a callsubdelayed in the same activity.

So I tried to activate a service which was in charge to call the "WithoutTimer". It is rather cumbersome and works not all the time (too fast I suppose).
My "timer" method works all the times, but is not really clean ;)
 
Upvote 0

freedom2000

Well-Known Member
Licensed User
Longtime User
If you don't try to show the MsgBox then there is no crash - showing the MsgBox causes the crash?
No the crash is caused whenever you exit the sub after having hidden the webview.

I tried a lot of possibilities this evening and the only one that I found "correct" was the timer. The callsubdelayed via a service started into the event routine was almost correct but crashing 1/3 of the time.
 
Upvote 0
Top