I have tried to modify Erel's Java class from this thread https://www.b4x.com/android/forum/threads/class-clvdragger-drag-to-reorder-items.104261/ for B4A
I have changed mouse events to touch events. The rest of the code is the same as in Erel's code.
The class code is as follows:
But I have a following error after moving the item:
Probably Erel would be the best person to answer this question but answer from anyone else is welcome.
The test project is attached
I have changed mouse events to touch events. The rest of the code is the same as in Erel's code.
The class code is as follows:
B4X:
'v1.00
Sub Class_Globals
Private xui As XUI
' Private fx As JFX
Private list As CustomListView
Private PressedColor As Int
Private Top As Int
Dim pnl As B4XView
Dim ListStartY As Int
End Sub
Public Sub Initialize (clv As CustomListView)
list = clv
PressedColor = list.PressedColor
End Sub
Public Sub Resize
For i = 0 To list.Size - 1
Dim p As B4XView = list.GetPanel(i)
Dim v As B4XView = p.GetView(p.NumberOfViews - 1)
If v Is Label And v.Tag = list Then
v.Left = p.Width - 32dip
End If
Next
End Sub
Public Sub RemoveDragButtons
For i = 0 To list.Size - 1
Dim p As B4XView = list.GetPanel(i)
Dim b As Boolean = IsLastViewADragLabel(p)
'Log(" b " & b)
If b Then 'IsLastViewADragLabel(p) Then
p.GetView(p.NumberOfViews - 1).RemoveViewFromParent
End If
Next
list.PressedColor = PressedColor
End Sub
Private Sub IsLastViewADragLabel (p As B4XView) As Boolean
'Log("no of views " & p.NumberOfViews )
If p.NumberOfViews > 0 Then
Dim v As B4XView = p.GetView(p.NumberOfViews - 1)
Dim b As Boolean
b = v Is Label
' Log("no of views " & p.NumberOfViews & " label " & b & " " & v.Tag)
If v.IsInitialized = False Then
Return False
End If
If v.Tag = Null Then
Return False
End If
Return v Is Label And v.Tag = list
End If
Return False
End Sub
Public Sub AddDragButtons
list.PressedColor = xui.Color_Transparent
Dim fnt As B4XFont = xui.CreateMaterialIcons(30)
For i = 0 To list.Size - 1
Dim p As B4XView = list.GetPanel(i)
If IsLastViewADragLabel(p) = False Then
Dim lbl As Label
lbl.Initialize("") 'Drag")
' lbl.MouseCursor = fx.Cursors.HAND
Dim xlbl As B4XView = lbl
xlbl.Font = fnt
xlbl.Text = Chr(0xE25D)
xlbl.TextColor = list.DefaultTextColor
xlbl.Tag = list
p.AddView(xlbl, p.Width - 32dip, p.Height / 2 - 15dip, 30dip, 30dip)
Dim r As Reflector
r.Target = lbl 'DragAndDrop
r.SetOnTouchListener("Drag_Touch")
End If
Next
End Sub
Sub Drag_Touch(ViewTag As Object, Action As Int, X As Float, Y As Float, EventData As Object) As Boolean
Dim lbl As B4XView = Sender
Dim list As CustomListView = lbl.Tag
If Action = 0 Then 'ACTION_DOWN
Log("action down " & Y)
Dim r As Reflector
r.Target = list.sv
r.RunMethod2("requestDisallowInterceptTouchEvent", True, "java.lang.boolean")
pnl = list.GetPanel(list.GetItemFromView(lbl)).Parent
pnl.GetView(0).SetColorAndBorder(xui.Color_Transparent, 3dip, 0xFF503ACD, 0)
ListStartY = Y + lbl.Top + pnl.Top
pnl.BringToFront
Top = pnl.Top
Else If Action = 1 Then 'ACTION_UP
Dim index As Int = list.GetItemFromView(lbl)
pnl = list.GetPanel(index).Parent
Dim Offset As Int = pnl.Top + pnl.Height / 2
Dim NewIndex As Int = list.FindIndexFromOffset(Offset)
Dim UnderlyingItem As CLVItem = list.GetRawListItem(NewIndex)
If Offset - UnderlyingItem.Offset > UnderlyingItem.Size / 2 Then
NewIndex = NewIndex + 1
End If
Dim ActualItem As B4XView = pnl.GetView(0)
ActualItem.SetColorAndBorder(pnl.Color, 0dip, xui.Color_Black, 0)
Dim RawItem As CLVItem = list.GetRawListItem(index)
list.RemoveAt(index)
If NewIndex > index Then
NewIndex = NewIndex - 1
End If
NewIndex = Max(0, Min(list.Size, NewIndex))
list.InsertAt(NewIndex, ActualItem, RawItem.Value)
list.GetRawListItem(NewIndex).TextItem = RawItem.TextItem
Else If Action = 2 Then 'ACTION_MOVE
Dim index As Int = list.GetItemFromView(lbl)
If pnl.Top < list.sv.ScrollViewOffsetY Then
list.sv.ScrollViewOffsetY = Max(0, list.sv.ScrollViewOffsetY - 10dip)
Else If list.sv.ScrollViewOffsetY + list.sv.Height < pnl.Top + pnl.Height Then
list.sv.ScrollViewOffsetY = list.sv.ScrollViewOffsetY + 10dip
End If
Dim ListY As Int = Y + lbl.Top + pnl.Top
Dim delta As Int = ListY - ListStartY
pnl.Top = Top + delta
Else
Log("action " & Action)
End If
Return True
End Sub
But I have a following error after moving the item:
B4X:
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
.customlistview_insertatimpl (B4A line: 113)
list.InsertAt(NewIndex, ActualItem, RawItem.Valu
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:5958)
at android.view.ViewGroup.addView(ViewGroup.java:5777)
at android.view.ViewGroup.addView(ViewGroup.java:5749)
at anywheresoftware.b4a.objects.PanelWrapper.AddView(PanelWrapper.java:65)
at anywheresoftware.b4a.objects.B4XViewWrapper.AddView(B4XViewWrapper.java:323)
at b4a.example3.customlistview._insertatimpl(customlistview.java:567)
at b4a.example3.customlistview._insertat(customlistview.java:540)
at b4a.example.clvdragger._drag_touch(clvdragger.java:270)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:213)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
at anywheresoftware.b4a.agraham.reflection.Reflection$7.onTouch(Reflection.java:1118)
at android.view.View.dispatchTouchEvent(View.java:14371)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3863)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3551)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3863)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3551)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3863)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3551)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3863)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3551)
Probably Erel would be the best person to answer this question but answer from anyone else is welcome.
The test project is attached