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

Figure 1: RadListView layouts

9 Answers 225 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.
Stan
Top achievements
Rank 1
Stan asked on 05 Aug 2017, 09:39 PM

I'm new to NativeScript & RadListView. I was drawn to NativeScript because of this picture and I'd to know how did they did this? At first I thought it was done with multiple itemTempletes but then I remember seeing this before multiple itemTempletes were available.

There is no documentation, or code, for this sample layout:
http://docs.telerik.com/devtools/nativescript-ui/Controls/NativeScript/ListView/overview#different-layouts

The SDK sample linear & Grid layouts are different.

9 Answers, 1 is accepted

Sort by
0
Accepted
Nick Iliev
Telerik team
answered on 07 Aug 2017, 06:16 AM
Hello Stan,

The example you are referring to is implemented with Telerik UI for Android which is a different product from the NativeScript UI. Although they are using almost identical RadListView implementation there are some functionalit8ites which are available only in one product and not the other. 

With RadListView for NativeScript, you can set header and footer for your vertical list views as done in this example from the SDK application. However, this would allow you to create headers and footers for vertically aligned items. 

To achieve the result from the first image (groped items - each group with its own header) you can approach the issue by using two separate list views (with horizontal alignment) and provide a custom made label as a header for each RadListView.
e.g. (pseudo code based on this example)
<GridLayout rows="50, *, 50, *" columns="">
     
    <Label row="0" text="First Group" textWrap="true" />
    <lv:RadListView row="1" items="{{ dataItems }}" >
        <lv:RadListView.listViewLayout>
            <lv:ListViewLinearLayout scrollDirection="Horizontal"/>
        </lv:RadListView.listViewLayout>
        <lv:RadListView.itemTemplate>
            <StackLayout orientation="vertical">
                <Label fontSize="20" text="{{ itemName }}"/>
                <Label fontSize="14" text="{{ itemDescription }}"/>
            </StackLayout>
        </lv:RadListView.itemTemplate>
    </lv:RadListView>
 
    <Label row="2" text="Second Group" textWrap="true" />
    <lv:RadListView row="3" items="{{ dataItems }}" >
        <lv:RadListView.listViewLayout>
            <lv:ListViewLinearLayout scrollDirection="Horizontal"/>
        </lv:RadListView.listViewLayout>
        <lv:RadListView.itemTemplate>
            <StackLayout orientation="vertical">
                <Label fontSize="20" text="{{ itemName }}"/>
                <Label fontSize="14" text="{{ itemDescription }}"/>
            </StackLayout>
        </lv:RadListView.itemTemplate>
    </lv:RadListView>
 
</GridLayout>


Regards,
Nikolay Iliev
Progress Telerik
Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
0
Stan
Top achievements
Rank 1
answered on 15 Aug 2017, 01:07 AM

Thank you so much for that! It worked great.

I would have never figured out to use rows="50, *, 50, *" in the GridLayout.

0
Stan
Top achievements
Rank 1
answered on 15 Aug 2017, 07:41 PM

Follow up question:

This works great when I have 2 groups, or 3 in portrait mode, but when I have 5 or 6 groups can this be done with a StackLayout and ScrollView in conjunction with RadListView?

Thank you in advance.

0
Accepted
Deyan
Telerik team
answered on 16 Aug 2017, 07:11 AM
Hello Stan,

Thanks for writing back.

You should be able to achieve the discussed scenario with a ScrollView provided that the horizontal scrolling of it is disabled (so that it does not interfere with the horizontal scrolling of the lists within).

Regards,
Deyan
Progress Telerik
Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
0
Stan
Top achievements
Rank 1
answered on 17 Aug 2017, 08:31 PM

Thanks!

<ScrollView orientation="vertical">
        <GridLayout rows="30, 300, 30, 300, 30, 300" >

Worked great.

0
Stan
Top achievements
Rank 1
answered on 07 Oct 2017, 01:11 AM

Follow-up problem with images not showing in Android:

My following code all works as expected in iOS but not in Android. So I thought using the nativescript-fresco module would help but it does not and the fresco code is causing problems with iOS now.

Please help. Thanks so much!

package.json

{
  "description": "NativeScript Application",
  "license": "SEE LICENSE IN <your-license-filename>",
  "readme": "NativeScript Application",
  "repository": "<fill-your-repository-here>",
  "nativescript": {
    "id": "org.nativescript.BeerWine",
    "tns-ios": {
      "version": "3.1.0"
    },
    "tns-android": {
      "version": "3.1.1"
    }
  },
  "dependencies": {
    "nativescript-fresco": "^3.0.6",
    "nativescript-telerik-ui": "^3.0.4",
    "nativescript-theme-core": "~1.0.2",
    "tns-core-modules": "~3.1.0"
  },
  "devDependencies": {
    "babel-traverse": "6.25.0",
    "babel-types": "6.25.0",
    "babylon": "6.17.4",
    "lazy": "1.0.11"
  }
}

app.js

require("./bundle-config");
var application = require("application");
var fresco = require("nativescript-fresco");
if (application.android) {
        application.on("launch", function () {
        fresco.initialize();
    });
}
application.start({ moduleName: "main-page" });

main-page.xml

<Page xmlns="http://schemas.nativescript.org/tns.xsd" xmlns:nfd="nativescript-fresco" xmlns:lv="nativescript-telerik-ui/listview" loaded="onPageLoaded">
    <ActionBar title="Liquor Store"/>

        <ScrollView orientation="vertical">
        <GridLayout rows="30, 200, 30, 200, 30, 200" >
            <Label row="0" text="Beers" height="30" style.backgroundColor="yellow" class="banner"/>
            <lv:RadListView row="1" id="beerList" items="{{ myBeerItems }}" selectionBehavior="Press" itemSelected="beerItemSelected">
                <lv:RadListView.listViewLayout>
                    <lv:ListViewLinearLayout scrollDirection="Horizontal" itemHeight="200" itemWidth="200"/>
                </lv:RadListView.listViewLayout>
                <lv:RadListView.itemTemplate>
                    <StackLayout orientation="horizontal">
                        <nfd:FrescoDrawee width="200" height="200" loadMode="async" decodeWidth="200" decodeHeight="200" imageUri="{{ myBeers }}"/>
                    <!--    <Image id="beers" src="{{ myBeers }}" decodeWidth="200" decodeHeight="200" loadMode="async" height="200" width="200" />  -->
                    </StackLayout>
                </lv:RadListView.itemTemplate>
            </lv:RadListView>

            <Label row="2" text="Wines" height="30" style.backgroundColor="yellow" class="banner"/>
            <lv:RadListView row="3" id="wineList" items="{{ myWineItems }}" selectionBehavior="Press" itemSelected="wineItemSelected">
                <lv:RadListView.listViewLayout>
                    <lv:ListViewLinearLayout scrollDirection="Horizontal" itemHeight="200" itemWidth="200"/>
                </lv:RadListView.listViewLayout>
                <lv:RadListView.itemTemplate>
                    <StackLayout orientation="horizontal">
                        <Image id="wines" src="{{ myWines }}" decodeWidth="200" decodeHeight="200" loadMode="async" height="200" width="200" />
                    </StackLayout>
                </lv:RadListView.itemTemplate>
            </lv:RadListView>

            <Label row="4" text="Whiskies" height="30" style.backgroundColor="yellow" class="banner"/>
            <lv:RadListView row="5" id="whiskyList" items="{{ myWhiskyItems }}" selectionBehavior="Press" itemSelected="whiskyItemSelected">
                <lv:RadListView.listViewLayout>
                    <lv:ListViewLinearLayout scrollDirection="Horizontal" itemHeight="200" itemWidth="200"/>
                </lv:RadListView.listViewLayout>
                <lv:RadListView.itemTemplate>
                    <StackLayout orientation="horizontal">
                        <Image id="whisky" src="{{ myWhiskies }}" decodeWidth="200" decodeHeight="200" loadMode="async" height="200" width="200" />
                    </StackLayout>
                </lv:RadListView.itemTemplate>
            </lv:RadListView>
        </GridLayout>
        </ScrollView>
</Page>

main-page.js

var fs = require("file-system");
var frameModule = require("ui/frame");
var observable = require("data/observable");
var ObservableArray = require("data/observable-array").ObservableArray;

var myBeerImages = new ObservableArray();
var myWineImages = new ObservableArray();
var myWhiskyImages = new ObservableArray();
var viewModel = new observable.Observable();
    viewModel.set("myBeerItems", myBeerImages);
    viewModel.set("myWineItems", myWineImages);
    viewModel.set("myWhiskyItems", myWhiskyImages);

function readBeerFiles() {
    var beerDocuments = fs.knownFolders.currentApp();
    var myBeerFolder = beerDocuments.getFolder("beers");
    var beerArray = myBeerFolder.getEntitiesSync();
    myBeerImages = new ObservableArray();  // clear out array before reloading it
    beerArray.forEach(function (element) {
        myBeerImages.push({myBeers: element._path});
    });
    viewModel.set("myBeerItems", myBeerImages);  // reset viewModel with new array
}

function readWineFiles() {
    var wineDocuments = fs.knownFolders.currentApp();
    var myWineFolder = wineDocuments.getFolder("wines");
    var wineArray = myWineFolder.getEntitiesSync();
    myWineImages = new ObservableArray();  // clear out array before reloading it
    wineArray.forEach(function (element) {
        myWineImages.push({myWines: element._path});
    });
    viewModel.set("myWineItems", myWineImages);  // reset viewModel with new array
}

function readWhiskyFiles() {
    var whiskyDocuments = fs.knownFolders.currentApp();
    var myWhiskyFolder = whiskyDocuments.getFolder("whiskies");
    var whiskyArray = myWhiskyFolder.getEntitiesSync();
    myWhiskyImages = new ObservableArray();  // clear out array before reloading it
    whiskyArray.forEach(function (element) {
        myWhiskyImages.push({myWhiskies: element._path});
    });
    viewModel.set("myWhiskyItems", myWhiskyImages);  // reset viewModel with new array
}

exports.beerItemSelected = function(arg) {
    var selectedItem = myBeerImages.getItem(arg.index);
    var detailPic = selectedItem.myBeers
    frameModule.topmost().navigate({
        moduleName: "detail-page",
        bindingContext: {detailPic}
    });  
}

exports.wineItemSelected = function(arg) {
    var selectedItem = myWineImages.getItem(arg.index);
    var detailPic = selectedItem.myWines
    frameModule.topmost().navigate({
        moduleName: "detail-page",
        bindingContext: {detailPic}
    });  
}

exports.whiskyItemSelected = function(arg) {
    var selectedItem = myWhiskyImages.getItem(arg.index);
    var detailPic = selectedItem.myWhiskies
    frameModule.topmost().navigate({
        moduleName: "detail-page",
        bindingContext: {detailPic}
    });  
}

var beerList;
var wineList;
var whiskyList;
exports.onPageLoaded = function(args) {
    readBeerFiles();
    readWineFiles();
    readWhiskyFiles();
    var page = args.object;
    beerList = page.getViewById("beerList");
    wineList = page.getViewById("wineList");
    whiskyList = page.getViewById("whiskyList");
    page.bindingContext = viewModel;
}

detail-page.xml

<Page navigatingTo="onNavigatingTo">
    <ActionBar title="">
        <NavigationButton text="Go Back" />
    </ActionBar>    
    <Image src="{{ detailPic }}" stretch="aspectFill"/>
</Page>

detail-page.xml

<Page navigatingTo="onNavigatingTo">
    <ActionBar title="">
        <NavigationButton text="Go Back" />
    </ActionBar>    
    <Image src="{{ detailPic }}" stretch="aspectFill"/>
</Page>

detail-page.js (not needed or used here)

0
Nikolay Tsonev
Telerik team
answered on 09 Oct 2017, 06:58 AM
Stan,

Thank you for contacting us and for the attached sample code.

I tested the code in a sample project, however, the images seem to be shown properly while using the default ImageView provided by the -core-modules and the latest version of -pro- 3.1.4 on Android simulator API level 25 and 23.

For your convenience, I am attaching sample project and gif file from the simulator. Please review the sample project and make the needed changes, which will allow us to debug the problem on our side.

In the meantime you could try upgrading the version of -pro- to 3.1.4, deleting node_modules and platforms folders and rebuilding the project.


Regards,
nikolay.tsonev
Progress Telerik
Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
0
Stan
Top achievements
Rank 1
answered on 10 Oct 2017, 12:04 AM

Thank you so much for your project zip file.

After some testing with different Android emulators and API levels, here is what I'm getting now. Please see attached.

API level 25 is definitely better than 23, but there is still some very bad issues. It seems the breaking point is when there is about six images in each folders (categories) specially when the images are large files. 

Thanks in advance.

0
Accepted
Nikolay Tsonev
Telerik team
answered on 10 Oct 2017, 09:04 AM
Hello Stan,

Thank you for the attached images, which shows the problem. 
We investigated this case and found that this is something related to the native part of the application and it is not connected with the NativeScript abstraction.

I found that some of the images provided in the sample app are large and they will be loaded properly on the latest API level, however, it will lead to an issue while showing it on the lower ones. This behavior with showing a blurred image or black one instead of the original is related to the fact that the image is too big for Android and it goes out of memory.  More about this topic could be found here in this StackOverflow thread.

Regarding that, I would suggest resizing the images, which are set up in the application into a smaller size.


Regards,
nikolay.tsonev
Progress Telerik
Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
Tags
ListView
Asked by
Stan
Top achievements
Rank 1
Answers by
Nick Iliev
Telerik team
Stan
Top achievements
Rank 1
Deyan
Telerik team
Nikolay Tsonev
Telerik team
Share this question
or