Other Working: Getting swiping + tapping for images in a panel working together

kanaida

Active Member
Licensed User
Longtime User
Hey guys, after fighting for a few days I found something useful.

I have a panel with various ImageViews inside. I needed localized swiping and image tapping to work together nicely. After trying many things, this is what worked.

Add a panel, and it's touch event
Add the image views on top of the panel in the designer, set the parent to be the panel. Don't set an event name, we're gonna let the panels touch event figure out what to do.

Now we're gonna add the panel_Touch event:
B4X:
Sub panel1_Touch (Action As Int, x As Float, Y As Float)

    Select Action
   
        Case Activity.ACTION_DOWN
            startX = x
            startY = Y
           
        Case Activity.ACTION_UP
            If Abs(Y - startY) > 10%y Then
                Return
            End If
           
            If x - startX > 10%x  Then
                Log("swipe left")
                 
            Else If startX - x > 10%x  Then
                Log("swipe right")

            Else
                Log("Click")
                For i = 0 To panel1.NumberOfViews-1
                    Dim v As View = panel1.GetView(i)
                   
                    If GetType(v) = GetType(SomeImageViewObject) Then
                        If    v.Left <= x AND v.Top <= Y AND v.Left+v.Width >= x AND v.Top+v.Height >= Y Then
                                Log("ImageView Clicked")
                                'I used the tag object to handle the click action, in my case displaying product details in another panel
  
                        End If
                    End If
                   
                   
                   
                Next
            End If
       
    End Select

If anyone has code to detect a LongClick that works reliably, please let me know so I can update my code as well. I'm assuming a timer would be necessary. Hope this helps you guys because it's been a real pain for me to figure this one out. The lesson is that views without an event specified pass touch events to the view below and that image views don't have Touch events but panels do. It also helps to keep it all in a panel so that the x/y coordinates are what's expected. This method works perfectly with the Picasso image loading library. The only other thing I'd like to figure out is getting a swipe looking animation to work with my scheme because since I have thousands of products I use the paging scheme rather than loading them all at once. Some sort of animation would be nice, currently I just clear the products and load another set.
 

barx

Well-Known Member
Licensed User
Longtime User
I did an example once for a user and they reported that it was reliable, here is the code, sure it can be mashed into your existing quite easily...

B4X:
#Region Module Attributes
    #FullScreen: False
    #IncludeTitle: True
    #ApplicationLabel: PanelTouchClick
    #VersionCode: 1
    #VersionName:
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

'Activity module
Sub Process_Globals

    Dim timer0 As Timer
    Dim TouchX, TouchY As Int
    Dim Drag, ClickState As Boolean
   
End Sub

Sub Globals
    Dim pnl As Panel
End Sub

Sub Activity_Create(FirstTime As Boolean)
    pnl.Initialize("pnl")
    Activity.AddView(pnl, 50dip, 50dip, 100%x - 100dip, 100%y - 100dip)
    timer0.Initialize("Timer0", 1000)
    Drag = False
    ClickState = False
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub pnl_Touch (Action As Int, X As Float, Y As Float)
    Log(Action)
    Select Action
    Case Activity.ACTION_DOWN
        TouchX = X
        TouchY = Y
        ClickState = True
        timer0.Enabled = True
       
    Case Activity.ACTION_UP
        timer0.Enabled = False   
        ClickCheck (X, Y)
    Case Activity.ACTION_MOVE
        If (X < (TouchX - 10dip)) OR (X > (TouchX + 10dip)) OR (Y < (TouchY - 10dip)) OR (Y > (TouchY + 10dip)) Then
            Drag = True
            timer0.Enabled = False
        End If
    End Select
       
End Sub

Sub timer0_Tick
    ClickState = False
    ClickCheck(TouchX, TouchY)
End Sub

Sub ClickCheck(x As Int, y As Int)
    If Not(x < (TouchX - 10dip)) AND Not(x > (TouchX + 10dip)) AND Not(y < (TouchY - 10dip)) AND Not(y > (TouchY + 10dip)) Then
        If ClickState Then
            ClickEvent
            timer0.Enabled = False
        Else
            LongClickEvent
            timer0.Enabled = False
        End If
    End If
End Sub

Sub ClickEvent
    ToastMessageShow("Click", False)
End Sub

Sub LongClickEvent
    ToastMessageShow("LongClick", False)
End Sub
 
Upvote 0

kanaida

Active Member
Licensed User
Longtime User
Thanks. I just tried using a similar approach, ended up with a customizable long click, based on how many milliseconds you hold it down for, then lift up your finger, as opposed to just popping up something else after x amount of time, so I can tap, medium length tap and let go, and possibly more. I'm exploring the usefulness for line of business type apps.

I was thinking maybe:
tap: show product details
med tap: context menu for stuff
long tap or diagonal swipe towards a shopping cart icon: add to shopping cart (count the number of ticks to determine what sub to call)
 
Upvote 0
Top