mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-17 21:01:34 +08:00
scroll event implemented
This commit is contained in:
@ -265,6 +265,50 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
|
|||||||
// Check verticalOffset after navigation
|
// Check verticalOffset after navigation
|
||||||
TKUnit.assertAreClose(this.testView.horizontalOffset, 100, 0.1, "this.testView.horizontalOffset after navigation");
|
TKUnit.assertAreClose(this.testView.horizontalOffset, 100, 0.1, "this.testView.horizontalOffset after navigation");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public test_scrollView_vertical_raised_scroll_event() {
|
||||||
|
this.testView.orientation = enums.Orientation.vertical;
|
||||||
|
|
||||||
|
var scrollY: number;
|
||||||
|
this.testView.on(scrollViewModule.ScrollView.scrollEvent, (args: scrollViewModule.ScrollEventData) => {
|
||||||
|
scrollY = args.scrollY;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.testView.width = 200;
|
||||||
|
this.testView.height = 300;
|
||||||
|
|
||||||
|
var btn = new button.Button();
|
||||||
|
btn.text = "test";
|
||||||
|
btn.height = 500;
|
||||||
|
this.testView.content = btn;
|
||||||
|
this.waitUntilTestElementLayoutIsValid();
|
||||||
|
|
||||||
|
this.testView.scrollToVerticalOffset(100, false);
|
||||||
|
TKUnit.waitUntilReady(function () { return scrollY > 0; });
|
||||||
|
TKUnit.assertEqual(this.testView.verticalOffset, scrollY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public test_scrollView_horizontal_raised_scroll_event() {
|
||||||
|
this.testView.orientation = enums.Orientation.horizontal;
|
||||||
|
|
||||||
|
var scrollX: number;
|
||||||
|
this.testView.on(scrollViewModule.ScrollView.scrollEvent, (args: scrollViewModule.ScrollEventData) => {
|
||||||
|
scrollX = args.scrollX;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.testView.width = 200;
|
||||||
|
this.testView.height = 300;
|
||||||
|
|
||||||
|
var btn = new button.Button();
|
||||||
|
btn.text = "test";
|
||||||
|
btn.width = 500;
|
||||||
|
this.testView.content = btn;
|
||||||
|
this.waitUntilTestElementLayoutIsValid();
|
||||||
|
|
||||||
|
this.testView.scrollToHorizontalOffset(100, false);
|
||||||
|
TKUnit.waitUntilReady(function () { return scrollX > 0; });
|
||||||
|
TKUnit.assertEqual(this.testView.horizontalOffset, scrollX);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createTestCase(): ScrollLayoutTest {
|
export function createTestCase(): ScrollLayoutTest {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import dependencyObservable = require("ui/core/dependency-observable");
|
import dependencyObservable = require("ui/core/dependency-observable");
|
||||||
import proxy = require("ui/core/proxy");
|
import proxy = require("ui/core/proxy");
|
||||||
import enums = require("ui/enums");
|
import enums = require("ui/enums");
|
||||||
|
import definition = require("ui/scroll-view");
|
||||||
|
import contentView = require("ui/content-view");
|
||||||
|
|
||||||
function isValidOrientation(value: any): boolean {
|
function isValidOrientation(value: any): boolean {
|
||||||
return value === enums.Orientation.vertical || value === enums.Orientation.horizontal;
|
return value === enums.Orientation.vertical || value === enums.Orientation.horizontal;
|
||||||
@ -13,4 +15,92 @@ export var orientationProperty = new dependencyObservable.Property(
|
|||||||
dependencyObservable.PropertyMetadataSettings.AffectsLayout,
|
dependencyObservable.PropertyMetadataSettings.AffectsLayout,
|
||||||
undefined,
|
undefined,
|
||||||
isValidOrientation)
|
isValidOrientation)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export class ScrollView extends contentView.ContentView implements definition.ScrollView {
|
||||||
|
private _scrollEventAttached: boolean;
|
||||||
|
public static scrollEvent = "scroll";
|
||||||
|
|
||||||
|
get orientation(): string {
|
||||||
|
return this._getValue(orientationProperty);
|
||||||
|
}
|
||||||
|
set orientation(value: string) {
|
||||||
|
this._setValue(orientationProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public addEventListener(arg: string, callback: any, thisArg?: any) {
|
||||||
|
super.addEventListener(arg, callback, thisArg);
|
||||||
|
|
||||||
|
if (arg === definition.ScrollView.scrollEvent) {
|
||||||
|
this.attach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeEventListener(arg: string, callback: any, thisArg?: any) {
|
||||||
|
super.addEventListener(arg, callback, thisArg);
|
||||||
|
|
||||||
|
if (arg === definition.ScrollView.scrollEvent) {
|
||||||
|
this.dettach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public onLoaded() {
|
||||||
|
super.onLoaded();
|
||||||
|
|
||||||
|
this.attach();
|
||||||
|
}
|
||||||
|
|
||||||
|
public onUnloaded() {
|
||||||
|
super.onUnloaded();
|
||||||
|
|
||||||
|
this.dettach();
|
||||||
|
}
|
||||||
|
|
||||||
|
private attach() {
|
||||||
|
if (!this._scrollEventAttached && this.isLoaded) {
|
||||||
|
this._scrollEventAttached = true;
|
||||||
|
|
||||||
|
this.attachNative();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private dettach() {
|
||||||
|
if (this._scrollEventAttached && this.isLoaded) {
|
||||||
|
this._scrollEventAttached = false;
|
||||||
|
|
||||||
|
this.dettachNative();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected attachNative() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
protected dettachNative() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
get horizontalOffset(): number {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get verticalOffset(): number {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get scrollableWidth(): number {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get scrollableHeight(): number {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public scrollToVerticalOffset(value: number, animated: boolean) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public scrollToHorizontalOffset(value: number, animated: boolean) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
import dependencyObservable = require("ui/core/dependency-observable");
|
import dependencyObservable = require("ui/core/dependency-observable");
|
||||||
import definition = require("ui/scroll-view");
|
import definition = require("ui/scroll-view");
|
||||||
import contentView = require("ui/content-view");
|
|
||||||
import common = require("./scroll-view-common");
|
import common = require("./scroll-view-common");
|
||||||
import utils = require("utils/utils");
|
import utils = require("utils/utils");
|
||||||
import enums = require("ui/enums");
|
import enums = require("ui/enums");
|
||||||
|
import proxy = require("ui/core/proxy");
|
||||||
|
|
||||||
global.moduleMerge(common, exports);
|
global.moduleMerge(common, exports);
|
||||||
|
|
||||||
@ -11,9 +11,10 @@ common.orientationProperty.metadata.onValueChanged = function scrollViewOrientat
|
|||||||
(<ScrollView>data.object)._onOrientationChanged(data.oldValue, data.newValue);
|
(<ScrollView>data.object)._onOrientationChanged(data.oldValue, data.newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ScrollView extends contentView.ContentView implements definition.ScrollView {
|
export class ScrollView extends common.ScrollView implements definition.ScrollView {
|
||||||
private _android: org.nativescript.widgets.VerticalScrollView | org.nativescript.widgets.HorizontalScrollView;
|
private _android: org.nativescript.widgets.VerticalScrollView | org.nativescript.widgets.HorizontalScrollView;
|
||||||
private _androidViewId: number;
|
private _androidViewId: number;
|
||||||
|
private handler: android.view.ViewTreeObserver.OnScrollChangedListener;
|
||||||
|
|
||||||
get android(): android.view.ViewGroup {
|
get android(): android.view.ViewGroup {
|
||||||
return this._android;
|
return this._android;
|
||||||
@ -23,13 +24,6 @@ export class ScrollView extends contentView.ContentView implements definition.Sc
|
|||||||
return this._android;
|
return this._android;
|
||||||
}
|
}
|
||||||
|
|
||||||
get orientation(): string {
|
|
||||||
return this._getValue(common.orientationProperty);
|
|
||||||
}
|
|
||||||
set orientation(value: string) {
|
|
||||||
this._setValue(common.orientationProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
get horizontalOffset(): number {
|
get horizontalOffset(): number {
|
||||||
if (!this._android) {
|
if (!this._android) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -68,8 +62,7 @@ export class ScrollView extends contentView.ContentView implements definition.Sc
|
|||||||
|
|
||||||
if (animated) {
|
if (animated) {
|
||||||
this._android.smoothScrollTo(0, value);
|
this._android.smoothScrollTo(0, value);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this._android.scrollTo(0, value);
|
this._android.scrollTo(0, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,8 +74,7 @@ export class ScrollView extends contentView.ContentView implements definition.Sc
|
|||||||
|
|
||||||
if (animated) {
|
if (animated) {
|
||||||
this._android.smoothScrollTo(value, 0);
|
this._android.smoothScrollTo(value, 0);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this._android.scrollTo(value, 0);
|
this._android.scrollTo(value, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,8 +83,7 @@ export class ScrollView extends contentView.ContentView implements definition.Sc
|
|||||||
public _createUI() {
|
public _createUI() {
|
||||||
if (this.orientation === enums.Orientation.horizontal) {
|
if (this.orientation === enums.Orientation.horizontal) {
|
||||||
this._android = new org.nativescript.widgets.HorizontalScrollView(this._context);
|
this._android = new org.nativescript.widgets.HorizontalScrollView(this._context);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this._android = new org.nativescript.widgets.VerticalScrollView(this._context);
|
this._android = new org.nativescript.widgets.VerticalScrollView(this._context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,17 +92,6 @@ export class ScrollView extends contentView.ContentView implements definition.Sc
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._android.setId(this._androidViewId);
|
this._android.setId(this._androidViewId);
|
||||||
|
|
||||||
var that = new WeakRef(this);
|
|
||||||
this._android.getViewTreeObserver().addOnScrollChangedListener(new android.view.ViewTreeObserver.OnScrollChangedListener({
|
|
||||||
onScrollChanged: function () {
|
|
||||||
var rootScrollView = that.get();
|
|
||||||
if (rootScrollView && rootScrollView.android) {
|
|
||||||
var scrollX = rootScrollView.android.getScrollX(); //for horizontalScrollView
|
|
||||||
var scrollY = rootScrollView.android.getScrollY(); //for verticalScrollView
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public _onOrientationChanged(oldValue: string, newValue: string) {
|
public _onOrientationChanged(oldValue: string, newValue: string) {
|
||||||
@ -127,4 +107,28 @@ export class ScrollView extends contentView.ContentView implements definition.Sc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected attachNative() {
|
||||||
|
var that = new WeakRef(this);
|
||||||
|
this.handler = new android.view.ViewTreeObserver.OnScrollChangedListener({
|
||||||
|
onScrollChanged: function () {
|
||||||
|
var rootScrollView = that.get();
|
||||||
|
if (rootScrollView && rootScrollView.android) {
|
||||||
|
rootScrollView.notify(<definition.ScrollEventData>{
|
||||||
|
object: rootScrollView,
|
||||||
|
eventName: definition.ScrollView.scrollEvent,
|
||||||
|
scrollX: rootScrollView.android.getScrollX() / utils.layout.getDisplayDensity(),
|
||||||
|
scrollY: rootScrollView.android.getScrollY() / utils.layout.getDisplayDensity()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this._android.getViewTreeObserver().addOnScrollChangedListener(this.handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected dettachNative() {
|
||||||
|
this._android.getViewTreeObserver().removeOnScrollChangedListener(this.handler);
|
||||||
|
this.handler = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
20
ui/scroll-view/scroll-view.d.ts
vendored
20
ui/scroll-view/scroll-view.d.ts
vendored
@ -3,11 +3,22 @@
|
|||||||
*/
|
*/
|
||||||
declare module "ui/scroll-view" {
|
declare module "ui/scroll-view" {
|
||||||
import contentView = require("ui/content-view");
|
import contentView = require("ui/content-view");
|
||||||
|
import observable = require("data/observable");
|
||||||
|
import dependencyObservable = require("ui/core/dependency-observable");
|
||||||
|
|
||||||
|
export var orientationProperty: dependencyObservable.Property;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a scrollable area that can have content that is larger than its bounds.
|
* Represents a scrollable area that can have content that is larger than its bounds.
|
||||||
*/
|
*/
|
||||||
class ScrollView extends contentView.ContentView {
|
class ScrollView extends contentView.ContentView {
|
||||||
|
public static orientationProperty: dependencyObservable.Property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String value used when hooking to scroll event.
|
||||||
|
*/
|
||||||
|
public static scrollEvent: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a value that contains the vertical offset of the scrolled content.
|
* Gets a value that contains the vertical offset of the scrolled content.
|
||||||
*/
|
*/
|
||||||
@ -56,8 +67,13 @@ declare module "ui/scroll-view" {
|
|||||||
on(eventNames: string, callback: (data: observable.EventData) => void, thisArg?: any);
|
on(eventNames: string, callback: (data: observable.EventData) => void, thisArg?: any);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Raised when a tap event occurs.
|
* Raised when a scroll event occurs.
|
||||||
*/
|
*/
|
||||||
on(event: "scroll", callback: (args: observable.EventData) => void, thisArg?: any);
|
on(event: "scroll", callback: (args: ScrollEventData) => void, thisArg?: any);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ScrollEventData extends observable.EventData {
|
||||||
|
scrollX: number;
|
||||||
|
scrollY: number;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,5 @@
|
|||||||
import view = require("ui/core/view");
|
import view = require("ui/core/view");
|
||||||
import definition = require("ui/scroll-view");
|
import definition = require("ui/scroll-view");
|
||||||
import contentView = require("ui/content-view");
|
|
||||||
import common = require("./scroll-view-common");
|
import common = require("./scroll-view-common");
|
||||||
import enums = require("ui/enums");
|
import enums = require("ui/enums");
|
||||||
import utils = require("utils/utils");
|
import utils = require("utils/utils");
|
||||||
@ -22,11 +21,18 @@ class UIScrollViewDelegateImpl extends NSObject implements UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
|
|
||||||
public scrollViewDidScroll(textView: UIScrollView): void {
|
public scrollViewDidScroll(textView: UIScrollView): void {
|
||||||
|
if (this._owner) {
|
||||||
|
this._owner.notify(<definition.ScrollEventData>{
|
||||||
|
object: this._owner,
|
||||||
|
eventName: definition.ScrollView.scrollEvent,
|
||||||
|
scrollX: this._owner.horizontalOffset,
|
||||||
|
scrollY: this._owner.verticalOffset
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ScrollView extends contentView.ContentView implements definition.ScrollView {
|
export class ScrollView extends common.ScrollView implements definition.ScrollView {
|
||||||
private _scroll: UIScrollView;
|
private _scroll: UIScrollView;
|
||||||
private _contentMeasuredWidth: number = 0;
|
private _contentMeasuredWidth: number = 0;
|
||||||
private _contentMeasuredHeight: number = 0;
|
private _contentMeasuredHeight: number = 0;
|
||||||
@ -35,25 +41,15 @@ export class ScrollView extends contentView.ContentView implements definition.Sc
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._scroll = new UIScrollView();
|
this._scroll = new UIScrollView();
|
||||||
|
|
||||||
this._delegate = UIScrollViewDelegateImpl.new().initWithOwner(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public onLoaded() {
|
protected attachNative() {
|
||||||
super.onLoaded();
|
this._delegate = UIScrollViewDelegateImpl.new().initWithOwner(this);
|
||||||
this._scroll.delegate = this._delegate;
|
this._scroll.delegate = this._delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public onUnloaded() {
|
protected dettachNative() {
|
||||||
this._scroll.delegate = null;
|
this._scroll.delegate = null;
|
||||||
super.onUnloaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
get orientation(): string {
|
|
||||||
return this._getValue(common.orientationProperty);
|
|
||||||
}
|
|
||||||
set orientation(value: string) {
|
|
||||||
this._setValue(common.orientationProperty, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get horizontalOffset(): number {
|
get horizontalOffset(): number {
|
||||||
|
Reference in New Issue
Block a user