Android Code Snippet [B4X] Get absolute top value of a View

B4X:
Private Sub GetAbsViewTop(xView As B4XView) As Int
    Dim Top As Int = xView.top
    Dim Parent As B4XView = xView.Parent
    Do While Parent.IsInitialized = True
        If GetType(Parent).EndsWith("b4a.BALayout") Then
            Try
                Top = Top + Parent.Top
                Parent = Parent.Parent
            Catch
                Exit
                Log(LastException)
            End Try
        Else
            Exit
        End If
    Loop
    Return Top
End Sub

Tested very little. Also, maybe someone has already published a snippet like this.

EDIT: read post #12
 
Last edited:

Alexander Stolte

Expert
Licensed User
Longtime User
Also, maybe someone has already published a snippet like this.
Code from my ASPopupMenu:
B4X:
Sub ViewScreenPosition (view As B4XView) As Int()
    
    Dim leftTop(2) As Int
    #IF B4A
    Dim JO As JavaObject = view
    JO.RunMethod("getLocationOnScreen", Array As Object(leftTop))
    leftTop(1) = leftTop(1) - view.Height
    #Else If B4I
    'https://www.b4x.com/android/forum/threads/absolute-position-of-view.56821/#content
    Dim parent As B4XView = view
    Do While GetType(parent) <> "B4IMainView"
        Dim no As NativeObject = parent
        leftTop(0) = leftTop(0) + parent.Left
        leftTop(1) = leftTop(1) + parent.Top
        parent = no.GetField("superview")
   Loop
    #Else
    Dim parent As B4XView = view
   Do While parent.IsInitialized
       leftTop(0) = leftTop(0) + parent.Left
       leftTop(1) = leftTop(1) + parent.Top
       parent = parent.Parent
   Loop
    #End If

    Return Array As Int(leftTop(0), leftTop(1))
End Sub
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
Code from my ASPopupMenu:
It seems that the B4A version does not work well.

I attach a project; I slightly modified your function to get only the Top value (I could have done otherwise) and changed its name, but I did not touch the code.

In the project, the click on the button should align two labels at the same top of two B4XFloatTextFields but the values are very different.
 

Attachments

  • GetAbsTop.zip
    19.2 KB · Views: 14

Alexander Stolte

Expert
Licensed User
Longtime User
It seems that the B4A version does not work well.
But it works. Only instead of the top value, the function returns the bottom value. You have to do the following:
B4X:
Private Sub Button1_Click
    Label1.Top = GetAbsTop(B4XFloatTextField2.mBase) - B4XFloatTextField2.mBase.Height
    Label2.Top = GetAbsTop(B4XFloatTextField3.mBase) - B4XFloatTextField3.mBase.Height
End Sub
 

LucaMs

Expert
Licensed User
Longtime User
:oops: :oops: :oops:

1731458653696.png



Asked ChatGPT:

1731459032865.png
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
However, despite the official documentation and ChatGPT's answer, it seems to be exactly as you wrote, Alexander, that in the case of B4A the function returns the Bottom, not the Top.

In order for the function not to be "inconsistent", you should add a line:
B4X:
    #IF B4A
        Dim JO As JavaObject = view
        JO.RunMethod("getLocationOnScreen", Array As Object(LeftTop))
        LeftTop(1) = LeftTop(1) - view.Height ' <------
    #Else If B4I
 
Top