nativescriptangular2-nativescriptnativescript-telerik-uinativescript-angularnativescript-cli

Get the height of a generated view


I'm trying to get the height of a StackLayout. This layout is filled with data from my backend, so it's not always the same height. I tried view.getViewById(parent, selector).effectiveHeight, but it keeps outputting 0.

My XML file looks a bit like this:

<Page>
    <ActionBar title="..."></ActionBar>
    <GridLayout rows="*, auto" columns="*">
        <ScrollView row="0" col="0">
            <GridLayout rows="*" columns="*">
                <StackLayout id="TARGET" row="0" col="1">
                    <StackLayout *ngFor="let x of y">
                        <FlexboxLayout justifyContent="space-between">
                            <FlexboxLayout>
                                <StackLayout>
                                    ...
                                </StackLayout>
                            </FlexboxLayout>

                            <FlexboxLayout justifyContent="space-between">
                                ...
                            </FlexboxLayout>

                        </FlexboxLayout>
                    </StackLayout>   
                </StackLayout>
                <StackLayout col="0" row="0">
                    ...
                </StackLayout>
            </GridLayout>
        </ScrollView>

        <StackLayout row="1" col="0">
            ...
        </StackLayout>
    </GridLayout>
</Page>

Thank you in advance!


Solution

  • if you are using view.getViewById(parent, selector).effectiveHeight it will only work if view is rendered and loaded. even if you are trying to get values on loaded() event it will be 0 because of nativescript bug. To workaround this case I would suggest setting up timeout with 200 milliseconds. for example

    home.component.html

    <ListView [items]="a"  class="list-group">
        <ng-template let-country="item" let-i="index" let-odd="odd" let-even="even">
            <WrapLayout  width="100%"  orientation="horizontal" backgroundColor="palegreen">
                <StackLayout  #abc  (loaded)="getSize($event)" width="20%" [height]="testWidth" backgroundColor="lightgray">
                    <Label [text]="'W'+testWidth" backgroundColor="red"></Label>
                    <Label text="LA" backgroundColor="green"></Label>
                </StackLayout>
            </WrapLayout>
        </ng-template>
    </ListView>
    

    home.component.ts

    import { Component, OnInit, ViewChild } from "@angular/core";
    import { PercentLength } from "tns-core-modules/ui/styling/style-properties"
    import { StackLayout } from "ui/layouts/stack-layout"
    @Component({
        selector: "Home",
        moduleId: module.id,
        templateUrl: "./home.component.html",
        styleUrls: ['./home.component.css']
    })
    export class HomeComponent implements OnInit {
        a = ['1', '2', '1', '2', '1', '2', '1', '2', '1', '2', '1', '2', '1', '2', '1', '2', '1', '2', '1', '2', '1', '2', '1', '2', '1', '2', '1', '2', '1', '2',]
        @ViewChild('abc') abc;
        testWidth = 0;
        constructor() {
    
        }
        getSize(args) {
            setTimeout(() => {
                let stack= <StackLayout>args.object;
                var stackSize = args.object.getActualSize();
                var stackWidth = stackSize.width;
                var stackHeight = stackSize.height;
                console.log("stackWidth: " + stackWidth);
                console.log("stackHeight: " + stackHeight);
                this.testWidth = stackWidth;
            }, 200);
        }
        ngOnInit(): void {
        }
        toDevicePixels(percentage: PercentLength) {
            console.dir(PercentLength.convertToString(percentage))
            return PercentLength.toDevicePixels(percentage,0,0);
        }
    }
    

    The code sample also shows, how to get the height and width of the StackLayout dynamically and bind them to view.