ListViewPlus - additional methods for the ListView component

This extension adds several features to the built-in ListView component.

Blocks v2:

Description:

AddClassicDividers: Add linear dividers in a classic ListView.

DecorateItems: Set rounded corners and margins for each item in the list. The radius is the same for every corner. Margin can be set with an integer, then all margins will have the same value. We can also list four integer values in the order left, top, right, and bottom.

BackgroundColorUnderItems: Set the color of the background that is under the list items.

Orientation: Change list view orientations. Fixes the original ListView property.

Reverse: Reverse the order of list items. The highest index will be at the top of the list.

ScrollTo: Scroll to a list item with animation. The item will be visible at the bottom of the list.

JumpTo: Scroll to a list item without animation. The item will be visible at the bottom of the list.

JumpToPx: Scroll to the height of the list expressed in px, without animation.

Position: Returns the list item to which the ListView is scrolled.

PositionPx: Returns the current height in px to which the ListView is scrolled.

SearchHintText: We can change the standard hint text that is displayed in the search bar.

DetectLongPress: Set ListView items to detect long press.

LongPress: An event triggered when we long press an item in the list.

Download extension:

Version 2: pl.listviewplus.aix (22.6 KB)

Download demo project:

TestListViewPlus.aia (132.9 KB)

The demo shows multi selection with a long press and deletion of selected items.

History:

V2:

  • added long press detection of ListView item,
  • added scrolling to height in pixels,
  • added the ability to read the current position of the scrolled ListView,
  • added option to modify hint text in list filtering bar,
  • added the ability to set the margins of an item from the list, so that each margin can be different,
  • adding dividers has been fixed to work in ListView horizontal view,
10 Likes

Great extension!

1 Like

will this working when set to show mainText and image?

Yes, the element is retrieved from the RecyclerView, so no matter what the view is, the one that is currently set is modified.

1 Like

The only thing is that the margins around the list item interfere with the built-in search engine, which hides items that do not match the search. The items are hidden but their margins remain, creating large gaps between list items. I'll have to think if there's a way around this.

hi, i dont know if this is a bug but i found there items have too big spaces to each other


image

Don't give Dividers because it's for the old list view. A margin of 100 is a lot, reduce it to, for example, 20 and it will be ok. Margins between items will be double because they add up. Top Position Margin + Bottom Position Margin.

thx

Modifies the extension so that each margin and each corner radius can be set separately.

Update:

Hi, may I ask if I can disable or adjust the shadows? Also, can ! control the background colour, spacing and text alignment of each element by adding more parameters? I don't know how to use dynamic components or comp creator, so I wanna ask if there are any more extensions available. Thx

This is my current listview.

I want to make it look like this:


(no shadow, more spacing, individual text alignment and colours)

Thank you so much for your help :pray: :pray: :pray: :pray:

or maybe the boxes be like this


Tysm

Hello. This is not possible with this extension. This extension only adds a few simple methods to the original ListView component. It's not easy to add many other methods to a ListView component from an extension. You need to look for an extension that creates the RecyclerView component from scratch. Or use the method with dynamic component creation.

Hi There. Nice extension.

Not sure if you're aware, but this extension doesn't seem to work under the emulator. When starting the TestListViewPlus example project using the emulator the following error is reported:

Runtime Error
invoke: no method named "CreateElement" in class java.lang.Boolean.

Sometimes the following is reported instead:

Runtime Error
Error from Companion: java.lang.RuntimeException: invalid syntax in eval form: :63:1: caught exception in inliner for # - java.lang.RuntimeException: no such class: pl.listviewplus.ListViewPlus gnu.bytecode.ObjectType.getReflectClass(ObjectType.java:179) gnu.bytecode.ClassType.getModifiers (ClassType.java:103) gnu.bytecode.ClassType.isInterface(ClassType.java:471) gnu.expr.InlineCalls.checkType(InlineCalls.java:56) gnu.expr.InlineCalls.visit(InlineCalls.java:49) gnu.expr.InlineCalls.visitSetExpValue(InlineCalls.java:363) gnu.expr.InlineCalls.visitSetExpValue(InlineCalls.java:28) gnu.expr.ExpVisitor.visitSetExp(ExpVisitor.java:114) gnu.expr.InlineCalls.visitSetExp(InlineCalls.java:369) gnu.expr.InlineCalls.visitSetExp(InlineCalls.java:28) gnu.expr.SetExp.visit(SetExp.java:406) gnu.expr.ExpVisitor.visit(ExpVisitor.java:55) gnu.expr.InlineCalls.visit(InlineCalls.java:46) gnu.expr.InlineCalls.visitBeginExp(InlineCalls.java:272) gnu.expr.InlineCalls.visitBeginExp(InlineCalls.java:28) gnu.expr.BeginExp.visit(BeginExp.java:156) gnu.expr.ExpVisitor.visit(ExpVisitor.java:51) gnu.expr.InlineCalls.visit(InlineCalls.java:46) gnu.expr.InlineCalls.visitBeginExp(InlineCalls.java:272) gnu.expr.InlineCalls.visitBeginExp(InlineCalls.java:28) gnu.expr.BeginExp.visit(BeginExp.java:156) gnu.expr.ExpVisitor.visit(ExpVisitor.java:51) gnu.expr.InlineCalls.visit(InlineCalls.java:46) gnu.expr.InlineCalls.visitLetExp(InlineCalls.java:317) gnu.expr.InlineCalls.visitLetExp(InlineCalls.java:28) gnu.expr.LetExp.visit(LetExp.java:207) gnu.expr.ExpVisitor.visit(ExpVisitor.java:51) gnu.expr.InlineCalls.visit(InlineCalls.java:46) gnu.expr.InlineCalls.visit(InlineCalls.java:28)
gnu.expr.LambdaExp.visitChildren Only(LambdaExp.java:1664) gnu.expr.LambdaExp.visitChildren(LambdaExp.java:1651) gnu.expr.InlineCalls.visitScopeExp(InlineCalls.java:279) gnu.expr.InlineCalls.visitLambda Exp(InlineCalls.java:349) gnu.expr.InlineCalls.visitLambdaExp(InlineCalls.java:28) gnu.expr.LambdaExp.visit(LambdaExp.java:1640) gnu.expr.ExpVisitor.visit(ExpVisitor.java:55) gnu.expr.InlineCalls.visit(InlineCalls.java:46) gnu.expr.InlineCalls.visit(InlineCalls.java:28)
gnu.expr.ExpVisitor.visitAndUpdate(ExpVisitor.java:161) gnu.expr.ExpVisitor.visitExps (ExpVisitor.java:175) gnu.expr.ApplyExp.visitArgs(ApplyExp.java:415)
gnu.kawa.reflect.CompileInvoke.validateApplyinvoke(Compilelnvoke.java:23) java.lang.reflect.Method.invoke(Native Method) gnu.expr.InlineCalls.maybelline (InlineCalls.java:467) gnu.expr.QuoteExp.validateApply(QuoteExp.java:150) gnu.expr.ReferenceExp.validateApply (ReferenceExp.java:191)
gnu.kawa.functions.CompilationHelpers.validateApply ToArgs(Compilation Helpers.java:66) java.lang.reflect.Method.invoke(Native Method)
gnu.expr.InlineCalls.maybelline (InlineCalls.java:467) gnu.expr.QuoteExp.validateApply(QuoteExp.java:150) gnu.expr.ReferenceExp.validateApply(ReferenceExp.java:191) gnu.expr.InlineCalls.visitApplyExp(InlineCalls.java:119) gnu.expr.InlineCalls.visitApplyExp(InlineCalls.java:28) gnu.expr.Apply Exp.visit(ApplyExp.java:410)
gnu.expr.ExpVisitor.visit(ExpVisitor.java:55) gnu.expr.InlineCalls.visit(InlineCalls.java:46) gnu.expr.QuoteExp.validateApply(QuoteExp.java:162)
gnu.expr.ReferenceExp.validateApply(ReferenceExp.java:191) gnu.kawa.functions.Compilation Helpers.validateApplyToArgs(Compilation Helpers.java:66)
java.lang.reflect.Method.invoke(Native Method) gnu.expr.InlineCalls.maybelline (InlineCalls.java:467) gnu.expr.QuoteExp.validateApply(QuoteExp.java:150)
gnu.expr.ReferenceExp.validateApply(ReferenceExp.java:191) gnu.expr.InlineCalls.visitApplyExp(InlineCalls.java:119) gnu.expr.InlineCalls.visitApplyExp(InlineCalls.java:28) gnu.expr.InlineCalls.visitBeginExp(InlineCalls.java:272) gnu.expr.InlineCalls.visitBeginExp(InlineCalls.java:28) gnu.expr.BeginExp.visit(BeginExp.java:156) gnu.expr.ExpVisitor.visit(ExpVisitor.java:51) gnu.expr.InlineCalls.visit(InlineCalls.java:46) gnu.expr.InlineCalls.visit(InlineCalls.java:28)
gnu.expr.ApplyExp.visit(ApplyExp.java:410) gnu.expr.ExpVisitor.visit(ExpVisitor.java:51) gnu.expr.InlineCalls.visit(InlineCalls.java:46)
gnu.expr.LambdaExp.visitChildren Only(LambdaExp.java:1664) gnu.expr.LambdaExp.visitChildren(LambdaExp.java:1651) gnu.expr.InlineCalls.visitScopeExp(InlineCalls.java:279) gnu.expr.InlineCalls.visitLambda Exp(InlineCalls.java:349) gnu.expr.InlineCalls.visitLambdaExp(InlineCalls.java:28) gnu.expr.ExpVisitor.visitModule Exp(ExpVisitor.java:103)
gnu.expr.ModuleExp.visit(ModuleExp.java:482) gnu.expr.ExpVisitor.visit(ExpVisitor.java:51) gnu.expr.InlineCalls.visit(InlineCalls.java:46)
gnu.expr.InlineCalls.inlineCalls (InlineCalls.java:33) gnu.expr.Compilation.walkModule(Compilation.java:994) gnu.expr.Compilation.process(Compilation.java:1965)
gnu.expr.ModuleInfo.loadByStages (ModuleInfo.java:330) gnu.expr.ModuleExp.evalModule1 (ModuleExp.java:238) gnu.expr.ModuleExp.evalModule(ModuleExp.java:198) gnu.expr.Language.eval(Language.java:943) gnu.expr.Language.eval(Language.java:883) gnu.expr.Language.eval (Language.java:865) com.google.appinventor.components.runtime.util.AppInvHTTPD.serve(AppInvHTTPD.java:197) com.google.appinventor.components.runtime.util.NanoHTTPD$HTTPSession.run(NanoHTTPD.java:489)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
java.lang.Thread.run(Thread.java:923)

The emulator appears to be running Android 11.

The same example works fine on my Phone though. My phone is running Android 9.

Cheers, Tim.

are you using USB to connect to the companion app?
does it work after building using the apk file?
try to connect via wifi

see also this thread

Regarding the extensions over USB issue, I believe I have identified the source of the problem and submitted a fix.

Taifun

The emulator runs on the same PC as the web browser I'm using to run the App Inventor UI. It appears to connect to aiStarter using localhost. I start it from the Connect menu, choosing Emulator. This starts the emulator, and then the companion App (within the Emulator), and then runs the project. I have aiStarter installed, and running, and all my projects seem to work fine under the Emulator with this setup. When I try to run the TestListViewPlus project, or I include the ListViewPlus extension in a project, I get the messages I reported previously.

I don't unserstand how I'd use USB or Wifi to connect to the emulator that's running on my PC...? Perhaps you're thinking I have the companion app on my phone, and I could understand if this were the case, but it's not. I could try it I guess, but I haven't at this point.

Cheers, Tim.

I don't use an emulator so I don't know about emulator errors. Does your emulator have the latest Companion installed? CreateElement is a block from the built-in ListView component. So either your Companion is not up to date or there is some problem with the ListView. Make a project with just ListView without the ListViewPlus extension and try it out.

You are using an emulator...
In this case try a device and connect via Wifi or test using the apk file

Taifun

Hi Patryk,

I believe it does have the latest companion installed. I just installed the emulator a few days a ago for the first time, so I'd be surprised if it was old. It reports version 2.65u when the emulator starts up.

No, my app that has a ListView in it works fine under the emulator, until I add ListViewPlus extension (that does nothing, just added an instance to screen1.) I've noticed now though, that another extension I tried (Ai2Tools) reports similar errors, so I may be unfairly singling out ListViewPlus, and it could be a general thing for extensions that use reflection to delve in to the internals.

Cheers, Tim.

Hi Taifun,

A built .apk works fine on my phone. I just like using the emulator on the PC as it is so much more convenient for quick testing while developing.

And I'm only pointing out that it doesn't work under the emulator in case it'd be releatively simple to fix at some time in the future. In the mean time I can live with using my phone to test with.

Cheers, Tim.