RadListView on Android (NS 2.5.1) - tap to detail and back will always back to top of list

Thread is closed for posting
2 posts, 1 answers
  1. Clarence
    Clarence avatar
    20 posts
    Member since:
    Nov 2016

    Posted 21 Feb 2017 Link to this post

    Hi,

    I found an issue on RadListView on Android that when click on an item and navigated to a detail page, when click back, it will scroll back to the top of the list. The expected behavior is that it should stay on where I clicked the item.

    Versions:

    • NativeScript UI Pro: 1.6.0_063
    • NativeScript 2.5.1
    • TNS Core Module: 2.5.1

    Steps to reproduce:

    • Clone the nativescript-ui angular sample project (https://github.com/telerik/nativescript-ui-samples-angular.git)
    • Run "tns update" to update to tns-core-modules 2.5.1
    • In the listview load on demand sample (nativescript-ui-samples-angular/sdkAngular/app/listview/load-on-demand/listview-load-on-demand.component.android.html), add a tap action to navigate to a simple detail page:
    <template tkListItemTemplate let-item="item">
        <StackLayout class="itemTemplateStackLayout" orientation="vertical" (tap)="listviewDetailTap()">
    • In the component (nativescript-ui-samples-angular/sdkAngular/app/listview/load-on-demand/listview-load-on-demand.component.ts), add the code to handle the tap and route to the detail component (router is of RouterExtensions)
    listviewDetailTap() {
        console.log(`Listview detail tapped`);
        this.router.navigate(["listviewdetail"]);
    }
    • Modify app.component.ts to add the route to the ListviewDetailComponent (just a simple component will some static content)
    • Run the project on Android emulator
    • Open the RadListView Load on Demand sample, scroll to the bottom, and then click on the item. It will display the detail page. When click back button on Android emulator, it will go back to the list view page. However, it will always scroll back to the top of the list, not the position where I clicked the item.
    • The issue doesn't exists on iOS

    Kindly advice and thanks

    Clarence

  2. Answer
    Nikolay Tsonev
    Admin
    Nikolay Tsonev avatar
    340 posts

    Posted 21 Feb 2017 Link to this post

    Hello,
    Thank you for reporting this issue.

    I reviewed your scenario, unfortunately, I have to confirm this is a real issue, which has been already logged in this issue in nativescript-telerik-ui repo. For further info about this behavior and fix you could keep track on the issue.

    Regard to that as a workaround, you could use application-settings modules and RadListView scrollToIndex method, which allows you to scroll to the needed index of the ListView. For you convenience, I am attaching  sample code based on load on demand sample (nativescript-ui-samples-angular/sdkAngular/app/listview/load-on-demand .

    HTML
    <GridLayout tkExampleTitle tkToggleNavButton>
        <RadListView (loaded)="onLoaded($event)" id="listviewid" [items]="dataItems" loadOnDemandMode="Manual" (loadMoreDataRequested)="onLoadMoreItemsRequested($event)" (itemTap)="onItemTap($event)">
            <template tkListItemTemplate let-item="item">
                <StackLayout class="itemTemplateStackLayout" orientation="vertical">
                    <StackLayout class="innerOtemTemplateStackLayout" orientation="horizontal" >
                        <FrescoDrawee height="100" width="80" [imageUri]="item.image"></FrescoDrawee>
                        <StackLayout class="labelsStackLayout" orientation="vertical" >
                            <Label class="labelName" [text]="item.name"></Label>
                            <Label class="labelTitle" [text]="item.title" textWrap="true"></Label>
                            <Label class="labelText" [text]="item.text" textWrap="true"></Label>
                        </StackLayout>
                    </StackLayout>
                </StackLayout>
            </template>
        </RadListView>
    </GridLayout>

    TypeScript
    import { Component, OnInit, ChangeDetectorRef } from "@angular/core";
    import { PlatformLocation } from "@angular/common";
    import { Router, Event, NavigationExtras } from "@angular/router";
    import { ObservableArray } from "data/observable-array";
    import { DataItem } from "../dataItem";
    import { ListViewLinearLayout, ListViewEventData, RadListView, ListViewLoadOnDemandMode }from "nativescript-telerik-ui-pro/listview";
    import * as applicationModule from "application";
    import * as Timer  from "timer";
    var posts = require("../../listview/posts.json");
    import {setNumber, getNumber} from "application-settings";
    import {isAndroid} from "platform";
    import {Page} from "ui/page"
     
    @Component({
        moduleId: module.id,
        selector: "tk-listview-load-on-demand",
        templateUrl: "listview-load-on-demand.component.html",
        styleUrls: ["listview-load-on-demand.component.css"]
    })
    // >> angular-listview-load-on-demand-code
    export class ListViewLoadOnDemandComponent implements OnInit {
        private _dataItems: ObservableArray<DataItem>;
        private _numberOfAddedItems;
        private _layout: ListViewLinearLayout;
     
        constructor(private _changeDetectionRef: ChangeDetectorRef, private router:Router, private page:Page, location: PlatformLocation) {
             location.onPopState(() => {
            });
        }
     
        ngOnInit() {
            this.layout = new ListViewLinearLayout();
            this.layout.scrollDirection = "Vertical";
            this.layout.itemHeight = 120;
            this.initDataItems();
            // this._changeDetectionRef.detectChanges();
        }
     
        public get dataItems(): ObservableArray<DataItem> {
            return this._dataItems;
        }
     
        public get layout(): ListViewLinearLayout {
            return this._layout;
        }
     
        public set layout(value: ListViewLinearLayout) {
            this._layout = value;
        }
     
        public onLoadMoreItemsRequested(args: ListViewEventData) {
            var that = new WeakRef(this);
            Timer.setTimeout(function () {
                var listView: RadListView = args.object;
                var initialNumberOfItems = that.get()._numberOfAddedItems;
                for (var i = that.get()._numberOfAddedItems; i < initialNumberOfItems + 2; i++) {
                    if (i > posts.names.length - 1) {
                        listView.loadOnDemandMode = ListViewLoadOnDemandMode[ListViewLoadOnDemandMode.None];
                        break;
                    }
     
                    var imageUri = applicationModule.android ? posts.images[i].toLowerCase() : posts.images[i];
                    that.get()._dataItems.push(new DataItem(i, posts.names[i], "This is item description", posts.titles[i], posts.text[i], "res://" + imageUri));
                    that.get()._numberOfAddedItems++;
                }
     
                listView.notifyLoadOnDemandFinished();
            }, 1000);
            args.returnValue = true;
        }
     
        private initDataItems() {
            this._dataItems = new ObservableArray<DataItem>();
            this._numberOfAddedItems = 0;
            for (var i = 0; i < posts.names.length - 15; i++) {
                this._numberOfAddedItems++;
                if (applicationModule.android) {
                    this._dataItems.push(new DataItem(i, posts.names[i], "This is item description", posts.titles[i], posts.text[i], "res://" + posts.images[i].toLowerCase()));
                }
                else {
                    this._dataItems.push(new DataItem(i, posts.names[i], "This is item description", posts.titles[i], posts.text[i], "res://" + posts.images[i]));
                }
            }
     
            
             
        }
     
        onItemTap(args:ListViewEventData) {
            setNumber("position", args.itemIndex);
            console.log(`Listview detail tapped`);
            this.router.navigate(["listviewdetail"]);
        }
     
        onLoaded(args){
                if(isAndroid){
                var number = getNumber("position");
                console.log("index "+number);
                args.object.scrollToIndex(number);
                }
        }
    }


    The most important part of the code are onItemTap and  onLoaded, where we save selected position and scroll back to it.
    Regards,
    nikolay.tsonev
    Telerik by Progress
    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.
Back to Top