Nativescript以编程方式滚动到ScrollView的底部

时间:2018-07-04 23:18:25

标签: nativescript angular2-nativescript

在我的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的底部。


一些注意事项:

我通过此方法将文本添加到关联组件类中的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);
    }
}

(此尝试基于here

的解释

我只能在Android设备上尝试过此操作,因为我无法访问Apple设备。

2 个答案:

答案 0 :(得分:4)

您将TextView设置为固定高度100%,这与ScrollView相同,这就是scrollableHeight始终为0的原因。您应该使用minHeight="100%"。 / p>

然后,当您将文本追加到终端文本this.terminalText += appendStr时,可以通过编程方式滚动到末尾。

像这样

public appendToTerminal(appendStr){
    this.terminalText += appendStr;
    setTimeout(()=>{
        scrollView.scrollToVerticalOffset(scrollView.scrollableHeight, false);

    },150);
}

这将附加文本,然后获取scrollableHeight,然后滚动至该文本。

这是工作场演示:https://play.nativescript.org/?template=play-ng&id=Rs0xnP&v=16

答案 1 :(得分:0)

下面的函数只能在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中)。这就是为什么在滚动之前必须使用new测试当前内容的原因:

// 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;

        }

    }

}