B4A Library [Lib] UltimateListView

I've been working on this project for a long time and I'm very proud to release the version 4 today.

The UltimateListView is, as its pompous name says, THE ListView.

  • It can handle very long lists. This is a screenshot of a list with 245813 items, all different:

    verylonglist.jpg


  • It can mix different layouts (and they can be changed dynamically). You can use it as an expandable ListView:

    layouts.jpg


  • It has a low memory footprint and is very fast (this report comes from the Performance demo where the list has to display 128901 distinct words read from a database and the used device is a Huawei Honor single core 1.4 Ghz):

    performance.png


  • It can scroll in both directions thanks to its swipe detector:

    tables.jpg


  • The swipe detector can also be used to implement a swipe-to-dismiss or a swipe-to-reveal:

    swipedetector.png
  • You can easily add editors to your table to change its content:

    celledit.jpg


  • You can animate the items when they are added, removed, replaced or when the list is scrolled (with your own custom animation):

    animationclap.png


  • It can stack items from the bottom:

    stackfrombottom.png


  • It supports drag & drop operations (internal & external):

    dragndrop.png


  • You can synchronize lists with different item heights:

    grid.jpg
The examples will show you how to implement a Pull-to-Refresh, create sticky headers or combine several lists to make a wheel. One of the examples is an improved version of my File Explorer class.

All texts and images can be loaded asynchronously (from Internet, from a database or from a local folder), so you can scroll even if the data are not fully loaded.

The list has its own state manager.

Since September 2018, ULV is available for free. You can still donate for it if you wish.
To send the money, just click on the Donate button below (the amount to enter is in euros):


Note that UltimateListView is not a wrapper around the work of someone else. It is 100% my own code and it is based upon the standard Java ListView of Android.

The UltimateListView does not work with Android versions < 2. It cannot work with B4J or B4i.

Current version: 4.50

DOWNLOAD HERE:
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
Another solution is to change the behavior of ItemClick. Currently the selection is changed first, so the items are updated before you get ClickedPanel. I could raise the event first, and make the selection after. In this case, ClickedPanel wouldn't reflect the current selected state of the panel. That may lead to side effects in your apps and I'm not very fond of this solution.
 

fredo

Well-Known Member
Licensed User
Longtime User
... and I'm not very fond of this solution.

I fully understand the need for changes since the products we rollout need to help our customers to fulfill their tasks.

"The only reliable constant is change" follows IT
specialists since Konrad Zuse decided to build the Z3.

For new projects I might use cached maps to carry ItemContents when unavoidable.

Will it be possible to use the "old" ULV library for existing projects and the "new" library for future projects?
 

johndb

Active Member
Licensed User
Longtime User
I fully understand the need for changes since the products we rollout need to help our customers to fulfill their tasks.

"The only reliable constant is change" follows IT
specialists since Konrad Zuse decided to build the Z3.

For new projects I might use cached maps to carry ItemContents when unavoidable.

Will it be possible to use the "old" ULV library for existing projects and the "new" library for future projects?
I have a fair bit of time invested in my current projects which uses the UltimateListView, so I agree with @fredo 's request to allow both instances (say 4.20) and new versions, with the understanding that the older version is unsupported. :)
 

johndb

Active Member
Licensed User
Longtime User
I see no reason to use this old version. Nothing changed for Android 4 to 6 in v4.21. And the v4.3 changes only the divider color if you use one the styles concerned.
I disagree. Version 4.21 is when view references within the UltimateListView selection panel are lost (no longer exist) upon refresh. I had to revert back to 4.20 is maintain the reference. It would be best if I send you a small project showing what I mean and then we can pursue this further. Don't get me wrong, UltimateListView is THE library I use most often for all sorts of uses. :)

[EDIT] I refactored some of the code dealing with how I am handling view references within the UltimateListView panel and all appears to work correctly. Updated to ULV 4.4 Beta and all is good. Suggest that we keep the clickedpanel argument passed as I also use the panel reference to change the colour of the panel.
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
I disagree. Version 4.21 is when view references within the UltimateListView selection panel are lost (no longer exist) upon refresh. I had to revert back to 4.20 is maintain the reference. It would be best if I send you a small project showing what I mean and then we can pursue this further. Don't get me wrong, UltimateListView is THE library I use most often for all sorts of uses. :)
??? I don't understand what you mean. I wait for your example.
 

GuyBooth

Active Member
Licensed User
Longtime User
I also make heavy use of ClickedPanel, and it is working under Android 7 - because my SelectionMode is always set to SELECTION_NONE.
I would hate to have to deal with a change to ULV for a setting that I don't use. Is there some way to set it up so that the use of ClickedPanel is only disabled when SelectionMode is set to SELECTION_SINGLE (even though this introduces an inconsistency).

Note that you can get the clicked panel with this code:
B4X:
Sub getClickedPanel(Position As Int) As Panel
   Dim JO As JavaObject = ULV
   Return JO.RunMethod("getChildAt", Array(Position))
End Sub
Sub ULV_ItemClick(ItemID As Long, Position As Int, ClickedPanel As Panel)
   Dim MyLabel As Label = getClickedPanel(Position).GetView(0)
...
EDIT: I found at least one case where the code above is not reliable.
If it became absolutely essential, I think (without having tested it) that I could use this code - but now it does need to be reliable.
What makes it unreliable?
 

Informatix

Expert
Licensed User
Longtime User
I also make heavy use of ClickedPanel, and it is working under Android 7 - because my SelectionMode is always set to SELECTION_NONE.
I would hate to have to deal with a change to ULV for a setting that I don't use. Is there some way to set it up so that the use of ClickedPanel is only disabled when SelectionMode is set to SELECTION_SINGLE (even though this introduces an inconsistency).


If it became absolutely essential, I think (without having tested it) that I could use this code - but now it does need to be reliable.
What makes it unreliable?
There are two reasons to remove the parameter:
1) It should not exist as accessing the views to get the data is something I strongly advise against (frankly, I have no idea why I added this parameter);
2) I cannot let a parameter that works under Android 6 and not under Android 7. When Android 7 will be the most used Android version, I will receive a lot of complaints asking why that parameter does not work (I could put a warning in the User's Guide but most of donors don't read this pdf).

My decision is still pending. There's a beta version 4.4 currently available for download that fixes two bugs (LoadImageAsync and Cache). The parameter is still there in this beta version.
 

cimperia

Active Member
Licensed User
Longtime User
I'd rather you left the parameter in as I use it, not to retrieve views but change its color and different other non view/data related elements.

If I am not mistaken, some of the ULV sample code uses it to change the panel color during drag operations.

B4X:
Sub ULVTarget_ItemLongClick(ItemID As Long, Position As Int, ClickedPanel As Panel)
    'Changes the background color of the dragged item (cf. Item_ContentFiller)
    DraggedID = ItemID

    'Changes the background color of the overlay
    ClickedPanel.Color = Colors.ARGB(220, 51, 181, 229)
...
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
I'd rather you left the parameter in as I use it, not to retrieve views but change its color and different other non view/data related elements.

If I am not mistaken, some of the ULV sample code uses it to change the panel color during operations.

B4X:
Sub ULVTarget_ItemLongClick(ItemID As Long, Position As Int, ClickedPanel As Panel)
    'Changes the background color of the dragged item (cf. Item_ContentFiller)
    DraggedID = ItemID

    'Changes the background color of the overlay
    ClickedPanel.Color = Colors.ARGB(220, 51, 181, 229)
...
This is a more convincing point. Changing the color implies to manage a variable and call RefreshContent to adjust the item color according to this variable while the list was just refreshed by the selection code. A bit cumbersome, I agree.
Maybe I could raise a RuntimeException when this parameter is used under Android 7 with an explicit message for the exception ("This parameter does not work under Android 7 when SelectionMode is set"). Not clean, but it's probably an acceptable solution for most of you.
 

GuyBooth

Active Member
Licensed User
Longtime User
This is a more convincing point. Changing the color implies to manage a variable and call RefreshContent to adjust the item color according to this variable while the list was just refreshed by the selection code. A bit cumbersome, I agree.
Maybe I could raise a RuntimeException when this parameter is used under Android 7 with an explicit message for the exception ("This parameter does not work under Android 7 when SelectionMode is set"). Not clean, but it's probably an acceptable solution for most of you.
That would certainly work for me ...
 

ilan

Expert
Licensed User
Longtime User
hi

i know that support is provided by email but i have a really stupid question :D

i add few views to each ulv item and if i click on a button inside the ulv item i want to get another button.
i could not find any method to get all views from an ulv item so i am doing it like this:

B4X:
Sub CldBtn_Click
    Dim btn As Button = Sender
    Dim colorpicker As ColorPickerDialog
    If colorpicker.Show("לבחור צבע","אישור","ביטול","",Null) = DialogResponse.POSITIVE Then
        Dim background As ColorDrawable
        background.Initialize2(colorpicker.ARGB(255),1,0,Colors.White)
        Dim pnl As Panel = btn.Parent
        Dim btn As Button = pnl.GetView(7)
        btn.Background = background
    End If
End Sub

what i do is i am getting the parent of the button that was clicked and then i am getting from that panel the view (button) in position 7
it works for me but is this the right way to do it?

thank you
 

Informatix

Expert
Licensed User
Longtime User
I really want emails. The answers that I give in the forum are very difficult to retrieve when I need them and I prefer to dedicate this thread to something else.

For your question, the answer is: No, it's not the best way, but if that works under all Android versions, then it's fine. Instead, I recommend to store a reference to the other button in the Tag property of your clicked button.
 

ilan

Expert
Licensed User
Longtime User
I really want emails. The answers that I give in the forum are very difficult to retrieve when I need them and I prefer to dedicate this thread to something else.

sorry, i will do it via mail next time.

Instead, I recommend to store a reference to the other button in the Tag property of your clicked button.

ok i understand but its a little bit weird to me that storing a reference of the button to the tag property of an other button is the right way to do it with ULV. i thought the right way would be .GetChildrenIDs but maybe i understood it wrong. anyway maybe you could add a simple way to do it in a future update of ULV.

something like:

B4X:
Dim l As List
l = myULV.getALLviewsFromParentof(btn)

thank you:)
 

Informatix

Expert
Licensed User
Longtime User
Great news! After hours spent in reading the Google's code, I understood what changed in API 19 and why I had various issues with Android 7 (API 24) where these changes are really used (recycled views can be detached from their window very quickly so they can be in this detached state when ULV tries to reuse them). I fixed all problems (I hope) with a single line of code and thus I was able to re-enable the recycling of items and the Cleaner event for Android 7.

v4.4:
- I fixed all issues with Android 7 and thus I re-enabled the recycling of items;
- I fixed the problem of images that were partially downloaded with LoadImageAsync;
- I fixed a bug in the Cache library.
 

cimperia

Active Member
Licensed User
Longtime User
Thank you for working so hard on this, Informatix.
 

MarcoRome

Expert
Licensed User
Longtime User
Great news! After hours spent in reading the Google's code, I understood what changed in API 19 and why I had various issues with Android 7 (API 24) where these changes are really used (recycled views can be detached from their window very quickly so they can be in this detached state when ULV tries to reuse them). I fixed all problems (I hope) with a single line of code and thus I was able to re-enable the recycling of items and the Cleaner event for Android 7.

v4.4:
- I fixed all issues with Android 7 and thus I re-enabled the recycling of items;
- I fixed the problem of images that were partially downloaded with LoadImageAsync;
- I fixed a bug in the Cache library.
Great work Fred
 
Top