Michael Eden
Michael Eden

Reputation: 1008

How to find/watch the dimensions of a view in a NativeScript layout?

When my layout loads any view inside of it has a width and height of NaN, it also has a getMeasuredHeight() and getMeasuredWidth() of 0.

At some point getMeasuredHeight() and getMeasuredWidth() (after the layout is laid out I guess) receive useful values.

How can I get the dimensions of anything? How can I watch them change?? When will .width and .height ever not be NaN??? Why can't I make a view hover over the entire screen????

So far I've been polling every 100ms and I feel pretty dumb. Please help.

Upvotes: 20

Views: 15272

Answers (8)

Aden Kurmanov
Aden Kurmanov

Reputation: 107

This code works for me

this.webView.on(WebView.loadedEvent, () => {
  this.webView.on(WebView.layoutChangedEvent, () => {
    this.size = this.webView.getActualSize();
    console.log("size: ", this.size);
  });
});

Upvotes: 0

odiaz
odiaz

Reputation: 241

Use the correct import:

const platform = require("platform")

or if you are using

import {screen} from "platform"
//or import {screen} from "tns-core-modules/platform/platform"

then you can use it depending on your language like this :

Typescript:

screen.mainScreen.widthDIPs //for example : 640
screen.mainScreen.widthPixels
screen.mainScreen.heightDIPs
screen.mainScreen.heightPixels

mainScreen implements the ScreenMetrics interface allowing access to the different screen sizes.

JS:

platform.screen.mainScreen.widthDIPs //for example : 640
platform.screen.mainScreen.widthPixels
platform.screen.mainScreen.heightDIPs
platform.screen.mainScreen.heightPixels

NOTE: this properties are the dimensions of the mobile device screen.

Upvotes: 16

Gabriel Cséfalvay
Gabriel Cséfalvay

Reputation: 538

It is possible to watch for the layoutChanged event of View. It is fired every time the layout process is done incl. view resize

myView.on("layoutChanged", function(){
    console.log("layout change");
});

Upvotes: 6

Jesse Crossen
Jesse Crossen

Reputation: 6995

You can use layoutChangedEvent to respond to the view being resized. If your view is called view, something like the following should do the trick:

import { View } from "ui/core/view";
import { EventData } from 'data/observable';

// ...

view.on(View.layoutChangedEvent, (e:EventData) => {
  const size = view.getActualSize();
  // ... do something with the size
});

Upvotes: 2

Sagar1911
Sagar1911

Reputation: 113

you can try view.getActualSize().width/height on navigatedTo event. only on this event you can get the actual height/width of a layout/view

you can refer here

Upvotes: 9

EricRobertBrewer
EricRobertBrewer

Reputation: 1762

How can I watch them change??

You can configure some variables when the device rotates, too:

in Angular2:

import { Component, OnInit, OnDestroy, NgZone } from "@angular/core";
import * as application from "application";

@Component({
    ...
})
export class MyComponent implements OnInit, OnDestroy {

    ngOnInit() {
        this.setIsScreenWide();
        application.on(application.orientationChangedEvent, this.onOrientationChanged, this);
    }

    isScreenWide: boolean;

    setIsScreenWide() {
        let widthDIPs = screen.mainScreen.widthDIPs;
        this.isScreenWide = widthDIPs >= 480;
    }

    onOrientationChanged = (args: application.OrientationChangedEventData) => {
        this.zone.run(() => {
            setTimeout(() => {
                this.setIsScreenWide();
            }, 17 /* one frame @ 60 frames/s, no flicker */);
        });
    };

    ngOnDestroy() {
        application.off(application.orientationChangedEvent, this.onOrientationChanged, this);
    }

    ...
}

Upvotes: 2

terreb
terreb

Reputation: 1467

When NS fires loaded event for a view, it has not been rendered at this point yet. That's why all your views inside have 0 height and width. You can workaround by waiting for sometime and than try to get the view dimensions. Add this to your loaded function:

var height = 0

function checkIfViewRendered() {
    setTimeout(function() {
        height = view.getMeasuredHeight()
    }, 100)
    if (height === 0) checkIfViewRendered()
    else console.log('rendered height is', height)
}

checkIfViewRendered()

Hope this helps.

Upvotes: 4

talpaz
talpaz

Reputation: 2006

you can subscribe to the navigatedTo event of the page, that seems to occur after the view has been laid out. There the getMeasuredHeight() and getMeasuredWidth() methods should return a value.

In the xml file add:

<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded" navigatedTo="{{ navigated }}">
<DockLayout id="mainLayout">
...
</DockLayout>

In the ts file add the matching method:

public navigated(args:EventData){
        alert ("My view height is " + this.myView.getMeasuredHeight());
    }

and in the pageLoaded event link myViewto your view:

public pageLoaded(args: EventData) {
    this.page = <Page>args.object;
    this.page.bindingContext = this;
    this.myView = <DockLayout>this.page.getViewById("mainLayout");        
}

Hope this helps.

Stefano

Upvotes: 1

Related Questions