Android Question Is Panel1_Touch() a boolean function?

Widget

Well-Known Member
Licensed User
Longtime User
I noticed code in this forum that has the Panel_Touch returning a boolean value to consume the event:

Example:
B4X:
Sub Panel1_Touch (Action As Int, X As Float, Y As Float) As Boolean 
  '--- some code to process the touch action ---
   
  Return True    'Prevent underling view (if there is one) from handling touch event
end sub

I'm using B4A 6.5 and the designer generates the touch event as:

Sub Panel1_Touch (Action As Int, X As Float, Y As Float)​

without the Boolean return value.

I've done some testing and I don't think is currently necessary for touch events to return a True value to prevent other views from handling the event. In other words the Touch event does not have to return True to consume the event.

Is this true?


TIA
 

LucaMs

Expert
Licensed User
Longtime User
The strange thing is that you can set the returned type as Boolean, String, Int, etc. and you don't get errors, the event will be raised anyway and its existence prevents underling views from...

Both the Designer and the "intellisense" create the event as method, not as function (apparently).


P.S.
It seems to me that compiling with the returned value as number, the java code created will be:
return 0;

If you don't declare its type:
return "";

Probably, all Subs are functions, with a hidden string value returned.

Anyway you don't need to write "return xxx" to consume the event.
 
Last edited:
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
The strange thing is that you can set the returned type as Boolean, String, Int, etc. and you don't get errors, the event will be raised anyway and its existence prevents underling views from...

Both the Designer and the "intellisense" create the event as method, not as function (apparently).


P.S.
It seems to me that compiling with the returned value as number, the java code created will be:
return 0;

If you don't declare its type:
return "";

Probably, all Subs are functions, with a hidden string value returned.

Anyway you don't need to write "return xxx" to consume the event.

Thanks, I also tried returning True after declaring Panel1_Touch as function as you did, and it had no effect.

But here's the problem. I have a custom view, similar to Klaus's LimitBar where the user can drag the panel horizontally and the panel changes its size. Works great when the LimitBar is placed on a Panel or Activity.

Except if I have the LimitBar on a HorizontalScrollView things go wonky. If I touch the LimitBar (panel) and start to drag it, it will execute the ltbPanelFront_Touch event as expected. It will be called 5 times with Action=0 (Down), Action=2 (Drag), Action=2 (Drag), Action=2 (Drag), Action=3 (Unknown) and for some reason the X & Y parameters now point to a spot outside the dimensions of LimitBar. The finger is still inside the LimitBar so the X,Y values are incorrect.

When it is called the 5th time with Action=3, the drag operation is now intercepted by the HorizontalScrollView and the HorizontalScrollView starts moving and the LimitBar drag operation is stopped dead. This is wrong because the LimitBar still has the focus and the finger is still inside the LimitBar (but the X,Y parameters are outside the dimension of the LimitBar). The HorizontalScrollView never got the Down touch event, so why is it scrolling?

I included a simple test app to demonstrate the problem.

Is there any way to lock the HorizontalScrollView to prevent it from scrolling?

TIA
 

Attachments

  • ClsLimitBarOnHSV.zip
    11.8 KB · Views: 177
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Is there any way to lock the HorizontalScrollView to prevent it from scrolling?
I think you could do it this way:

B4X:
Sub Globals
Private mReflector As Reflector



mReflector.Target = HSV
mReflector.SetOnTouchListener("HSV_Touch")

Sub HSV_Touch (obj As Object, Action As Int, X As Float, Y As Float, MotionEvent As Object) As Boolean
   Log("HSV_Touch")
   Return True
End Sub

but I don't know if it can help.

[Obviously, you should set and remove the OnTouchListener in the right place - when "scrolling the limits"]
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

klaus

Expert
Licensed User
Longtime User
Sub Panel1_Touch (Action As Int, X As Float, Y As Float) As Boolean
As Erel already posted, there were B4A versions which had the boolean return value, and was removed in newer versions.
If you download the current version of the B4A User's Guide.
The code in ClsLimitBar2 is without the return value:
Private Sub ltbPanelFront_Touch (Action As Int, X As Float, Y As Float)
You can remove the return value and remove the Return True line at the end of the routine.
The problem with the HorizontalScrollView is that it takes over the move action.
I didn't know that the LimitBar_Touch event would be raised for a short time.

Another point in your code:
You must never load a layout in If FirstTime = True Then
 
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
I used your Reflector example to disable the HSV touch altogether by setting it to:

mReflector.Target = HSV
mReflector.SetOnTouchListener("")

and it does not solve the problem. The HSV still takes over control from the LimitBar.
Even if the HSV doesn't have to scroll, because its InnerWidth = Width, it will still intercept the touch and will cause the LimitBar touch to fail.

The only solution I see is to replace the HorizontalScrollView with a class of my own. It's not that difficult and I will have full control of what it does.

Thanks anyways.
 
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
Sub Panel1_Touch (Action As Int, X As Float, Y As Float) As Boolean
As Erel already posted, there were B4A versions which had the boolean return value, and was removed in newer versions.
If you download the current version of the B4A User's Guide.
The code in ClsLimitBar2 is without the return value:
Private Sub ltbPanelFront_Touch (Action As Int, X As Float, Y As Float)
You can remove the return value and remove the Return True line at the end of the routine.

Yes, I actually added the return value to the function to see if it would make a difference and it didn't. This wasn't in your original User's Guide code.

The problem with the HorizontalScrollView is that it takes over the move action.
I didn't know that the LimitBar_Touch event would be raised for a short time.

Yup. The two views (Panel & HorizontalScrollView) just don't get along when it comes to Touching. The LimitBar gets its hand slapped. :rolleyes:

Another point in your code:
You must never load a layout in If FirstTime = True Then
Yes, my Bad. :(
 
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
You have to add also the event routine, to temporarily "disable" the hsv scrolling (while you "scroll" your limitbar).

This is what I meant in #4.

Using your code, the HSV_Touch gets executed when the LimitBar is being dragged. But it doesn't change anything. The HSV takes control over any drag operations for any view that it contains. The LimitBar drag operation is stopped dead by the HSV. (The HSV gives the LimitBar a big slap - Don't touch me you CAD):D

The only solution is to replace HorizontalScrollView with horizontally scroll panels because at least they get along.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
My code was "general" code, I have not tried to insert it in your custom view (I suppose you could do it and you should also check what is the type of its parent).

If you solve with panels or other methods, perfect; I just wanted to answer your specific question:
Is there any way to lock the HorizontalScrollView to prevent it from scrolling?
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
I am afraid that you need to find a solution without a HorizontalScrollView.
Or a small HorizontalScrollView at the bottom and a Panel with the LimitBars on it, attached your modified project.
But this is probably not what you want.
 

Attachments

  • ClsLimitBarOnHSV1.zip
    12.2 KB · Views: 212
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
I am afraid that you need to find a solution without a HorizontalScrollView.
Or a small HorizontalScrollView at the bottom and a Panel with the LimitBars on it, attached your modified project.
But this is probably not what you want.

Thanks for the demo. Actually yours is a pretty good alternative. It has my creative juices going. :rolleyes:

I had thought of using a SeekBar to move the panels, but a separate HorizontalScrollView may work too, if I can convince the user it is there and how to use it. Maybe I'll put some arrow "icon" labels "<" ">" interspersed throughout the HSV using FontAwesome or MaterialIcons to indicate motion?

I was also going to put a touch event on Panel5 (the bottom panel) so it would move like a HorizontalScrollView. This will work with panels because the TouchEvent for the LimitBar (panel) will NOT be intercepted by Panel5 like it is with HorizontalScrollView. That's because everything is based on panels and panel touch events get along quite well.

What do you think?
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
I was also going to put a touch event on Panel5 (the bottom panel) so it would move like a HorizontalScrollView.
The difference is that the Panel scrolling with the Touch event has not the dynamic scrolling like a HorizontalScrollView.
 
Upvote 0
Top