NativeScript:Scrollableheight 始终为 0
NativeScript: Scrollableheight is always 0
我进行了聊天,我正在尝试实现的功能是聊天应始终滚动到最后一条消息。
html:
<ActionBar>
<NavigationButton (tap)="onBackTap()" android.systemIcon="ic_menu_back"></NavigationButton>
<Label [text]="user.name"></Label>
</ActionBar>
<ScrollView #scrollLayout style="height: 80%;margin-top: -200px">
<ListView class="chat-body" [items]="messages" separatorColor="transparent" style="min-height:100%" >
<ng-template let-message="item" let-odd="odd" let-even="even">
<GridLayout rows ="auto, *">
<Label style="padding-right:150px" *ngIf="message.sender == me" horizontalAlignment="right" class="chat-message-me" [text]="message.msg" textWrap="true"></Label>
<Label *ngIf="message.sender == me" horizontalAlignment="right" class="chat-timestamp" verticalAlignment="bottom" [text]="message.time"></Label>
<Label style="padding-left:170px" *ngIf="message.sender != me" horizontalAlignment="left" class="chat-message-you" [text]="message.msg" textWrap="true"></Label>
<Label *ngIf="message.sender != me" horizontalAlignment="left" verticalAlignment="bottom" class="chat-timestamp" [text]="message.time"></Label>
</GridLayout>
</ng-template>
</ListView>
</ScrollView>
<StackLayout class="nt-form chat-wrapper" >
<StackLayout loaded="test" id="chat-form" orientation="horizontal" class="nt-input input-field form">
<TextField
(textChange)="onTextChange($event)"
[text]="inputText"
width="800px"
class="-rounded-lg input"
hint="Nachricht"
style="background-color: #ffffff;"
></TextField>
<button width="120px" class="-rounded-lg fa far fas fab" (tap)="sendMessage();" style="margin-left: 15px;" text=""></button>
</StackLayout>
</StackLayout>
ts:
@Component({
selector: "ItemDetail",
styleUrls: ['item-detail.component.css'],
templateUrl: "./item-detail.component.html",
providers: [DatePipe]
})
export class ItemDetailComponent implements OnInit {
@ViewChild('scrollLayout') scrollen: ElementRef;
constructor(){}
ngOnInit(): void {
}
ngAfterViewInit(): void{
setTimeout(()=> {
var scroller = this.scrollen.nativeElement.scrollableHeight
console.log("height", scroller)
this.scrollen.nativeElement.scrollToVerticalOffset(this.scrollen.nativeElement.scrollableHeight, false);
}, 1000);
}
看起来像这样:
但应该是这样的(向下滚动):
NgAfterViewInit 的控制台日志总是“高度 0”所以它告诉我 ListView 是 0?
我怎样才能让它以编程方式向下滚动?
我认为问题在于 ListView
嵌套在 ScrollView
中。 ListView
默认情况下已经带有滚动行为,因此您不需要将其嵌套在 ScrollView
.
中
<ListView class="chat-body" [items]="messages" separatorColor="transparent" style="min-height:100%">
<ng-template let-message="item" let-odd="odd" let-even="even">
<GridLayout rows ="auto, *">
<Label style="padding-right:150px" *ngIf="message.sender == me" horizontalAlignment="right" class="chat-message-me" [text]="message.msg" textWrap="true"></Label>
<Label *ngIf="message.sender == me" horizontalAlignment="right" class="chat-timestamp" verticalAlignment="bottom" [text]="message.time"></Label>
<Label style="padding-left:170px" *ngIf="message.sender != me" horizontalAlignment="left" class="chat-message-you" [text]="message.msg" textWrap="true"></Label>
<Label *ngIf="message.sender != me" horizontalAlignment="left" verticalAlignment="bottom" class="chat-timestamp" [text]="message.time"></Label>
</GridLayout>
</ng-template>
</ListView>
滚动到底部
而不是 ngAfterViewInit
,我们可以使用 ListView
s 加载事件来确保列表视图已加载并准备好滚动。
<ListView (loaded)="listViewLoaded($event)"
class="chat-body" [items]="messages" separatorColor="transparent" style="min-height:100%">
...
</ListView>
listViewLoaded(args: EventData) {
const listView = args.object as ListView;
const lastIndex = this.messages.length - 1;
// you might need a setTimeout here if it still fires too early
listView.scrollToIndex(lastIndex)
// or this if you want the scroll to be animated
listView.scrollToIndexAnimated(lastIndex)
}
我进行了聊天,我正在尝试实现的功能是聊天应始终滚动到最后一条消息。
html:
<ActionBar>
<NavigationButton (tap)="onBackTap()" android.systemIcon="ic_menu_back"></NavigationButton>
<Label [text]="user.name"></Label>
</ActionBar>
<ScrollView #scrollLayout style="height: 80%;margin-top: -200px">
<ListView class="chat-body" [items]="messages" separatorColor="transparent" style="min-height:100%" >
<ng-template let-message="item" let-odd="odd" let-even="even">
<GridLayout rows ="auto, *">
<Label style="padding-right:150px" *ngIf="message.sender == me" horizontalAlignment="right" class="chat-message-me" [text]="message.msg" textWrap="true"></Label>
<Label *ngIf="message.sender == me" horizontalAlignment="right" class="chat-timestamp" verticalAlignment="bottom" [text]="message.time"></Label>
<Label style="padding-left:170px" *ngIf="message.sender != me" horizontalAlignment="left" class="chat-message-you" [text]="message.msg" textWrap="true"></Label>
<Label *ngIf="message.sender != me" horizontalAlignment="left" verticalAlignment="bottom" class="chat-timestamp" [text]="message.time"></Label>
</GridLayout>
</ng-template>
</ListView>
</ScrollView>
<StackLayout class="nt-form chat-wrapper" >
<StackLayout loaded="test" id="chat-form" orientation="horizontal" class="nt-input input-field form">
<TextField
(textChange)="onTextChange($event)"
[text]="inputText"
width="800px"
class="-rounded-lg input"
hint="Nachricht"
style="background-color: #ffffff;"
></TextField>
<button width="120px" class="-rounded-lg fa far fas fab" (tap)="sendMessage();" style="margin-left: 15px;" text=""></button>
</StackLayout>
</StackLayout>
ts:
@Component({
selector: "ItemDetail",
styleUrls: ['item-detail.component.css'],
templateUrl: "./item-detail.component.html",
providers: [DatePipe]
})
export class ItemDetailComponent implements OnInit {
@ViewChild('scrollLayout') scrollen: ElementRef;
constructor(){}
ngOnInit(): void {
}
ngAfterViewInit(): void{
setTimeout(()=> {
var scroller = this.scrollen.nativeElement.scrollableHeight
console.log("height", scroller)
this.scrollen.nativeElement.scrollToVerticalOffset(this.scrollen.nativeElement.scrollableHeight, false);
}, 1000);
}
看起来像这样:
但应该是这样的(向下滚动):
NgAfterViewInit 的控制台日志总是“高度 0”所以它告诉我 ListView 是 0? 我怎样才能让它以编程方式向下滚动?
我认为问题在于 ListView
嵌套在 ScrollView
中。 ListView
默认情况下已经带有滚动行为,因此您不需要将其嵌套在 ScrollView
.
<ListView class="chat-body" [items]="messages" separatorColor="transparent" style="min-height:100%">
<ng-template let-message="item" let-odd="odd" let-even="even">
<GridLayout rows ="auto, *">
<Label style="padding-right:150px" *ngIf="message.sender == me" horizontalAlignment="right" class="chat-message-me" [text]="message.msg" textWrap="true"></Label>
<Label *ngIf="message.sender == me" horizontalAlignment="right" class="chat-timestamp" verticalAlignment="bottom" [text]="message.time"></Label>
<Label style="padding-left:170px" *ngIf="message.sender != me" horizontalAlignment="left" class="chat-message-you" [text]="message.msg" textWrap="true"></Label>
<Label *ngIf="message.sender != me" horizontalAlignment="left" verticalAlignment="bottom" class="chat-timestamp" [text]="message.time"></Label>
</GridLayout>
</ng-template>
</ListView>
滚动到底部
而不是 ngAfterViewInit
,我们可以使用 ListView
s 加载事件来确保列表视图已加载并准备好滚动。
<ListView (loaded)="listViewLoaded($event)"
class="chat-body" [items]="messages" separatorColor="transparent" style="min-height:100%">
...
</ListView>
listViewLoaded(args: EventData) {
const listView = args.object as ListView;
const lastIndex = this.messages.length - 1;
// you might need a setTimeout here if it still fires too early
listView.scrollToIndex(lastIndex)
// or this if you want the scroll to be animated
listView.scrollToIndexAnimated(lastIndex)
}