diff --git a/tns-core-modules/ui/core/view/view.android.ts b/tns-core-modules/ui/core/view/view.android.ts index 207068057..a75bfc731 100644 --- a/tns-core-modules/ui/core/view/view.android.ts +++ b/tns-core-modules/ui/core/view/view.android.ts @@ -31,7 +31,6 @@ const androidBackPressedEvent = "androidBackPressed"; const modalMap = new Map(); let TouchListener: TouchListener; -let disableUserInteractionListener: org.nativescript.widgets.DisableUserInteractionListener; let DialogFragment: DialogFragment; interface DialogOptions { @@ -50,14 +49,6 @@ interface DialogFragment { new(): android.support.v4.app.DialogFragment; } -function initializeDisabledListener(): void { - if (disableUserInteractionListener) { - return; - } - - disableUserInteractionListener = new org.nativescript.widgets.DisableUserInteractionListener(); -} - function initializeTouchListener(): void { if (TouchListener) { return; @@ -649,9 +640,8 @@ export class View extends ViewCommon { } [isUserInteractionEnabledProperty.setNative](value: boolean) { - if (this.nativeViewProtected.setClickable) { - this.nativeViewProtected.setClickable(value); - } + this.nativeViewProtected.setClickable(value); + this.nativeViewProtected.setFocusable(value); } [visibilityProperty.getDefault](): Visibility { diff --git a/tns-core-modules/ui/scroll-view/scroll-view-common.ts b/tns-core-modules/ui/scroll-view/scroll-view-common.ts index fef327b48..8dbf4b5a6 100644 --- a/tns-core-modules/ui/scroll-view/scroll-view-common.ts +++ b/tns-core-modules/ui/scroll-view/scroll-view-common.ts @@ -11,6 +11,7 @@ export abstract class ScrollViewBase extends ContentView implements ScrollViewDe public orientation: Orientation; public scrollBarIndicatorVisible: boolean; + public isScrollEnabled: boolean; public addEventListener(arg: string, callback: any, thisArg?: any) { super.addEventListener(arg, callback, thisArg); @@ -102,4 +103,10 @@ export const scrollBarIndicatorVisibleProperty = new Property({ + name: "isScrollEnabled", defaultValue: true, + valueConverter: booleanConverter +}); +isScrollEnabledProperty.register(ScrollViewBase); \ No newline at end of file diff --git a/tns-core-modules/ui/scroll-view/scroll-view.android.ts b/tns-core-modules/ui/scroll-view/scroll-view.android.ts index f2f33e0e7..58660d9a7 100644 --- a/tns-core-modules/ui/scroll-view/scroll-view.android.ts +++ b/tns-core-modules/ui/scroll-view/scroll-view.android.ts @@ -1,5 +1,8 @@ import { ScrollEventData } from "."; -import { ScrollViewBase, layout, scrollBarIndicatorVisibleProperty } from "./scroll-view-common"; +import { + ScrollViewBase, layout, scrollBarIndicatorVisibleProperty, + isUserInteractionEnabledProperty, isScrollEnabledProperty +} from "./scroll-view-common"; export * from "./scroll-view-common"; @@ -44,6 +47,21 @@ export class ScrollView extends ScrollViewBase { return nativeView.getScrollableLength() / layout.getDisplayDensity(); } + [isUserInteractionEnabledProperty.setNative](value: boolean) { + // NOTE: different behavior on iOS & Android: + // iOS disables user interaction recursively for all subviews as well + this.nativeViewProtected.setClickable(value); + this.nativeViewProtected.setFocusable(value); + this.nativeViewProtected.setScrollEnabled(value); + } + + [isScrollEnabledProperty.getDefault](): boolean { + return this.nativeViewProtected.getScrollEnabled(); + } + [isScrollEnabledProperty.setNative](value: boolean) { + this.nativeViewProtected.setScrollEnabled(value); + } + [scrollBarIndicatorVisibleProperty.getDefault](): boolean { return true; } @@ -57,7 +75,7 @@ export class ScrollView extends ScrollViewBase { public scrollToVerticalOffset(value: number, animated: boolean) { const nativeView = this.nativeViewProtected; - if (nativeView && this.orientation === "vertical") { + if (nativeView && this.orientation === "vertical" && this.isScrollEnabled) { value *= layout.getDisplayDensity(); if (animated) { @@ -70,7 +88,7 @@ export class ScrollView extends ScrollViewBase { public scrollToHorizontalOffset(value: number, animated: boolean) { const nativeView = this.nativeViewProtected; - if (nativeView && this.orientation === "horizontal") { + if (nativeView && this.orientation === "horizontal" && this.isScrollEnabled) { value *= layout.getDisplayDensity(); if (animated) { diff --git a/tns-core-modules/ui/scroll-view/scroll-view.d.ts b/tns-core-modules/ui/scroll-view/scroll-view.d.ts index 0a4c73853..d9f73d137 100644 --- a/tns-core-modules/ui/scroll-view/scroll-view.d.ts +++ b/tns-core-modules/ui/scroll-view/scroll-view.d.ts @@ -14,6 +14,11 @@ export class ScrollView extends ContentView { */ public static scrollEvent: string; + /** + * Gets or sets a value indicating whether scroll is enabled. + */ + isScrollEnabled: boolean; + /** * Gets a value that contains the vertical offset of the scrolled content. */ diff --git a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts index f99e8b635..eeade71b8 100644 --- a/tns-core-modules/ui/scroll-view/scroll-view.ios.ts +++ b/tns-core-modules/ui/scroll-view/scroll-view.ios.ts @@ -1,5 +1,7 @@ import { ScrollEventData } from "."; -import { View, layout, ScrollViewBase, scrollBarIndicatorVisibleProperty } from "./scroll-view-common"; +import { + View, layout, ScrollViewBase, scrollBarIndicatorVisibleProperty, isScrollEnabledProperty +} from "./scroll-view-common"; import { ios as iosUtils } from "../../utils/utils"; // HACK: Webpack. Use a fully-qualified import to allow resolve.extensions(.ios.js) to // kick in. `../utils` doesn't seem to trigger the webpack extensions mechanism. @@ -99,6 +101,13 @@ export class ScrollView extends ScrollViewBase { return Math.max(0, this.nativeViewProtected.contentSize.height - this.nativeViewProtected.bounds.size.height); } + [isScrollEnabledProperty.getDefault](): boolean { + return this.nativeViewProtected.scrollEnabled; + } + [isScrollEnabledProperty.setNative](value: boolean) { + this.nativeViewProtected.scrollEnabled = value; + } + [scrollBarIndicatorVisibleProperty.getDefault](): boolean { return true; } @@ -107,14 +116,14 @@ export class ScrollView extends ScrollViewBase { } public scrollToVerticalOffset(value: number, animated: boolean) { - if (this.nativeViewProtected && this.orientation === "vertical") { + if (this.nativeViewProtected && this.orientation === "vertical" && this.isScrollEnabled) { const bounds = this.nativeViewProtected.bounds.size; this.nativeViewProtected.scrollRectToVisibleAnimated(CGRectMake(0, value, bounds.width, bounds.height), animated); } } public scrollToHorizontalOffset(value: number, animated: boolean) { - if (this.nativeViewProtected && this.orientation === "horizontal") { + if (this.nativeViewProtected && this.orientation === "horizontal" && this.isScrollEnabled) { const bounds = this.nativeViewProtected.bounds.size; this.nativeViewProtected.scrollRectToVisibleAnimated(CGRectMake(value, 0, bounds.width, bounds.height), animated); } diff --git a/tns-platform-declarations/android/org.nativescript.widgets.d.ts b/tns-platform-declarations/android/org.nativescript.widgets.d.ts index 32a0d2615..d2e446278 100644 --- a/tns-platform-declarations/android/org.nativescript.widgets.d.ts +++ b/tns-platform-declarations/android/org.nativescript.widgets.d.ts @@ -342,11 +342,15 @@ export class VerticalScrollView extends android.widget.ScrollView { constructor(context: android.content.Context); public getScrollableLength(): number; + public getScrollEnabled(): boolean; + public setScrollEnabled(value: boolean): void; } export class HorizontalScrollView extends android.widget.HorizontalScrollView { constructor(context: android.content.Context); public getScrollableLength(): number; + public getScrollEnabled(): boolean; + public setScrollEnabled(value: boolean): void; } export class ImageView extends android.widget.ImageView {