B4A Library [Class] CheckList

Hi,

I created a class to manage a list with checkboxes (but not only, you can use it for any kind of list with rows). The layout is highly customizable and you can even extend a clicked item with extra content. You can rearrange the items programmatically or manually (drag & drop).

Tutorials: How they do #1, How they do #3

img1.jpg img2.jpg img3.jpg img4.jpg img5.jpg

v1.1: I added the ExtendItem function and an option to check the box when items are added

v1.2: I fixed the width problem (in a container like TabHost, the width property returns -1, so we have to use a different method to get the SV width) and, in the demo, a click on the extended item collapses now its content.

v1.3: I added a new function to add items without checkbox (AddItemNoChkbx) so you can use this class as a ListView replacement;
I changed the way it colors the selected item (now it complies to the default Android theme);
I added an option to color differently the extended item.

v1.4: I optimized the code a little bit and I added three functions:
AddCustomItem (adds your own layout to the list);
AdjustBitmap (resizes the bitmap to fit the given dimensions);
GetFirstText (returns the first label text found for the given ID).

v1.5: I simplified and improved the management of extended items (I also fixed a bug). Unfortunately, that could break existing code.
Inspired by the class CustomListView, I added a parameter to Initialize: DividerHeight (if you want to put a colored divider between items) and several functions:
- NumberOfItems
- getHeight
- JumpToPosition
- JumpToItem
- CollapseItem
- HasExtraContent
- ExtendedItemID

v1.6:
Now, you can define the color of checked items and the background color (transparent by default).
I added two (very fast) functions:
- JumpToView (scrolls the list to the given view)
- FindPanelContaining (returns the panel containing the given view)
I added another example.

v2.0:
I added more than 10 new functions (MoveItem, RemoveItemAt, SwapItems, SortItems, ReplaceItem, ApplyColors, CreateTextList, etc.). See post #21 for complete list;
I changed the ID type (formerly Int) to Object (that shouldn't break the existing code);
I added the Drag & Drop feature;
I optimized JumpToPosition (a lot quicker now);
I fixed a bug with colors.

v2.1:
I added functions to filter the list;
I added CreateIntegerList to ease the sorting and filtering of integer values;
Now you can change the item height in ReplaceItem.

v2.2:
I fixed a bug (BackgroundColor was not applied to new items)
I added new functions:
- FindPanelWithID(ID As Object) As Object
- SetOnPaintListener(SubName As String)
- Repaint(pnlItem As Panel)
I renamed ApplyColors to RepaintAllItems

v2.21:
I changed an incorrect declaration in the demo #1 and #2.
The class is now compatible with the obfuscation option.

v2.22:
The class no longer displays warnings with B4A v2.7x.
All examples are now compatible with the obfuscation option.

Complete list of functions here

Fred

PS: you need the Reflection Lib
 

Attachments

  • CheckList v2.22.zip
    60.2 KB · Views: 2,362
Last edited:

Informatix

Expert
Licensed User
Longtime User
I fixed the width problem (in a container like TabHost, the width property returns -1, so we have to use a different method to get the SV width) and, in the demo, a click on the extended item collapses now its content.

I think I won't improve this class any longer.
 
Last edited:

Phantomco

Member
Licensed User
Longtime User
Curious

Fred,

Nice job on the class!

I had a weird one; I'm building the class into an app and it only worked if I physically change the orientation of the tablet first, it works fine after that.
There is no error on the tablet, the view is just blank if I don't insert a header.

Found I had a remnant of initializing the scrollview in the app itself which killed the scrollview, as well as giving an error on addheader. That went away when I removed the initialize. (Just in case anybody does the same thing)

My expansion of the class was to add two checkboxes per line, as we need a yes/no.

Again, great job, very useful!

Mike
 

Informatix

Expert
Licensed User
Longtime User
New version (1.3):
- I added a new function to add items without checkbox (AddItemNoChkbx) so you can use this class as a ListView replacement;
- I changed the way it colors the selected item (now it complies to the default Android theme);
- I added an option to color differently the extended item.

Enjoy,
Fred
 

Jack Cole

Well-Known Member
Licensed User
Longtime User
Thanks for this class and your work on it. It is very useful.

I am having one problem with it. It works fine when you click a checkbox, but returns the following when you click on an item in the scrollview.

An error has occurred in sub: java.lang.Exception: Sub pnlsvtouch signature does not match expected signature.

I get this also in the example app that you have included.

Any ideas?
 

Informatix

Expert
Licensed User
Longtime User
New version (1.4):
I optimized the code a little bit and I added three functions:
AddCustomItem (adds your own layout to the list);
AdjustBitmap (resizes the bitmap to fit the given dimensions);
GetFirstText (returns the first label text found for the given ID).

See post #1 for files

Fred
 

Informatix

Expert
Licensed User
Longtime User
New version (1.5):
I simplified and improved the management of extended items (I also fixed a bug). Unfortunately, that could break existing code.

Inspired by the class CustomListView, I added a parameter to Initialize: DividerHeight (if you want to put a colored divider between items) and several functions:
- NumberOfItems
- getHeight
- JumpToPosition
- JumpToItem
- CollapseItem
- HasExtraContent
- ExtendedItemID

Now, the big question is: what are the differences between my class and the Erel's class ?
- Checkboxes are not handled natively in CustomListView (you can display them and use them, but you have to write everything)
- CustomListView doesn't allow a custom background (like a picture)
- CustomListView has functions to insert or remove items at a specific position (I can add these functions in my class if someone needs them)
- CheckList uses less memory (it doesn't need the extra panels in each item to handle the user actions and doesn't need a panel to hold the Scrollview)
- CheckList can add an extra content under the clicked item (try the demo to understand)

Let me know if I forgot something (or if you disagree).

Am I saying "my class is better" ? Yes and no. It depends on your needs. Try both.
And I'm not in a kind of competition (especially against Erel). I think that several different ways of providing new features are never superfluous.

Fred
 

Informatix

Expert
Licensed User
Longtime User
New version v1.6:
Now, you can define the color of checked items and the background color (transparent by default).

I added two (very fast) functions:
- JumpToView (scrolls the list to the given view)
- FindPanelContaining (returns the panel containing the given view)

I added another example.

Fred
 

Mahares

Expert
Licensed User
Longtime User
@Fred:
I applied your new CheckList class, which is very good by the way, to a SQLite table and managed to make it work work well.
The only time I get an error is when I UNcomment 4 lines that are currently commented in the ExpandItem sub of the main module. I would like to uncomment them because they serve a purpose. I tried a few code combinations to no avail. I have attached the sample in its entirety.
Merci d'avance.
 

Attachments

  • CheckListMahares.zip
    14.5 KB · Views: 524

Informatix

Expert
Licensed User
Longtime User
@Fred:
I applied your new CheckList class, which is very good by the way, to a SQLite table and managed to make it work work well.
The only time I get an error is when I UNcomment 4 lines that are currently commented in the ExpandItem sub of the main module. I would like to uncomment them because they serve a purpose. I tried a few code combinations to no avail. I have attached the sample in its entirety.

Only the first line must stay commented because it is not needed. Without this line, that works fine. The panel containing the label is already set in ExpandItem because it is one of the function parameters.

Three remarks about your code:
- in Activity_Create, you could replace the loop index value (i) in lst.AddCustomItem by Cursor1.GetInt("CODE"). This way, the item ID becomes the code value and you get back this code in a function like CheckedList.
- CheckAllBoxes does not need to be in a loop.
- Your loop in btnSelection_Click to get the text of each selected item is not very efficient because GetFirstText isn't optimized (it goes through all items each time). You should use GetFirstText only outside of a loop (and I should mention that in its comment). Since the data come from a DB, the better solution is to create a SQL query with the selected ID (you create your WHERE clause with CheckedList) and read your result in a loop. That's quicker and allows you to read all the stored data for each item (if you need these additional data, of course).

Merci d'avance.
De rien.
 

Mahares

Expert
Licensed User
Longtime User
@Fred: Thank you very much for your suggestions. I was able to implement the first three. I could not quite understand how to optimize the last one:
Since the data come from a DB, the better solution is to create a SQL query with the selected ID (you create your WHERE clause with CheckedList) and read your result in a loop. That's quicker and allows you to read all the stored data for each item (if you need these additional data, of course).

B4X:
For i=0 To lst.CheckedList.Size -1
      MyChem=lst.GetFirstText(lst.CheckedList.Get(i))   'gets the text of the item selected
      Msgbox("Total number of Checked items: " & lst.CheckedList.Size & CRLF _
      & "Selected item: " & MyChem,"")
Next
Salutations
 

Informatix

Expert
Licensed User
Longtime User
When you work with a database, you have many options when it comes to put these data into a list. You can store them in an array and work with this array (in most cases, it's a very bad solution, especially on a phone, because of the limited memory); you can store them in the views (very limited solution, the views cannot hold everything and trying to put a lot of things in the Tag property is not different from storing data in an array); you can put only what's needed for display in the views and get the other data (the other DB columns) only when these data are required (after a user selection, for example). I think this the best solution.
How to implement it ?
1) With a SELECT query, you read only a subset of your columns (the column needed to display informations to the user);
2) When the user has made his choices and clicks on the Selection button, you
retrieve only the required columns for each selected row. CheckedList returns a list with the selected items ID, so you can construct a WHERE clause with these ID. The goal is to send to your DB something like SELECT Col1, Col2 WHERE ID=n1 OR ID=n2 OR ID=n3...
Is it clear?

EDIT: In your case, ID is in fact CODE in the WHERE clause.
 
Last edited:

Mahares

Expert
Licensed User
Longtime User
If the CODE is an integer , I can use it in place of the ID as you suggested. And it works. See below code construct:
B4X:
txt="SELECT CHEMICAL FROM tblChemicals WHERE CODE IN(" & lst.CheckedList.Get(0) 
   For i=1 To lst.CheckedList.Size -1
      txt=txt  & "," &  lst.CheckedList.Get(i)
   Next
   txt=txt & ") ORDER BY CHEMICAL"
   Cursor1=SQL1.ExecQuery(txt)
   Cursor1.Position=0   
   For i=0 To Cursor1.RowCount-1
      Cursor1.Position= i
      Msgbox(Cursor1.GetString("CHEMICAL"),"")
Next
However, if CODE is a string, how can you use the ID in a SQL statement when ID is not part of the underlying table. For instance:
B4X:
txt="SELECT CHEMICAL FROM tblChemicals WHERE ID IN(" & lst.CheckedList.Get(0)
, etc.. is not going to work. The only way I see it with my blinders right now is:
SELECT CHEMICAL FROM tblChemicals WHERE CHEMICAL IN(" & lst.GetFirstText(lst.CheckedList.Get(0)) and so on...
I hope you have given it some thought. Best regards.
 

Informatix

Expert
Licensed User
Longtime User
The current type is Int for ID, but that's a design error. That should be Object and that's gonna change in the next version (I hope to release it tomorrow). In the meanwhile, you can replace all "ID as Int" by "ID as Object" in the class. So it won't matter if your CODE contains int, string or whatever else.
 

Mahares

Expert
Licensed User
Longtime User
@Fred:
To accommodate a string in the ID, I have replaced all ID as Int by ID as Object in the CLASS and also in the MAIN module. It worked well after the replacement. I will be your Guinea-pig.
One thing to think about is: What if you use the ID as string, but can have duplicate values for that ID. Would that present any problem? Should the ID's be DISTINCT (unique)?, etc..
For instance:
Prenom Compagnie
Fred Informatix_France
Fred Informatix_USA
Thanks
 

Informatix

Expert
Licensed User
Longtime User
@Fred:
To accommodate a string in the ID, I have replaced all ID as Int by ID as Object in the CLASS and also in the MAIN module. It worked well after the replacement. I will be your Guinea-pig.
One thing to think about is: What if you use the ID as string, but can have duplicate values for that ID. Would that present any problem? Should the ID's be DISTINCT (unique)?, etc..
For instance:
Prenom Compagnie
Fred Informatix_France
Fred Informatix_USA
Thanks
The IDs are under your control. Their uniqueness depends on you. If you want to use functions as JumpToItem, their uniqueness is mandatory or you could jump to the wrong item. ExtendItem needs also an unique ID, so I strongly recommend unique IDs. If you use database, you should have an unique ID for each row (the row number - not recommended - or the row key).
 
Top