Nativescript 以编程方式滚动到 ScrollView 的底部
Nativescript scroll to bottom of ScrollView programmatically
在我的 Nativescript Angular 应用程序中,我在 ScrollView 中有一个 TextView,定义如下:
<ScrollView orientation="vertical" height="70%" width="100%" style="margin-bottom: 1%; background-color:white" (loaded)="onScrollerLoaded($event)">
<TextView
id="terminal" [text]="terminalText" editable="false"
style="color: whitesmoke; background-color: black; font-size: 8%; font-family: monospace" height="100%"
(tap)="onTap($event)" (loaded)="onTerminalLoaded($event)">
</TextView>
</ScrollView>
此元素的用途是充当终端,并快速打印来自蓝牙设备的传入消息。
目前,每当我向 TextView 绑定到的 terminalText
变量添加一些文本时,ScrollView 就会滚动回顶部。 我希望能够将 ScrollView 保持在 TextView 的底部。
一些注意事项:
我正在通过此方法向关联组件 class 中的 terminalText
变量添加文本:
public appendToTerminal(appendStr){
this.terminalText += appendStr;
}
我已经尝试实现以下代码,一旦 ScrollView 加载就会执行:
private scrollIntervalId;
onScrollerLoaded(data: EventData){
if(!this.scrollIntervalId){
this.scrollIntervalId = setInterval(()=>{
this.ngZone.run(() =>
(data.object as any).scrollToVerticalOffset((data.object as any).scrollableHeight, false)
)
}, 10);
}
}
(此尝试基于给出的解释
我只在 Android 设备上尝试过,因为我无法访问 Apple 设备。
您正在将 TextView
设置为固定高度 100%,这将与 ScrollView
相同,这就是为什么 scrollableHeight
将始终为 0。您应该使用 minHeight="100%"
.
然后您可以在将文本附加到终端文本时以编程方式滚动到末尾 this.terminalText += appendStr
。
像这样
public appendToTerminal(appendStr){
this.terminalText += appendStr;
setTimeout(()=>{
scrollView.scrollToVerticalOffset(scrollView.scrollableHeight, false);
},150);
}
这将附加文本,然后获取 scrollableHeight,然后滚动到它。
这里是 working playground 演示:https://play.nativescript.org/?template=play-ng&id=Rs0xnP&v=16
以下函数只能在Angular ngDoCheck() 或 ngAfterContentChecked() 生命周期中使用:
// See https://angular.io/guide/lifecycle-hooks
function goDownScrollView(scrollView: object, animate: boolean = true): boolean {
let neScrollView: ScrollView = <ScrollView>getNativeElement(scrollView),
scrollableHeight: number = neScrollView.scrollableHeight;
console.log("neScrollView:", neScrollView);
console.log("neScrollView scrollableHeight:", scrollableHeight);
if (scrollableHeight > 0) {
neScrollView.scrollToVerticalOffset(scrollableHeight, animate);
return true;
} else {
return false;
}
}
始终获取原生元素的助手:
function getNativeElement(object: object): object {
return (object.hasOwnProperty("nativeElement")) ? object['nativeElement'] : object;
}
在生命周期的第一次通过时,可滚动高度可能为零(例如,如果您使用 HTTP 请求向 ScrollView 添加元素)。这就是为什么你必须在滚动前用新的测试当前内容:
// See https://angular.io/api/core/ViewChild
@ViewChild("content") private _pageContent: ElementRef<ScrollView>;
public currentContent: object;
private _previousContent: object;
...
ngAfterContentChecked(): void {
if (this.currentContent != this._previousContent) {
let isScrollDown: boolean = goDownScrollView(this._pageContent);
if (isScrollDown) {
this._previousContent = this.currentContent;
}
}
}
在我的 Nativescript Angular 应用程序中,我在 ScrollView 中有一个 TextView,定义如下:
<ScrollView orientation="vertical" height="70%" width="100%" style="margin-bottom: 1%; background-color:white" (loaded)="onScrollerLoaded($event)">
<TextView
id="terminal" [text]="terminalText" editable="false"
style="color: whitesmoke; background-color: black; font-size: 8%; font-family: monospace" height="100%"
(tap)="onTap($event)" (loaded)="onTerminalLoaded($event)">
</TextView>
</ScrollView>
此元素的用途是充当终端,并快速打印来自蓝牙设备的传入消息。
目前,每当我向 TextView 绑定到的 terminalText
变量添加一些文本时,ScrollView 就会滚动回顶部。 我希望能够将 ScrollView 保持在 TextView 的底部。
一些注意事项:
我正在通过此方法向关联组件 class 中的 terminalText
变量添加文本:
public appendToTerminal(appendStr){
this.terminalText += appendStr;
}
我已经尝试实现以下代码,一旦 ScrollView 加载就会执行:
private scrollIntervalId;
onScrollerLoaded(data: EventData){
if(!this.scrollIntervalId){
this.scrollIntervalId = setInterval(()=>{
this.ngZone.run(() =>
(data.object as any).scrollToVerticalOffset((data.object as any).scrollableHeight, false)
)
}, 10);
}
}
(此尝试基于给出的解释
我只在 Android 设备上尝试过,因为我无法访问 Apple 设备。
您正在将 TextView
设置为固定高度 100%,这将与 ScrollView
相同,这就是为什么 scrollableHeight
将始终为 0。您应该使用 minHeight="100%"
.
然后您可以在将文本附加到终端文本时以编程方式滚动到末尾 this.terminalText += appendStr
。
像这样
public appendToTerminal(appendStr){
this.terminalText += appendStr;
setTimeout(()=>{
scrollView.scrollToVerticalOffset(scrollView.scrollableHeight, false);
},150);
}
这将附加文本,然后获取 scrollableHeight,然后滚动到它。
这里是 working playground 演示:https://play.nativescript.org/?template=play-ng&id=Rs0xnP&v=16
以下函数只能在Angular ngDoCheck() 或 ngAfterContentChecked() 生命周期中使用:
// See https://angular.io/guide/lifecycle-hooks
function goDownScrollView(scrollView: object, animate: boolean = true): boolean {
let neScrollView: ScrollView = <ScrollView>getNativeElement(scrollView),
scrollableHeight: number = neScrollView.scrollableHeight;
console.log("neScrollView:", neScrollView);
console.log("neScrollView scrollableHeight:", scrollableHeight);
if (scrollableHeight > 0) {
neScrollView.scrollToVerticalOffset(scrollableHeight, animate);
return true;
} else {
return false;
}
}
始终获取原生元素的助手:
function getNativeElement(object: object): object {
return (object.hasOwnProperty("nativeElement")) ? object['nativeElement'] : object;
}
在生命周期的第一次通过时,可滚动高度可能为零(例如,如果您使用 HTTP 请求向 ScrollView 添加元素)。这就是为什么你必须在滚动前用新的测试当前内容:
// See https://angular.io/api/core/ViewChild
@ViewChild("content") private _pageContent: ElementRef<ScrollView>;
public currentContent: object;
private _previousContent: object;
...
ngAfterContentChecked(): void {
if (this.currentContent != this._previousContent) {
let isScrollDown: boolean = goDownScrollView(this._pageContent);
if (isScrollDown) {
this._previousContent = this.currentContent;
}
}
}