diff --git a/tns-core-modules/utils/utils-common.ts b/tns-core-modules/utils/utils-common.ts index dc5eaee81..f32515f5a 100644 --- a/tns-core-modules/utils/utils-common.ts +++ b/tns-core-modules/utils/utils-common.ts @@ -58,17 +58,17 @@ export function convertString(value: any): any { export module layout { - var MODE_SHIFT = 30; - var MODE_MASK = 0x3 << MODE_SHIFT; + const MODE_SHIFT = 30; + const MODE_MASK = 0x3 << MODE_SHIFT; - export var UNSPECIFIED = 0 << MODE_SHIFT; - export var EXACTLY = 1 << MODE_SHIFT; - export var AT_MOST = 2 << MODE_SHIFT; + export const UNSPECIFIED = 0 << MODE_SHIFT; + export const EXACTLY = 1 << MODE_SHIFT; + export const AT_MOST = 2 << MODE_SHIFT; - export var MEASURED_HEIGHT_STATE_SHIFT = 0x00000010; /* 16 */ - export var MEASURED_STATE_TOO_SMALL = 0x01000000; - export var MEASURED_STATE_MASK = 0xff000000; - export var MEASURED_SIZE_MASK = 0x00ffffff; + export const MEASURED_HEIGHT_STATE_SHIFT = 0x00000010; /* 16 */ + export const MEASURED_STATE_TOO_SMALL = 0x01000000; + export const MEASURED_STATE_MASK = 0xff000000; + export const MEASURED_SIZE_MASK = 0x00ffffff; export function getMode(mode: number): string { switch (mode) { diff --git a/tns-core-modules/utils/utils.android.ts b/tns-core-modules/utils/utils.android.ts index c9f73467e..a75815bfa 100644 --- a/tns-core-modules/utils/utils.android.ts +++ b/tns-core-modules/utils/utils.android.ts @@ -1,8 +1,60 @@ -import { enabled as traceEnabled, write as traceWrite, categories as traceCategories, - messageType as traceMessageType, notifyEvent as traceNotifyEvent, isCategorySet } from "trace"; +import { + enabled as traceEnabled, write as traceWrite, categories as traceCategories, + messageType as traceMessageType, notifyEvent as traceNotifyEvent, isCategorySet +} from "trace"; export * from "./utils-common"; +export module layout { + let density = -1; + let metrics: android.util.DisplayMetrics; + + // cache the MeasureSpec constants here, to prevent extensive marshaling calls to and from Java + // TODO: While this boosts the performance it is error-prone in case Google changes these constants + const MODE_SHIFT = 30; + const MODE_MASK = 0x3 << MODE_SHIFT; + let sdkVersion = -1; + let useOldMeasureSpec = false; + + export function makeMeasureSpec(size: number, mode: number): number { + if (sdkVersion === -1) { + // check whether the old layout is needed + sdkVersion = ad.getApplicationContext().getApplicationInfo().targetSdkVersion; + useOldMeasureSpec = sdkVersion <= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; + } + + if (useOldMeasureSpec) { + return size + mode; + } + + return (size & ~MODE_MASK) | (mode & MODE_MASK); + } + + export function getDisplayMetrics(): android.util.DisplayMetrics { + if (!metrics) { + metrics = ad.getApplicationContext().getResources().getDisplayMetrics(); + } + + return metrics; + } + + export function getDisplayDensity(): number { + if (density === -1) { + density = getDisplayMetrics().density; + } + + return density; + } + + export function toDevicePixels(value: number): number { + return value * getDisplayDensity(); + } + + export function toDeviceIndependentPixels(value: number): number { + return value / getDisplayDensity(); + } +} + // We are using "ad" here to avoid namespace collision with the global android object export module ad { let nativeApp: android.app.Application;