Android Code Snippet show tooltip for view

Discussion in 'Code Snippets' started by Dave O, Jul 5, 2016.

  1. Dave O

    Dave O Active Member Licensed User

    The standard Android UI includes a way to show tooltips for controls by long-clicking them (press and hold). This creates a toast-like message near the control. So, for an Edit icon (the pencil), you can long-click and it will show a tooltip of "Edit".

    This is not directly supported in B4A (there's no hintText property), so I wrote some code to do it. Not enough for a class (just 4 subs), so here it is:

    To add a tooltip to a view, it's a single line of code in the view's LongClick event listener:
    Code:
    Sub cancelButton_LongClick
       showTooltip(
    Sender"Cancel")
    End Sub
    And here's the code that does the (not very) heavy lifting.
    Code:
    'shows a toast message just above the view (or below if there's no room above)
    Sub showTooltip(viewArg As View, text As String)
        
    Dim const verticalOffset As Int = 60dip
        
    Dim position(2As Int
        position = getScreenPosition(viewArg)
        
    Dim toastTop As Int = position(1) - verticalOffset        'normally show hint above the view
        If toastTop < 0 Then                                              'no room at top, so move toast below the view
            toastTop = position(1) + verticalOffset
        
    End If
        showToastAt(position(
    0), toastTop, text, False)
    End Sub

    'Show standard toast at given x/y position relative to activity.
    'Toast will always appear within the screen boundaries, even if x or y is off-screen.
    Sub showToastAt(x As Int, y As Int, text As String, longDuration As Boolean)
        
    Dim duration As Int
        
    If longDuration = True Then
            duration = 
    1
        
    Else
            duration = 
    0
        
    End If
        
    Dim r As Reflector
        r.Target = r.GetActivity
        
    Dim toastJO As JavaObject
        toastJO.InitializeStatic(
    "android.widget.Toast")
        
    Dim toastJO2 As JavaObject
        toastJO2 = toastJO.RunMethod(
    "makeText"Array As Object(r.GetContext, text, duration))
        toastJO2.RunMethod(
    "setGravity"Array As Object (Bit.Or(Gravity.TOP, Gravity.LEFT), x, y))
        toastJO2.RunMethod(
    "show"Null)
    End Sub

    'Calculate the position of the view relative to the activity (not to the view's parent).
    'Returns an integer array where index 0 is left, index 1 is top
    Sub getScreenPosition(viewArg As ViewAs Int()
        
    Dim position(2), parentPosition(2As Int
        
    If viewArg.parent Is ScrollView Then
            
    'the scrollview's panel has no layout, so ignore
            Dim sv As ScrollView = viewArg.Parent
            position(
    0) = sv.left
            position(
    1) = sv.Top - sv.ScrollPosition
            
    Return position
        
    else If viewArg.parent Is AHViewPager Then        'you can comment out this part if you don't use AHViewPager
            'the pager's container has no layout, so ignore
            Dim pager As AHViewPager = viewArg.Parent
            position(
    0) = pager.left
            position(
    1) = pager.Top
            
    Return position
        
    else if viewArg.parent = getCurrentActivity Then
            position(
    0) = viewArg.Left
            position(
    1) = viewArg.Top
            
    Return position
        
    Else
            parentPosition = getScreenPosition(viewArg.parent)
            position(
    0) = viewArg.Left + parentPosition(0)
            position(
    1) = viewArg.top + parentPosition(1)
            
    Return position
        
    End If
    End Sub

    Sub getCurrentActivity As Activity
        
    Dim r As Reflector
        r.Target = r.GetActivityBA
        
    Return r.GetField("vg")   
    End Sub
    Notes:
    - I recommend putting this into a code module so you can use it in all of your app's activities.
    - Requires the Reflector and JavaObject libraries.
    - The standard Android tooltip shows below the control, but fingers get in the way, so I changed it to appear above the control where possible.

    Feel free to use and modify this code as you wish. Please post any fixes or improvements in this thread.

    Thanks to those who helped me with this in the forums. Cheers!
     
    johndb and Erel like this.
  2. Erel

    Erel Administrator Staff Member Licensed User

    There is no such feature in Android.
     
  3. Dave O

    Dave O Active Member Licensed User

    Sorry, I didn't mean that there is a hintText property in Android that B4A is missing (poor wording on my part).

    I meant that there is a common UI pattern in Android (tooltips), used in many popular apps (including Google's own apps), that is not easy to do in B4A if you're an intermediate coder like me. (I don't know how easy/hard it is to implement in Android Java either.)

    I'd love to see standard UI patterns like this made easier to implement, especially in a RAD tool like B4A.

    Cheers!
     
    Erel likes this.
Loading...