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

Posted

技术标签:

【中文标题】Nativescript 以编程方式滚动到 ScrollView 的底部【英文标题】:Nativescript scroll to bottom of ScrollView programmatically 【发布时间】:2018-12-13 08:50:47 【问题描述】:

在我的 Nativescript Angular 应用程序中,我在 ScrollView 中有一个 TextView,定义如下:

<ScrollView orientation="vertical"   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"      
        (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 设备。

【问题讨论】:

在滚动视图加载时它是否工作? @bhavinjalodara 它正在工作 【参考方案1】:

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

然后,您可以在将文本附加到终端文本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

【讨论】:

试过你的方法,还是不行。我可能已经找到了原因 - 我记录了 scrollView 的值,它是 scrollableHeight ,虽然 scrollView 很好,但 scrollableHeight 始终设置为 0,即使我可以手动向下滚动页面也是如此。对此有何评论?我尝试将TextView 嵌入StackLayout,但也没有运气。 你能创建 Playground 演示吗?那我可以看看。 游乐场链接:play.nativescript.org/?template=play-ng&id=Rs0xnP 万一有人得到仍然 0 作为 scrollableHeight。我不知道为什么,但没有 setTimeout 它不起作用。在 setTimeout cb 函数中处理可滚动的东西可以解决这个问题。 你也可以尝试在 NgZone 中运行它。【参考方案2】:

以下函数只能在 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;

        

    


【讨论】:

以上是关于Nativescript 以编程方式滚动到 ScrollView 的底部的主要内容,如果未能解决你的问题,请参考以下文章

NativeScript ScrollView 当组件打开时它会滚动到某个部分

如何在 Nativescript-vue 中以编程方式折叠 raddataform“组”

NativeScript Vue RadAutoCompleteTextView 以编程方式删除所有标记

以编程方式为 NativeScript Vue 中的标签设置“跨度”颜色在 FormattedString 中不起作用

如何在 nativescript 中进行水平轮播布局?

以编程方式滚动到 NestedScrollView 的顶部