Android Question Help needed. DrawPath object on canvas is covered by Label view

fredo

Well-Known Member
Licensed User
Longtime User
To create a moveable BubbleView, @Brandsum 's inspiration made a promising test project possible.

The solution is far from optimal, but almost fulfills its purpose (2), since the pointer follows the view movements (3).

B4X:
' -------------------------------------
' Class draggablebubble
' -------------------------------------

'
' Inspired by Erel --> https://www.b4x.com/android/forum/threads/classes-are-soon-coming.18395/
'
'***************************
' Usage example
'***************************
'Sub Activity_Create(FirstTime As Boolean)
'   Activity.LoadLayout("1")
'   Dim dv1 As draggableview
'   dv1.Initialize(MainBackPanel, Label1, Label0, 0xff06AF8F)
'End Sub
'***************************


Sub Class_Globals
    Private innerView As B4XView
    Private TouchPanelOverBubble As Panel
    Private downx As Int
    Private downy As Int
    Private ACTION_DOWN, ACTION_MOVE, ACTION_UP As Int
    
    Private cvs As B4XCanvas
    Private av As B4XView
    Private panX As Panel
    Private bcolor As Int
    Private shadowwidth As Int = 2dip
End Sub

Sub Initialize(ParentPanel As Panel, ViewToBlubble As B4XView, AnchorView As View, BackColor As Int)
    panX = ParentPanel
    av = AnchorView
    bcolor = BackColor
    cvs.Initialize(panX)
    
    innerView = ViewToBlubble
    TouchPanelOverBubble.Initialize("")
    TouchPanelOverBubble.Color = Colors.Transparent
    ViewToBlubble.SetColorAndBorder(bcolor, 0, 0, 5dip)

    panX.AddView(TouchPanelOverBubble, ViewToBlubble.Left, ViewToBlubble.Top, ViewToBlubble.Width, ViewToBlubble.Height)

    ACTION_DOWN = panX.ACTION_DOWN
    ACTION_MOVE = panX.ACTION_MOVE
    ACTION_UP = panX.ACTION_UP
  
    Dim r As Reflector
    r.Target = TouchPanelOverBubble
    r.SetOnTouchListener("Panel1_Touch") 'why reflection instead of the regular Panel_Touch event? Good question which deserves a forum thread of its own (not related to classes)...
    BubbleMoved
    
End Sub

Private Sub Panel1_Touch (o As Object, ACTION As Int, x As Float, y As Float, motion As Object) As Boolean
    If ACTION = ACTION_DOWN Then
        downx = x
        downy = y
    Else
        innerView.Left = innerView.Left + x - downx
        innerView.Top = innerView.Top + y - downy
        TouchPanelOverBubble.Left = innerView.Left
        TouchPanelOverBubble.Top = innerView.Top
        BubbleMoved
    End If
    Return True
End Sub

private Sub BubbleMoved
    cvs.ClearRect(cvs.TargetRect)
    
    ' --- Draw shadow for inner view
    Dim l,t,r,b As Float
    l = innerView.Left
    t = innerView.Top +shadowwidth
    r = innerView.Left + innerView.Width
    b = innerView.Top + innerView.Height +shadowwidth
    Dim ivrec As B4XRect
    ivrec.Initialize(l,t,r,b)
    Dim path As B4XPath
    path.InitializeRoundedRect(ivrec, 5dip)
    cvs.ClipPath(path)
    cvs.DrawRect(cvs.TargetRect,  Colors.ARGB(3* 24, 160, 160, 160) , True, shadowwidth)
    cvs.RemoveClip
    
    ' --- Draw shadow for pointer
    For i = 0 To 3
        Dim bpa As B4XPath
        bpa.Initialize(innerView.Left +(innerView.Width/2), innerView.Top +(innerView.Height /2))
        bpa.LineTo( av.Left +(av.Height /2), av.Top + (av.Height /2) )
        bpa.LineTo( innerView.Left +(innerView.Width/2), innerView.Top +(innerView.Height /2) +24dip + i*shadowwidth)
        cvs.DrawPath(bpa, Colors.ARGB(i*24, 160, 160, 160), True, 0)
    Next
    
    ' --- Draw pointer
    Dim bpa As B4XPath
    bpa.Initialize(innerView.Left +(innerView.Width/2), innerView.Top +(innerView.Height /2))
    bpa.LineTo( av.Left +(av.Height /2), av.Top + (av.Height /2))
    bpa.LineTo( innerView.Left +(innerView.Width/2), innerView.Top +(innerView.Height /2) +24dip)
    cvs.DrawPath(bpa, bcolor, True, 0)
    
    panX.Invalidate ' Is this needed?
    
End Sub




' -----------------------------
' Main activity
' -----------------------------
 #Region  Project Attributes
    #ApplicationLabel: B4A Example
    #VersionCode: 3
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    Private su As StringUtils
End Sub

Sub Globals
    Private MainBackPanel As B4XView
    Private Label0 As B4XView
    Private Label1 As B4XView
    Private Label2 As B4XView
    Private Label3 As B4XView
    Private dv1 As draggablebubble
    
    Private BubbleAnkerView As String = ""
End Sub

Sub Activity_Create(FirstTime As Boolean)
    
    Activity.LoadLayout("Layout1")
    Activity.Color = Colors.White
    Label0.SetColorAndBorder(0xff425CFB, 0, 0, Label0.Width / 2)
    
    Label1.Text = "Drag me around. Lorem ipsum dolor sit amet, consectetuer adipiscing elit."
    Label1.Width = 200dip
    Label1.Height = su.MeasureMultilineTextHeight(Label1, Label1.Text)
    Label2.Text = "..."
    
    BubbleAnkerView = "Label0"
    dv1.Initialize(MainBackPanel, Label1, Label0, 0xff06AF8F)
    
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

Sub Label3_Click

    If BubbleAnkerView = "Label0" Then
        Label1.Text = "Go ahead - drag again. Aenean commodo ligula eget dolor. Aenean massa."
        dv1.Initialize(MainBackPanel, Label1, Label3, 0xff06AF8F)
        BubbleAnkerView = "Label3"
    Else
        Label1.Text = "And the drag goes on. Lorem ipsum dolor sit amet, consectetuer adipiscing elit."
        dv1.Initialize(MainBackPanel, Label1, Label0, 0xffFC4242)
        BubbleAnkerView = "Label0"
    End If
    Label2.Text = "BubbleAnkerView = " & BubbleAnkerView


End Sub

2019-11-16_15-31-52.jpg


Unfortunately the canvas-drawn "pointer triangle" is covered (4) by other views on the parent panel (SendToBack didn't help).
As there is no experience how to work with canvas so far, a push in the right direction is needed.

 

Attachments

  • DraggableBubble3.zip
    11 KB · Views: 129
Top