How to create list programmatically

8 messages - 1846 views

Some of the lists in my application were growing somewhat big and I wanted to test out the programmatic way of creating the UI so I could try if I could get better performance from my application.

But creating the lists seems to be a bit difficult. How am I supposed to create it programmatically ? There seems to be no reasonable way of using a data provider and providing the renderer for the list widget. Or am I supposed to add the child listitem widgets by hand, and if so then it seems that I will be unable to use the data provider to automatically update the list and/or values..

Every XML loading in Kuix pass through this method : Kuix.loadXml(Widget rootWidget, InputStream inputStream, DataProvider dataProvider, boolean append), like screen loading or listItem loading.

This method permit to load a widget tree represented in an xml input stream as a child of the given rootWidget.

For example the rootWidget for loading a new screen is a new Screen instance. While loading a listItem, the rootWidget is the List instance. A list is nothing more than a simple container and then a simple widget. Then List, listItem are only made to be simple to use. But you can completly rewrite the way to load items in a List or in you own list implementation.

List and Dataproviders are made to optimize ListItem creation by regenerating only new items.

Hello there !

I'm afraid I don't understand how we're supposed to build lists or other stuff programmatically.

I'm currently trying to set up a SearchFrame which is at first composed of a label, a textfield and a "search" button. When the button is clicked, I get the search results through a webservice call on the target platform and then, I would like to display them with a List.

Am i supposed to reload another .xml screen containing the List widget and passing a dataprovider as an argument or is it possible to build and add it to the current sreen programmatically? I'm tryin' to but failin' every time, a piece of code helping me to solve my problem would be really enjoyable !

Thanks

 

 

 

 

 

The best way to do what you want is to use DataProviders. In this way you can display result in your first screen.
I can proposed to you something like that :

<screen style="layout:borderlayout">
    <container style="layout-data:bld(north);layout:borderlayout">
        <textfield id="myTextfield" style="layout-data:bld(center)"/>
        <button style="layout-data:bld(east)" onAction="search(myTextfield.text)">GO</button>
    </container>
    <scrollContainer style="layout-data:bld(center)">
        <list>
           <_renderer><![CDATA[
              <listItem><text>@resultLabel</text></listItem>
           ]]></_renderer>
           <_items>@results</_items>
        </list>
    </scrollContainer>
</screen>

Layouts :
- first a screen has by default a gridlayout(1,1) then style="layout:borderlayout" change it to borderlayout
- in this sample a container with textfield and a button is on the north and a list within a scrollcontainer is placed in center

List :
- in the list we defined the rendrer and items attribute.
- rendrer is used by the list as a template to render each list item and @resultLabel will correspond to a specific value for each item. More informations in the next lines.
- items is used to bind the list to the dataprovider.

DataProvider:
- First you need to create you own DataProvider:

DataProvider myDataProvider = new DataProvider();
   
  here we only use myDataProvide as item holder then  we do not need to override the DataProvider class.
   
- Second load your screen :

Screen myScreen = Kuix.loadScreen("/xml/myScreen.xml", myDataProvider);

- Third set the screen as current :

KuixMIDlet.getDefault().getCanvas().getDesktop().setCurrentScreen(myScreen);

At this state, your DataProvider is empty, then only a textfield and a button is displayed.
Next I supposed that you know how to catch the button action to intercept the 'search(string)' call. After that you received the response of your webService and you'll be able to populate you dataProvider with all results.

Now we need to create a DataProvider for each result. Then override the DataProvider class like :

public class ResulDataProvider extends DataProvider {

             private String resultLabel;
             
             public ResulDataProvider(String resultLabel) {
                             this.resultLabel = resultLabel;
             }
             
             public String getValue(String property) {
                             if ("resultLabel".equals(property) {
                                  return resultLabel;
                             }
                             super.getValue(property);
             }
             
}

We are now ready to populate myDataProvider :

(loop)
            myDataProvider.addItem("results", new ResultDatProvider(/* here the string label */));
(endloop)

After this the display is automaticaly updated.

Else, Kaprice sources may help you to undestand DataProvider and Lists.

Hey Bo !

 

Thank you for you rapid and very detailed answer ! Thanks to you explanations I'm done with this list-population and  can now go on in my coding work!

I really enjoy Kuix (at least for the time being :D) and hope for you that it'll be a success ! Good cheer !

when i tried this im getting an error

 

java.lang.NullPointerException
        at com.explorer.kuixApp.onMessage(kuixApp.java:50)
        at org.kalmeo.util.frame.FrameHandler.processMessage(FrameHandler.java:247)
        at org.kalmeo.kuix.core.Kuix.callActionMethod(+18)
        at org.kalmeo.kuix.widget.ActionWidget.processActionEvent(ActionWidget.java:115)
        at org.kalmeo.kuix.widget.MenuItem.processActionEvent(MenuItem.java:63)
        at org.kalmeo.kuix.widget.ActionWidget.processKeyEvent(ActionWidget.java:82)
        at org.kalmeo.kuix.core.focus.FocusManager.processKeyEvent(FocusManager.java:264)
        at org.kalmeo.kuix.widget.Menu$1.processKeyEvent(Menu.java:101)
        at org.kalmeo.kuix.widget.Screen.processMenuAction(+34)
        at org.kalmeo.kuix.widget.Screen$ScreenMenu.processActionEvent(Screen.java:171)
        at org.kalmeo.kuix.core.focus.FocusManager.processSoftKeyEvent(FocusManager.java:350)
        at org.kalmeo.kuix.widget.Menu$1.processKeyEvent(Menu.java:102)
        at org.kalmeo.kuix.core.KuixCanvas$2.run(KuixCanvas.java:266)
        at org.kalmeo.util.worker.Worker.run(Worker.java:164)
Execution completed.

my code

dataProvider.addItem("results", new DynamicDataProvider("Male"));
            Screen screen = Kuix.loadScreen("list_container.xml", dataProvider);
            screen.setCurrent();

 

public class DynamicDataProvider extends DataProvider {

    // create a value variable
    private String gender = "Anas";
    public DynamicDataProvider(String str){
        this.gender = str;
    }

    // override the parent method to handle user defined value
    protected Object getUserDefinedValue(String property) {
        return gender;
    }   

 

Please help

Ok, but what is your code for the onMessage method of com.explorer.kuixApp ?