I use a ScrollView for a Chat-Overview in NativeScript.
I used this code for the Scrollview until now:
<ScrollView #scrollLayout style="height: 80%;margin-top: -200px">
<StackLayout class="chat-body">
<StackLayout *ngFor="let message of messages" orientation="vertical">
<Label *ngIf="message.sender == me" horizontalAlignment="right" class="chat-message-me" [text]="message.msg"></Label>
<Label *ngIf="message.sender == me" horizontalAlignment="right" class="chat-timestamp" [text]="message.time"></Label>
<Label *ngIf="message.sender != me" horizontalAlignment="left" class="chat-message-you" [text]="message.msg"></Label>
<Label *ngIf="message.sender != me" horizontalAlignment="left" class="chat-timestamp" [text]="message.time"></Label>
</StackLayout>
</StackLayout>
</ScrollView>
It worked, but when i added a new element to the messages array the view would load the complete array on top of the already showing array.
Message Array:
View of Chat:
So my Solution was to use a ListView, like this:
<ScrollView #scrollLayout style="height: 80%;margin-top: -200px">
<GridLayout class="chat-body">
<ListView [items]="messages" orientation="vertical">
<ng-template let-item="message">
<Label *ngIf="message.sender == me" horizontalAlignment="right" class="chat-message-me" [text]="message.msg"></Label>
<Label *ngIf="message.sender == me" horizontalAlignment="right" class="chat-timestamp" [text]="message.time"></Label>
<Label *ngIf="message.sender != me" horizontalAlignment="left" class="chat-message-you" [text]="message.msg"></Label>
<Label *ngIf="message.sender != me" horizontalAlignment="left" class="chat-timestamp" [text]="message.time"></Label>
</ng-template>
</ListView>
</GridLayout>
</ScrollView>
But i get this Error:
System.err: An uncaught Exception occurred on "main" thread.
System.err: Calling js method getView failed
System.err: Error: No suitable views found in list template! Nesting level: 0
System.err:
A ListView
automatically scrolls, so you shouldn't need a ScrollView
parent.
The error you are seeing is because the ListView
requires a single component/layout inside it (where you have the 4 labels).
To fix the error you could wrap your labels inside a ContentView
or a layout like so:
<ListView [items]="messages" orientation="vertical">
<ng-template let-message="item">
<ContentView>
<Label *ngIf="message.sender == me" horizontalAlignment="right" class="chat-message-me" [text]="message.msg"></Label>
<Label *ngIf="message.sender == me" horizontalAlignment="right" class="chat-timestamp" [text]="message.time"></Label>
<Label *ngIf="message.sender != me" horizontalAlignment="left" class="chat-message-you" [text]="message.msg"></Label>
<Label *ngIf="message.sender != me" horizontalAlignment="left" class="chat-timestamp" [text]="message.time"></Label>
</ContentView>
</ng-template>
</ListView>
However, using ngIf
s inside a ListView
has some performance impacts. If possible, use multiple item templates instead. This blog post has some indepth comparison between the two approaches.