NativeScript:Scrollableheight 始终为 0

时间:2021-05-24 06:16:54

标签: angular listview nativescript

我做了一个聊天,我想实现的功能是聊天应该总是滚动到最后一条消息。

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="&#xf1d8;"></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);     
    }

看起来像这样:

enter image description here

但应该是这样的(向下滚动):

enter image description here

NgAfterViewInit 中的控制台日志总是“高度 0”,所以它告诉我 ListView 是 0? 我怎样才能让它以编程方式向下滚动?

1 个答案:

答案 0 :(得分:1)

我认为问题在于在 ListView 中嵌套了 ScrollViewListView 已经默认带有滚动行为,因此您不需要将其嵌套在 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 的加载事件来确保列表视图已加载并准备好滚动。

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