Android onMeasure not called


#1

Hi all. I have a class that extends GridLayout and overrides the onMeasure method. On iOS this method is called, but on Android it is not. Any insight? Thanks!


#2

I’m actually struggling with the entire layout system at this point… On iOS we get onMeasure and onLayout callbacks, which gives us a chance to layout subviews once a view is correctly measured. On Android these callbacks aren’t fired. What’s the correct point for laying out subviews on both platforms?

Also, on iOS I can add a layout trace and get a wealth of debugging info:

trace.setCategories(trace.categories.Layout)

But this doesn’t output anything on Android. Am I missing something?


#3

onMeasure method will not be executed in NativeScript while building the app for Android. This behavior is by design and this method will not do the job for you.
The best solution will be to create custom Layout by extending the native classes for Android as well as for iOS.
You could review and reuse the code from tns-core-modules(iOS, Android) by creating your custom Layout and include the needed functionality.
To be able to reuse your code in other applications you could also create NativeScript plugin. For more help, you could also review the attached link, where has been described, how to create UI plugin.
http://docs.nativescript.org/plugins/ui-plugin
http://docs.nativescript.org/plugins/plugins


About your second comment, to be able to debugged Layouts for Android, you should open <app_name>/app/App_Resources/AndroidManifest.xml file and to include <meta-data android:name="debugLayouts" android:value="true"/> tag. For example

application
		android:name="com.tns.NativeScriptApplication"
		android:allowBackup="true"
		android:icon="@drawable/icon"
		android:label="@string/app_name"
		android:theme="@style/AppTheme">
		<meta-data android:name="debugLayouts" android:value="true"/>
		<activity
			android:name="com.tns.NativeScriptActivity"
			android:label="@string/title_activity_kimera"
			android:configChanges="keyboardHidden|orientation|screenSize"
			android:theme="@style/LaunchScreenTheme">

			<meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />
			

			<intent-filter>
				<action android:name="android.intent.action.MAIN" />
				<category android:name="android.intent.category.LAUNCHER" />
			</intent-filter>
		</activity>
		<activity android:name="com.tns.ErrorReportActivity"/>
	</application>

Before rebuilding the app, delete platforms folder and run adb logcat and build the project with tns run android


#4

Thanks for the response!

Creating a custom layout sounds a little heavy-handed for what we were trying to accomplish here. The existing layouts work well, we simply needed a hook for the moment after layout was complete.

What I did in the end was add a listener to the native android layout event:

let androidLayoutObservable = new Observable();

export class CustomView extends GridLayout {

    onLoaded() {
        super.onLoaded();
        if (this.android) {
            this.android.addOnLayoutChangeListener(new android.view.View.OnLayoutChangeListener({
                onLayoutChange(v: android.view.View, left: number, top: number, right: number, bottom: number, oldLeft: number, oldTop: number, oldRight: number, oldBottom: number): void {
                    var eventData: observableModule.EventData = {
                        eventName: "customLayoutChange",
                        object: androidLayoutObservable
                    }
                    androidLayoutObservable.notify(eventData);
                }
            }));
            androidLayoutObservable.on("customLayoutChange", ()=>{
                this.androidOnLayout();
            })
        }
    }

    ...
}

I do feel like the NativeScript layout documentation is misleading: https://docs.nativescript.org/ui/layouts

This makes it sound like iOS and Android use the same layout system. I might suggest exposing the android onMeasure and onLayout callbacks in the common interface.

Thanks for the tip on debugging Android layouts, I’m sure that’ll come in handy!