Android Question Extra views event ?

MitchBu

Well-Known Member
Licensed User
Longtime User
I want to be able to move views across the screen with the finger.

I use a panel onto which rest several views.

At this moment, I iterate through GetAllViewsRecursive and use a small sub to check if the finger is within the boundaries of the view. If so I record the view, x and y.

B4X:
Sub PnlMoveView_Touch (Action As Int, X As Float, Y As Float)
If Action = 0 Then'Action Down
        For Each v As View In PnlMoveView.GetAllViewsRecursive
            If Within(v, PnlMoveView, X, Y) Then
                DownX = x
                DownY = y
                ViewToMove = v
                Log("Return " & (DateTime.Now - n))
                Log("> " & ViewToMove.Tag)
                Return   
            End If
        Next
'.../...
end sub

Sub Within(v As View, Pnl As Panel, x As Int, y As Int) As Boolean
    Return (x > v.Left And x < v.Left + v.Width And y > v.Top And y < v.Top + v.height)
End Sub

Right now in the small test project I have only 3 labels.

My problem is that it can take between 800 and 1045 milliseconds to find the view among three. My plan is to use that for 20 views or so.

Ideally, it would be nice to use an event in the view itself to signal the panel touch event which view has been touched.

I tried to return false in the view Click event, but still, the view consumes the event.

In another basic, I could use mouseDown in the view to move instead. Is there any way I could do that ? Perhaps through Java ?

TIA
 

Semen Matusovskiy

Well-Known Member
Licensed User
To find a view, which you touched, requires nothing. Use SetOnTouchListener method of Reflector.
For example:
B4X:
    Dim reflectorInstance                                                       As Reflector
   ...
   reflectorInstance.SetOnTouchListener ("MyLabel_Touch")
Inside subroutine MyLabel_Touch use Sender:
B4X:
Sub MyLabel_Touch (objectInstance As Object, intAction As Int, floatX As Float, floatY As Float, objectMotion As Object) As Boolean

    Dim labelAny                                                                As Label

    labelAny = Sender
    If intAction = Activity.ACTION_DOWN Then
       ...
    Else If intAction = Activity.ACTION_UP Then
       ...
    End If

    Return False

End Sub
 
Upvote 0

MitchBu

Well-Known Member
Licensed User
Longtime User
Semen,

I appreciate your reply. Thank you.

But I am sorry, after compiling, upon run, I get a Java error in the log.

Here is my code :

B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("MoveMe")
    Private reflectorInstance As Reflector
    If FirstTime Then
        reflectorInstance.SetOnTouchListener ("MyLabel_Touch")
    End If
End Sub

B4X:
Sub MyLabel_Touch (objectInstance As Object, intAction As Int, floatX As Float, floatY As Float, objectMotion As Object) As Boolean
    Dim labelAny As Label
    labelAny = Sender
    If intAction = Activity.ACTION_DOWN Then
        Log("Down")
        ViewToMove = Sender
    Else If intAction = Activity.ACTION_UP Then
        Log("Up")
    End If
    Return False
End Sub

Here is the error I get. Line 37 where it happens is when I set the listener.

B4X:
reflectorInstance.SetOnTouchListener ("MyLabel_Touch")

Error occurred on line: 36 (Main)
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnTouchListener(android.view.View$OnTouchListener)' on a null object reference
at anywheresoftware.b4a.agraham.reflection.Reflection.SetOnTouchListener(Reflection.java:1113)
at b4a.example.main._activity_create(main.java:397)
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:144)
at b4a.example.main.afterFirstLayout(main.java:104)
at b4a.example.main.access$000(main.java:17)
at b4a.example.main$WaitForLayout.run(main.java:82)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:7000)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
 
Upvote 0

Semen Matusovskiy

Well-Known Member
Licensed User
SetOnTouchListener is relative to object. Before reflectorInstance.SetOnTouchListener ("MyLabel_Touch") you need to assign reflectorInstance.Target = Label1 (name of your label)
 
Upvote 0

MitchBu

Well-Known Member
Licensed User
Longtime User
SetOnTouchListener is relative to object. Before reflectorInstance.SetOnTouchListener ("MyLabel_Touch") you need to assign reflectorInstance.Target = Label1 (name of your label)

Great. I had been to https://www.b4x.com/android/help/reflection.html#reflector but could not find an example of use.

Now it works as expected, and response time is short enough to make it easy on the user.

I love B4A for the power of the language with these libs.

And for a community always here to help.

Thank you so much, Semen.
 
Upvote 0

MitchBu

Well-Known Member
Licensed User
Longtime User
ahem...

Small side effect...

After adding the event listener to a view, longClick is broken.

Is there any way to remove the event listener ?
 
Last edited:
Upvote 0

Semen Matusovskiy

Well-Known Member
Licensed User
Not sure that reflector supports similar operation.
Meanwhile LongClick is not broken. Try attached sample.
 

Attachments

  • 1.zip
    8.3 KB · Views: 113
Upvote 0

MitchBu

Well-Known Member
Licensed User
Longtime User
Not sure that reflector supports similar operation.
Meanwhile LongClick is not broken. Try attached sample.

Well, I don't know what happens in my project, but long click indeed no longer fires after I have attached the listener to the couple dozen views.

Your small demo project indeed shows the contrary.

I hope I will be able to find what is going on. If not, I simply will have to abandon the feature.

Thank you for your assistance, though.
 
Upvote 0
Top