How to create a grid view with two columns per row using RadListView


#1

Hello, I thought this is easy, but unfortunately, I can not find out any answer.
I installed telerik-ui, and want to use RadListView. From the doc, I can see the demo page with perfect layout, to have mulitple items per row. In my case, I want to have two columns per row and then show the list view. Below is my xml code, but it is rendering blank page. can anyone help to tell why? Thanks

This is the code in my XML:

<RadListView [items]="flattenDishes">
    <ListViewLinearLayout scrollDirection="Vertical" itemHeight="500" spanCount="2"></ListViewLinearLayout>
    <ng-template tkListItemTemplate let-flattenDish="item">
        <GridLayout rows="auto" columns="auto, *">
            <StackLayout orientation="vertical">
              <Image [src]="serverUrl +'images/' +  flattenDish.get('option_imageUrl') " stretch="aspectFill" width=200 height=200></Image>
              <Label  [text]="flattenDish.get('option_size')+':'+ flattenDish.getTrans('zh').get('title')"></Label>
              <Label  [text]="flattenDish.get('option_price')"></Label>
            </StackLayout>
        </GridLayout>
    </ng-template>
</RadListView>

Can anyone help me to have a working template here?

Thanks


#2

You have a grid layout but dont make use of it. You have a stacklayout in a gridlayout and never specify which row or column to use


#3

I updated the layout as below, still blank:

<RadListView [items]="flattenDishes">
    <ListViewLinearLayout scrollDirection="Vertical" itemHeight="500" spanCount="2"></ListViewLinearLayout>
    <ng-template tkListItemTemplate let-flattenDish="item" let-i="index">
        <GridLayout rows="auto" columns="auto, *">
            <StackLayout orientation="vertical" [row]="i/2" [col]="i%2">
              <Image [src]="serverUrl +'images/' +  flattenDish.get('option_imageUrl') " stretch="aspectFill" width=200 height=200></Image>
              <Label  [text]="flattenDish.get('option_size')+':'+ flattenDish.getTrans('zh').get('title')"></Label>
              <Label  [text]="flattenDish.get('option_price')"></Label>
            </StackLayout>
        </GridLayout>
    </ng-template>
</RadListView>

Any idea how to dynamically set row / col and how to make it work?

Thanks


#4

I believe you are not using the GridLayout the correctly.
You did specify the number of rows and columns the right way (although you don’t really need to specify rows if it only contains one row).

However inside the ‘content’ of your GridLayout you need to specify which element needs to be on which column.

For example if you want a GridLayout with one label in each column:

<GridLayout rows="auto" columns="auto *">
   <Label [text]="Label 1" col="0" row="0"></Label>
   <Label [text]="Label 2" col="1" row="0"></Label>
</GridLayout>

Take a look at the docs for better understanding: http://docs.nativescript.org/cookbook/ui/layouts/grid-layout


#5

what I want to do is actually put the stacklayout, which containing image, and two labels as a whole block, that is why I gives col, row to stackLayout within gridLayout.
May I ask if you are to provide this layout, how do you do that?
Thanks


#6

I changed the layout as below:

<ListView [items]="flattenDishes" height="100%">
    <ng-template let-flattenDish="item" let-i="index">
      <GridLayout rows="*" columns="*, *">
               <StackLayout orientation="vertical" [row]="getFloor(i/2)" [col]="i%2" width="200">
                   <Image [src]="serverUrl +'images/' +  flattenDish.get('option_imageUrl') " stretch="aspectFill" width=100 height=100></Image>
                   <Label  [text]="flattenDish.get('option_size')+':'+ flattenDish.getTrans('zh').get('title')"></Label>
                   <Label  [text]="flattenDish.get('option_price')"></Label>
               </StackLayout>
   </GridLayout>
    </ng-template>
</ListView>

But unfortunately, I found it is one item per row, only putting the second row item in the second column. It seemed the row setting for the stackLayout does not take effect.
Any idea?
Thanks


#7

It’s not really clear to me what kind of layout you are trying to achieve…
Do you have an image or an example?


#8

Hey @xhe, it appears to me that you still don’t grasp how grid layouts work, so I’ll try to simplify.

With the <GridLayout rows="*" columns="*, *"> declaration, you state that:

  • rows="*" you want a container of one row (note you have only one ‘value’ - the asterisk)
  • the row ("*") will take up all available vertical space in the grid layout
  • columns="*, *" you want the container to also be split into 2 columns (notice the 2 values separated by the comma)
  • each of the two columns will take up equal horizontal space of the grid layout.

All rows and cols are zero-indexed, so the available values for any item inside your grid layout are limited to the following combinations:
<view row="0" col="0">, <view row="0" col="1">
Note the zero values are default, so you may not have to specify them explicitly in the xml declarations.

With the above in mind, and when we look at the code you’ve provided, I can tell that StackLayout will be the only view aligned in one of the gridlayout cells, so perhaps you want to put col attributes to the labels instead? I am still not sure what you are planning to do with the Image element.


#9

Thanks @Pete.K for your explanation. I now changed the layout as this:

<ListView [items]="flattenDishes" height="100%" (itemTap)="onItemTap($event)">
    <ng-template let-flattenDish="item" let-i="index" let-odd="odd" let-even="even">
    <GridLayout rows="*" columns="200, *" [class.odd]="odd" [class.event]="even">

        <Image [src]="serverUrl +'images/' +  flattenDish.get('option_imageUrl') "
        stretch="aspectFill" width=100 height=100 row="0" col="0"></Image>

        <StackLayout orientation="vertical" [row]="0" [col]="1" verticalAlignment="center">
                       <Label  [text]="flattenDish.getTrans('zh').get('title')"></Label>
                       <Label  [text]="flattenDish.get('option_size')"></Label>
                       <Label  [text]="flattenDish.get('option_price') +' USD'"></Label>
                   </StackLayout>
    </GridLayout>
    </ng-template>
</ListView>

With this layout, I am placing each item in one row, which contains image one the left, first column and description, StackLayout, on the second columns.

Now, it is good.

I did this because I finally gave up by using a two column grid. My original plan is to use ListView to loop all the product and then put two produce side by side in one row and let them auto-grow. It seemed this design is very hard to implement. Don’t know if anyone can have good idea on how to achieve that result.

Thanks


#10

Hey @xhe did you manage to get this done by any chance? I struggled a few months ago to no avail - Dynamic GridLayout from array - Angular.

Nearly everyone who does tutorials seem fixated on [linear] lists, but barely anything on populating a grid.

If anyone of you more capable peeps can help with displaying data in dynamic gridlayout/gridview, you’ll be my hero! Hopefully someone can help with this.


#11

I can not find out solution, so I have changed layout here. just using
stackLayout to show vertical one, then showing each item per row. Here I
use gridLayout to show two columns for one item, that is it.


#12

Did you ever try RadListView with ListViewGridLayout? It’s working perfectly fine for me.

In my component there’s a property called nrOfColumns which sets the nr of columns in the grid based on the device type (phone/tablet), and in the view there’s this instead of ListViewLinearLayout:

<ListViewGridLayout tkListViewLayout scrollDirection="Vertical" itemHeight="200" [spanCount]="nrOfColumns"></ListViewGridLayout>

Along with a lot of other code to make things pretty that ends up looking like this (left side - on the right there’s a detail view of the stuff on the left… in this case changing stock levels of the highlighted Nike shoe):


#13

Thanks @Eddy, I’ll look into that - app looks really smart btw.

I also found out yesterday that Peter Staev’s plugin now has Angular support which is great!

I would have preferred to be able to do it in simple/plain code like you can the ListView without a plugin, but I am most grateful for a way to do it at all.


#14

Eddy,
Is that possible for you to share the complete template with us?
That will be much more helpful.
Thanks


#15

@xhe It’s a lot of code, comprised of many nested components etc so that’s a bit hard for me. However, Telerik has official samples for you to run and test, and copy-paste as you see fit:

Vanilla (XML):

Angular:


Dynamic GridLayout from array - Angular
#16

Awesome @Eddy! I meant to also post an update, but hadn’t had a chance. I implemented Peter Staev’s plugin much earlier and it worked great. Couldn’t have taken more than 10mins! - https://github.com/PeterStaev/NativeScript-Grid-View

Now to trial RadListView as soon as I can.