This is a migrated thread and some comments may be shown as answers.

Creating a listview with list-items with different layouts

6 Answers 310 Views
ListView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
dash
Top achievements
Rank 1
dash asked on 19 Nov 2016, 12:38 PM

Can I create a listview with list-items with different layouts?

I think I saw something was in the works.

 

6 Answers, 1 is accepted

Sort by
0
Nick Iliev
Telerik team
answered on 21 Nov 2016, 07:41 AM
Hi dash man,

Yes, you can create a different layout for list-view items.
The approach is a bit different depending on whether you are creating a core NativeScritpt application or Angulae-2 + NativeScript application, but overall the concept is the same.
In order to achieve that you should control your item styles via your code behind files.

A nice example (Nativescript core) for customization based on item index is shown here.In the example from the link the items are created and initialized but the same logic can be applied when using custom CSS styles for your items.
Basically to do that in NativeScript core and RadListView you can use itemLoading event.(if you need example for Angular-2 app scroll down after the snippets)
<lv:RadListView id="listView" items="{{ dataItems }}" row="1" itemLoading="onItemLoading">
    <lv:RadListView.listViewLayout>
        <lv:ListViewLinearLayout scrollDirection="Vertical"/>
    </lv:RadListView.listViewLayout>
    <lv:RadListView.itemTemplate>
        <StackLayout orientation="vertical" padding="15">
            <Label fontSize="20" text="{{ itemName }}" marginBottom="10"/>
            <Label fontSize="14" text="{{ itemDescription }}"/>
        </StackLayout>
    </lv:RadListView.itemTemplate>
</lv:RadListView>

and with the code behind to create the customization logic in the callback
function onItemLoading(args) {
    if (args.itemIndex % 2 == 0) {
        args.view.backgroundColor = "#b3ecff";
        args.view._subViews[0].fontSize = "24";
        args.view._subViews[1].fontSize = "18";
    }
    else {
        args.view.backgroundColor = "#ccf2ff";
        args.view._subViews[0].fontSize = "20";
        args.view._subViews[1].fontSize = "14";
    }
}
exports.onItemLoading = onItemLoading;


In NativeScript + Angular-2 app you can follow this example which shows how to apply CSS class only on specific list-view items and this way fully customizing the UI. Notice the usage of setupItemView where the list items are distinguished with some logic and then the usage of different styles based on this setup in the HTML file.

Regards,
Nikolay Iliev
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
dash
Top achievements
Rank 1
answered on 21 Nov 2016, 12:49 PM

I don't think I explained properly.

I meant - can you have list-items that different layouts - i.e. different UI elements - not just CSS changes.

Have 1 list-view - then have different formatted list-items.

 

0
Nick Iliev
Telerik team
answered on 21 Nov 2016, 01:57 PM
Hi dash man,

Yes, you can add different layout component as well (and remove pre-defined ones).
Again you can use that with the same code as shown below but instead of styling you can access your main container for the itemTemplate and add/remove children component to it.

For example, let's assume you have the following itemTemplate:
<lv:RadListView.itemTemplate>
    <StackLayout orientation="vertical" padding="15">
         <Label fontSize="20" text="{{ itemName }}" marginBottom="10"/>
         <Label fontSize="14" text="{{ itemDescription }}"/>
    </StackLayout>
</lv:RadListView.itemTemplate>

Then you can access the Stack layout (which we will use as the template container) and from there you can add/remove to the stack.

e.g.:
export function onItemLoading(args) {
    if (args.itemIndex % 2 == 0){
        var lbl = new Label();
        lbl.text = "added new Label";
 
        args.view.addChild(lbl);
            // args.view is the StackLayout based on the above snippet
            // args.view.subViews[0] wiil be the first label in that case
            // args.view.removeChildren() will remove all childs of the StackLayout
    }
    else {
        // do something else
    }
}


Regards,
Nikolay Iliev
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
dash
Top achievements
Rank 1
answered on 21 Nov 2016, 02:40 PM

Thank you for the response - I will try it out.

 

But instead of creating the elements in code - it would be good if it was possible to create in xml.

The only requirement would be that when the user objects are pushed into the ObservableArray,

the objects would have a special method getItemID() or something.

Then when the ListView object needs to create the listitem - it would call getItemID() on the user object

and it would create the UI XML element group with the same id.

 

<lv:RadListView.itemTemplate>
    <StackLayout orientation="vertical">
           <StackLayout item_id="some_name">
               <Label fontSize="14"/>
            </StackLayout>
           <StackLayout item_id="personal">
               <TextView fontSize="14" />
            </StackLayout>
 
    </StackLayout>
</lv:RadListView.itemTemplate>

 

0
Nick Iliev
Telerik team
answered on 21 Nov 2016, 02:57 PM
Hi dash man,

The scenario you are describing is possible to implement in NativeScript + Angular-2 application.
In angular you have several exported values (like odd, even, index, etc.) and you can also create your own exported values and reuse them as allies for local ones.
In your case, you can reuse them for creating the logic for different list-view cells.
For example look at this reference.
In Angular-2 you have also structural directives like *ngSwitch and *ngIf which can further extend your UI.
Some samples for those directives can be found here.

However, if you need to implement similar logic in NativeScript Core you can do it using visibility attribute and again controlling it from your code behind.

<StackLayout>

    <StackLayout visibility="{{ isFirstTemplateVisible ? 'visible' : 'collapsed' }}" >
<!-- the first template components follows here -->
      </
StackLayout>
    <StackLayout visibility="{{ isSecondTemplateVisible ? 'visible' : 'collapsed' }}" >  
<!-- the second template components follows here -->
      </
StackLayout>

</StackLayout>

Where you have two boolean variables which you can control in your loaded event or in your itemLoading event.

Regards,
Nikolay Iliev
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
dash
Top achievements
Rank 1
answered on 21 Nov 2016, 03:05 PM

I'm not familiar with Angular and have already invested quite some time in my {N} app.

I am doing what you suggested - controlling view via `visibility` - and it works but slow.

I've got 8-10 different layouts and each has about 10 UI elements - so for each list-item - about 80-100

views have to be created when only about 10 is needed - very inefficient. Multiply that by the number of

list-items and you can see, this is a not a very good long term solution.

 

I will most probably create the list-item dynamically as you suggested coupla responses ago - but

if this feature was available at the XML level - it would be faster and cleaner software development.

 

Thanks again for this great product.

 

 

Tags
ListView
Asked by
dash
Top achievements
Rank 1
Answers by
Nick Iliev
Telerik team
dash
Top achievements
Rank 1
Share this question
or