Nativescript прокручивает вниз ScrollView программно - PullRequest
0 голосов
/ 05 июля 2018

В моем приложении Nativescript Angular у меня есть TextView в ScrollView, определенный как:

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

Цель этого элемента - действовать как терминал и быстро распечатывать входящие сообщения с устройства Bluetooth.

В настоящее время ScrollView прокручивается обратно к вершине всякий раз, когда я добавляю некоторый текст в переменную terminalText, к которой привязан TextView. Я хотел бы иметь возможность держать 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);
    }
}

(Эта попытка основана на объяснении, данном здесь

Я пробовал это только на устройстве Android, так как у меня нет доступа к устройству Apple.

Ответы [ 2 ]

0 голосов
/ 15 марта 2019

Следующая функция может использоваться только в жизненном цикле 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;

}

Высота прокрутки может быть нулевой на первом проходе жизненного цикла (например, если вы добавляете элементы в ScrollView с помощью HTTP-запроса). Вот почему вы должны проверить текущий контент с новым перед прокруткой:

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

        }

    }

}
0 голосов
/ 06 июля 2018

вы устанавливаете 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

...