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
When scrolling down a list of items, I tick my checkbox I've added and that fires an event in my db to save something.. If I scroll own far enough that particular checkbox moves off screen. When I scroll back the tick is now gone from the checkbox. I understand from a search that I cannot update the cursor that I am using which the list is feeding off but would like the ticks to show when the items comes back to be viewed.. can you suggest the best way for this. I guess an array of clicked items may be the way to go but would like your opinion on it as I am sure I'm not the first to ask (I hope)..

Either you read the information directly from your (local) database (you have to get a new cursor after your SQL Update; look at my Editor demo) or you store the information in a map (key=id, value=checked state) and retrieve it from this map (if the key is not found or value=false then the box is not checked). If your checkbox is used to select items, you can use the internal selection list. Call SetSelected() when the checkbox is clicked and use IsSelected to reflect the proper state in the Filler sub (don't forget to specify a selection mode, e.g. ULV.SelectionMode=ULV.SELECTION_MULTIPLE).
 

Derek Jee

Active Member
Licensed User
Longtime User
Thank you so much.. I did see your 'editor' code and that you update the sql db each time a value has been updated. Do you have issues with the list position after the update or do I have to worry about that? I would really prefer to do this but the map suggestion is also a good one..

Thank you..

Derek.
 

Informatix

Expert
Licensed User
Longtime User
Thank you so much.. I did see your 'editor' code and that you update the sql db each time a value has been updated. Do you have issues with the list position after the update or do I have to worry about that? I would really prefer to do this but the map suggestion is also a good one..

Thank you..

Derek.
The SQlite engine is very fast so you can update a data and read it just after without lag issue most of the time. That depends of course on the data to update, on the table structure, on the number of records in the table, on the number of records fetched in your code, etc. In my performance demo, I prefer to limit the cursor to one record because of the number of records in the table. And as you can see, you can scroll without issue while a record is retrieved for every single item.
 

Derek Jee

Active Member
Licensed User
Longtime User
So I update my db, refresh the cursor but the ULV knows the rowids from the activity_create and fetches them from the updated cursor when scrolling.. magic.. I am very encouraged. Thank you again..

Derek.
 

Rusty

Well-Known Member
Licensed User
Longtime User
I purchased your lib last week and it is working well :)
Is there a method by which one can iterate through the currently displayed items within the list?
i.e. 100 items in a list, 5 are being displayed on the screen, I'd like to find out which 5 are currently in the display.
Thanks,
Rusty
 

Rusty

Well-Known Member
Licensed User
Longtime User
Thanks,
I already discovered these, but how do I retrieve the "layout", layout contents etc.?
I envision:
B4X:
For i = getfirstvisibleposition to getlastvisibleposition
'Grab the data within the layout here...but HOW?
Next
Thanks
Rusty
 

Informatix

Expert
Licensed User
Longtime User
Thanks,
I already discovered these, but how do I retrieve the "layout", layout contents etc.?
I envision:
B4X:
For i = getfirstvisibleposition to getlastvisibleposition
'Grab the data within the layout here...but HOW?
Next
Thanks
Rusty
I discourage to do so because that leads to bad practices (and there's no way without the JavaObject library). Why do you need to access the views ?
 

Rusty

Well-Known Member
Licensed User
Longtime User
My appication plays a very short MP3 file (1 second each at max) as each item in the list is displayed (I hope).
Your suggestions are welcome.
Rusty
 

Informatix

Expert
Licensed User
Longtime User
My appication plays a very short MP3 file (1 second each at max) as each item in the list is displayed (I hope).
Your suggestions are welcome.
Rusty
o_O What's the expected result when you scroll the list?
I still don't understand why you need to access the views. It seems that you just need to know if a new item is visible to produce the sound, no? In this case, use the Scrolled event.
 

Rusty

Well-Known Member
Licensed User
Longtime User
I tried using the anim_Scrolled event, but unless there are more than can show on the screen, this event doesn't fire.
i.e. If there 4 items in the list and they all fit on the screen without scrolling, they won't fire the scrolled event.
If there are more than will fit, it does fire.
 

Informatix

Expert
Licensed User
Longtime User
I tried using the anim_Scrolled event, but unless there are more than can show on the screen, this event doesn't fire.
i.e. If there 4 items in the list and they all fit on the screen without scrolling, they won't fire the scrolled event.
If there are more than will fit, it does fire.
It's quite normal for a Scrolled event to not be raised when the list is not scrolled or has no reason to scroll. ;)
To be sure to produce a sound each time an item becomes visible, put your code in the Filler sub. Moreover you're able to access all views in this sub, but I suppose that you tried that first. So what did you not use this solution? Could you explain exactly what you're trying to do and the expected behavior in various cases because I burnt all my neurons trying to create a fast gaussian blur on Android these past days... Producing a sound for each item seems a bit weird in a list.
 
Last edited:

Rusty

Well-Known Member
Licensed User
Longtime User
Thanks for the update.
My application is for illiterate/low-literacy people.
It displays multiple "lists" of information from which they select item(s).
In order for this to happen, each item has to "read" itself to the person.
As the item is reading itself (audibly), it needs to highlight/change its color so the illiterate person can tell which one is reading itself.
therefore, as the list is being displayed OR after it is displayed, each item needs to change color and run an .mp3 audio file.
I've moved my attempts all over the place to find access to the displayed items, but need some guidance.
Thanks :)
 

Informatix

Expert
Licensed User
Longtime User
What are exactly the cases when the item is read? I understood that there's the case when the item becomes visible. But I don't understand the other cases (when it is selected ? when it is clicked ? whenever the list is scrolled? but in this case what is the item to read among the scrolled items?).
 

Rusty

Well-Known Member
Licensed User
Longtime User
Good question.
Each item is read when it appears for the first time. if it is in a list of items, each item is "highlighted" (background image is changed) read individually and the the background image is restored after the audio has finished.
if the list extends beyond the visible page and the other items are scrolled up or down into view, the newly visible items are highlighted and read. This is done until an item is selected. (I have an asynchronous mp3 player with player complete events that allow me to know when the mp3 is finished)
When it is touched, it is read again and its background image is changed to show them which item was selected (this time the background image is left changed because the item is "selected")
Further, when the person has selected an item and they go back to that list of items the item they selected is remembered and that remembered item is read again to remind them of their selection. (remember they can't read)

BTW, AnimationEnd doesn't fire, can you advise?
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
Good question.
Each item is read when it appears for the first time. if it is in a list of items, each item is "highlighted" (background image is changed) read individually and the the background image is restored after the audio has finished.
if the list extends beyond the visible page and the other items are scrolled up or down into view, the newly visible items are highlighted and read. This is done until an item is selected. (I have an asynchronous mp3 player with player complete events that allow me to know when the mp3 is finished)
When it is touched, it is read again and its background image is changed to show them which item was selected (this time the background image is left changed because the item is "selected")
Further, when the person has selected an item and they go back to that list of items the item they selected is remembered and that remembered item is read again to remind them of their selection. (remember they can't read)
Each time that the filler sub is called, check if you've already played the sound for that item. If no, play the sound and add a "Played" flag in a map (you will use this map to check). Play also the sound in the OnItemClick event and in the Filler sub when IsSelected is true (if you enabled a selection mode).

BTW, AnimationEnd doesn't fire, can you advise?
In what case?
 

Rusty

Well-Known Member
Licensed User
Longtime User
Thanks for the suggestions.
I did embed the player within the filler and that works ok, but I have no way to address the list "item" to be able to change its background image/color as it is playing and then again when the player finishes, change the colors back.
As far as the AnimationEnd not firing, my mistake, I'd misspelled the view name :)
Now that it is firing, i can play the mp3's there, but I still need a way to "highlight" the animated view that has appeared. (this can happen after the animation is complete, but I need to be able to show the person which view is playing by highlighting (changing the background image/color)
Thank you so much for your continued support.
 

Informatix

Expert
Licensed User
Longtime User
Thanks for the suggestions.
I did embed the player within the filler and that works ok, but I have no way to address the list "item" to be able to change its background image/color as it is playing and then again when the player finishes, change the colors back.
As far as the AnimationEnd not firing, my mistake, I'd misspelled the view name :)
Now that it is firing, i can play the mp3's there, but I still need a way to "highlight" the animated view that has appeared. (this can happen after the animation is complete, but I need to be able to show the person which view is playing by highlighting (changing the background image/color)
Thank you so much for your continued support.
When you want to update a particular item, set a flag and call RefreshContent. In your filler sub, add some code to react to this flag.
For example:
the music ends and you want to stop the animation of a view, then set PlayMusic.put(Position, False) (PlayMusic is a map) and call RefreshContent.
In the filler sub, add a condition:
if PlayMusic.GetDefault(Position, False) then
'animate
else
'stop the animation
end if
 

Rusty

Well-Known Member
Licensed User
Longtime User
Thanks for your wonderful support :)
I have this working well and the mp3's are playing etc.
Now I'm dealing with an issue I thought you could point me to a solution quickly.
When the user touches a view/panel in the ULV, and they accidentally slide it up or down a few pixels, it fires the scrolled event.
is there a simple way to determine if the scroll was incidental (very few pixels of movement) or if it was intentional (scrolled a whole panel or more)?
Thanks,
Rusty
 
Top