Hello,
I am running into an issue when using the scrollToIndex function to scroll to the bottom. In android it works fine, but in iOS, the list does not reach the bottom.
The _initialize() function is called when the page is initialized.
@ViewChild('radListView') listViewComponent: RadListViewComponent;
private _initialize() {
this.showLoading(true);
if (this.otherUser.id === this.messageManagerService.getCurrentUser().id) {
this.routerExtensions.backToPreviousPage();
} else {
this.messageManagerService.getMessageByReceiverId(1).subscribe(messages => {
this.messages = messages;
this._calculateDisplayDates();
this.scrollTo(messages.length - 1);
this.showLoading(false);
});
}
}
private scrollTo(index: number) {
setTimeout(() => {
this.listViewComponent.listView.scrollToIndex(index);
}, 0);
}
13 Answers, 1 is accepted
Thank you for the attached sample code.
I reviewed your scenario, however, It would help if you could provide some more info about your project and when the _initialize is called, whether this happened on ngOnInit or on some other event.
The problem could be related to the fact that the scrollToIndex is called too early when the items are not properly loaded to the screen. In regard to that, it would help if you could send as a sample project, where the problem could be reproduced locally.
Meanwhile, you could separate the code and to scroll to the needed position on ngAfterViewInit.
ngAfterViewInit(){
this.listViewComponent.listView.scrollToIndex(50);
}Let me know if I could assist you further.
Regards,
nikolay.tsonev
Progress Telerik
I am using a service to get the data items from a server, so I don't think I should put it on ngAfterViewInit.
Also, I believe the bug occurs because the items have dynamic height since it's a textview.
In this code sample, I put itemHeight="100" on the ListViewLinearLayout and it scrolls fine besides the fact the items should not all be that size.
Is there any way to set a dynamic height to itemHeight?
<
RadListView
#radListView
class
=
"messages-list"
[items]="messages"
row
=
"0"
col
=
"0"
backgroundColor
=
"transparent"
(itemLoading)="onItemLoading($event)"
pullToRefresh
=
"true"
(pullToRefreshInitiated)="onPullToRefreshInitiated($event)">
<
ListViewLinearLayout
tkListViewLayout
scrollDirection
=
"Vertical"
itemHeight
=
"100"
itemInsertAnimation
=
"Default"
itemDeleteAnimation
=
"Default"
></
ListViewLinearLayout
>
<
ng-template
tkListItemTemplate
let-item
=
"item"
let-i
=
"index"
>
<
StackLayout
>
<
StackLayout
*
ngIf
=
"item.displayDate"
>
<
Label
class
=
"display-date"
[text]="item.displayDate"></
Label
>
</
StackLayout
>
<
DockLayout
>
<
TextView
[dock]="item.isMe ? 'right' : 'left'"
class
=
"message"
[class.me]="item.isMe"
[class.last]="messages.length - 1 === i" [text]="item.text" [editable]=false [isUserInteractionEnabled]=false></
TextView
>
<
Label
></
Label
>
</
DockLayout
>
</
StackLayout
>
</
ng-template
>
</
RadListView
>
Regarding your first question, the idea for changing the place of the scrollToIndex method was to verify, whether the method is called after the items are loaded on the screen. In your case, when the data is loaded from a service on the subscribe method, just for the test you could set setTimeout with 100 milliseconds and verify, whether the Listview will be scrolled to the bottom.
private scrollTo(index: number) {
setTimeout(() => {
this.listViewComponent.listView.scrollToIndex(index);
}, 100);
}
Instead of setting the itemHeight for every item you could change the Layout of the RadListView to ListViewStaggeredLayout. With this Layout type defining an explicit item size is not needed since the essence of a staggered layout is that items are freely measured and positioned according to their desired size. For example:
<
RadListView
#radListView
class
=
"messages-list"
[items]="messages"
row
=
"0"
col
=
"0"
backgroundColor
=
"transparent"
(itemLoading)="onItemLoading($event)"
pullToRefresh
=
"true"
(pullToRefreshInitiated)="onPullToRefreshInitiated($event)">
<
lv:ListViewStaggeredLayout
scrollDirection
=
"Vertical"
spanCount
=
"1"
/>
<
ng-template
tkListItemTemplate
let-item
=
"item"
let-i
=
"index"
>
<
StackLayout
>
<
StackLayout
*
ngIf
=
"item.displayDate"
>
<
Label
class
=
"display-date"
[text]="item.displayDate"></
Label
>
</
StackLayout
>
<
DockLayout
>
<
TextView
[dock]="item.isMe ? 'right' : 'left'"
class
=
"message"
[class.me]="item.isMe"
[class.last]="messages.length - 1 === i" [text]="item.text" [editable]=false [isUserInteractionEnabled]=false></
TextView
>
<
Label
></
Label
>
</
DockLayout
>
</
StackLayout
>
</
ng-template
>
</
RadListView
>
For further info about the available Layouts review this article in the docs.
Hope this will help.
Regards,
nikolay.tsonev
Progress Telerik
Thanks for the quick replies.
Sorry, I forgot to mention it in the last post. But, I tried the setTimeout with delay of 1000 and it still didn't work.
This worked for me though, thank you.
<
ListViewStaggeredLayout
tkListViewLayout
spanCount
=
"1"
></
ListViewStaggeredLayout
>
If I understand you correctly, changing the ListView Layout to s
ListViewStaggeredLayout,
resolves the issue with the scrollToIndex method. Is that correct or the issue still exist on your side.Regards,
nikolay.tsonev
Progress Telerik
This is exactly what I've been looking for to fix my scrolling issue. A helpful note in the doc would say "use the ListViewStaggeredLayout in order for scrollToIndex() to work on iOS". Since it works fine on android without it, the behavior seems like a bug at first, even if that's not the case.
Maybe it's mentioned in the docs already and I just missed it.
This is exactly what I needed to fix my scrolling issue. Would be helpful if the docs mentioned that "you must use ListViewStaggeredLayout in order for scrollToIndex() to work correctly on iOS". Since it works on android, it seems like a bug at first, even if that's not the case.
Maybe it's already in the RadListView documentation and I just missed it.
Maybe it's already in the RadListView documentation and I just missed it.
If I understand you correctly, the scrollToIndex functionality works as expected on your side and the issue in the project is related to a bad request. Is that correct or you still have an issue with the RadListView component?
I would like to notice that you could also review our NativeScript nativescript-ui-samples and nativescript-ui-samples-angular applications, where are shown the whole functionality of the NativeScript UI Components.
Regards,
nikolay.tsonev
Progress Telerik
I don't have an issue now that I'm using the ListViewStaggeredLayout. Prior to that, on iOS the scrollToIndex() function wouldn't scroll to the correct location. It was just kind of an obscure solution since it worked fine on android without the ListViewStaggeredLayout.
I was just suggesting that something in the documentation for scrollToIndex() would be helpful to others in the future ("make sure you use the correct listview layout or this function won't work on iOS"). Otherwise it's not really clear until one stumbles upon this forum post.
Thanks for the help!
Thank you for your suggestion, we will add this additional info in the documentation.
Regards,
nikolay.tsonev
Progress Telerik