[Q]Sortable listview

KZero

Active Member
Licensed User
Longtime User
Hi,
is it possible to do "manually sortable listview" to drag and drop items up or down ?

thanks in advance
 

mc73

Well-Known Member
Licensed User
Longtime User
I don't know about listViews, but you can certainly do drag-and-drop in items of a scrollview.

If you insist on using a listview, you could place two buttons, one for moving an item up and one for moving it down. You should reconstruct the list accordingly.
 
Last edited:
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
thx mc
i can drag and drop views but i was looking for something smoother like this

Making a sortable ListView in Android | TechRepublic

I couldn't watch the video, it didn't open for me, but you can have a look at this code, perhaps it helps, though I couldn't make it too smooth. Furthermore, I'm sure there are good examples in this forum of smooth movement, though I didn't have time to search.
B4X:
'Activity module
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Dim ScrollView1 As ScrollView
    Dim Label1 As Label
    Dim Panel1 As Panel
    Dim tm As Timer 
    
    Dim curX, curY As Int 
    Dim flMove As Boolean 
    Dim whichLabel As Int 
    
    Dim tenLabels(10) As String 
End Sub

Sub Activity_Create(FirstTime As Boolean)
    ScrollView1.Initialize (Activity.Height)
    Dim tempPanel As Panel 
    tempPanel=ScrollView1.Panel 
    For i=0 To 9
        tenLabels(i)="item " & (i+1)
    Next
    setLabels
    Panel1.Initialize ("Panel1")
    Panel1.Visible =False
    Panel1.Color =Colors.Blue 
    Activity.AddView (ScrollView1,0,0,Activity.Width,Activity.Height )
    Activity.AddView (Panel1,0,0,Activity.Width,50dip)
    Label1.Initialize ("")
    Panel1.AddView (Label1,0,0,Panel1.Width,Panel1.Height )
    flMove=False
    tm.Initialize ("myTimer",200)
    tm.Enabled =True

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
Sub label_click
    Panel1.Visible =False
    Dim tempLabel As Label
    tempLabel=Sender
    whichLabel=tempLabel.Tag 
    Label1.Text=tempLabel.Text
    Panel1.Left=tempLabel.Left
    Panel1.Top =tempLabel.Top 
    Panel1.Visible =True
    Panel1.BringToFront 
    Panel1.RequestFocus 
End Sub


Sub Panel1_Touch (Action As Int, x As Float, Y As Float) As Boolean 'Return True to consume the event
    flmove=True
    curX=x:curY=Y
    Select Action
        Case Activity.ACTION_DOWN 
            flMove=True
            curX=x:curY=Y
        Case Activity.ACTION_MOVE 
            flMove=True
            curX=x:curY=Y
        Case Activity.ACTION_UP
            flMove=False
            Dim absX As Int, absY As Int 
            absX=x+Panel1.Left +Panel1.Width /2
            absY=Y+Panel1.Top +Panel1.Height /2
            Dim whichPos As Int 
            whichPos=absY/(ScrollView1.Height/10)
            If whichPos>9 Then whichPos=9
            If whichPos<0 Then whichPos=0
            If whichPos<>whichLabel Then
                'exchange Labels
                Dim templ,templ2 As String 
                templ=tenLabels(whichPos)
                templ2=tenLabels(whichLabel)
                tenLabels(whichPos)=templ2
                tenLabels(whichLabel)=templ
                For k=0 To ScrollView1.Panel.NumberOfViews -1
                    ScrollView1.Panel.RemoveViewAt (0)    
                Next
                setLabels
                Msgbox("Exchanged " & templ & " with " & templ2,"Drag & Drop finished") 
            End If
            Panel1.Visible =False
    End Select
    Return True
End Sub

Sub myTimer_tick
    If flMove=True Then
        'Panel1.Left =curX+Panel1.Left-Panel1.Width/2 
        Panel1.Top =curY+Panel1.Top -Panel1.Height/2
    End If
End Sub

Sub setLabels
    Dim tempPanel As Panel 
    tempPanel=ScrollView1.Panel 
    For i=0 To 9
        Dim tempLabel As Label 
        tempLabel.Initialize ("label")
        tempLabel.Tag =i
        tempLabel.Text=tenLabels(i)
        tempPanel.AddView (tempLabel,0,i*50dip,tempPanel.Width,tempPanel.Height /10)
    Next
End Sub
 
Upvote 0

KZero

Active Member
Licensed User
Longtime User
thx m8
nice code but i'm already working in one more advanced will post it here when i finish it
thx for ur help:)
 
Upvote 0

KZero

Active Member
Licensed User
Longtime User
i just finished it
the code attached

the code may need some modifications if anyone gonna use in his project
like putting it into scroll view or adding items programmatically
 

Attachments

  • sortablelist.zip
    11.8 KB · Views: 272
  • sort.png
    sort.png
    44.5 KB · Views: 343
Last edited:
Upvote 0

Informatix

Expert
Licensed User
Longtime User
i just finished it
the code attached

the code may need some modifications if anyone gonna use in his project
like putting it into scroll view or adding items programmatically

I don't want to be demoralizing but you've done the easiest part of the job. If you put these panels in a ScrollView and add EditText on these panels, you'll quickly see what I mean. That's a mess because there are three touch event listeners and three coordinate spaces: Scrollview (inside the activity), Panel (inside the ScrollView), EditText (inside the panel). Moreover, ScrollView intercepts some touch events.
For each touch event, you have to convert X and Y to the same coordinate space and send the result to only one function which does the move.
 
Upvote 0

KZero

Active Member
Licensed User
Longtime User
I don't want to be demoralizing but you've done the easiest part of the job. If you put these panels in a ScrollView and add EditText on these panels, you'll quickly see what I mean. That's a mess because there are three touch event listeners and three coordinate spaces: Scrollview (inside the activity), Panel (inside the ScrollView), EditText (inside the panel). Moreover, ScrollView intercepts some touch events.
For each touch event, you have to convert X and Y to the same coordinate space and send the result to only one function which does the move.

yes you completely right, but i did this part of code to use in my project (not tool for public use) and i put my needs only (about 5 sortable checkboxes in non scrolled panel)
anyone will put it in scrollview will this face problem but i don't have idea to fix it
tell me if u know :sign0085:
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
I found a new way of moving a panel inside a ScrollView. You can see it in action in my CheckList class.
The idea is pretty simple: I transform the panel to move into a bitmap and I move the bitmap after forbidding the Scrollview to intercept touch events. This way, I have only one coordinate space to manage and I'm not bothered by the touch events triggered by the views inside the panel to move.
 
Upvote 0

KZero

Active Member
Licensed User
Longtime User
I found a new way of moving a panel inside a ScrollView. You can see it in action in my CheckList class.
The idea is pretty simple: I transform the panel to move into a bitmap and I move the bitmap after forbidding the Scrollview to intercept touch events. This way, I have only one coordinate space to manage and I'm not bothered by the touch events triggered by the views inside the panel to move.

:sign0098:
 
Upvote 0
Top