forked from NativeScript/NativeScript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathview.android.ts
More file actions
323 lines (257 loc) · 11.6 KB
/
view.android.ts
File metadata and controls
323 lines (257 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
import viewCommon = require("ui/core/view-common");
import viewDefinition = require("ui/core/view");
import trace = require("trace");
import utils = require("utils/utils");
import dependencyObservable = require("ui/core/dependency-observable");
import proxy = require("ui/core/proxy");
// merge the exports of the common file with the exports of this file
declare var exports;
require("utils/module-merge").merge(viewCommon, exports);
var ANDROID = "_android";
var NATIVE_VIEW = "_nativeView";
var VIEW_GROUP = "_viewGroup";
var OWNER = "_owner";
function onIdPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var view = <View>data.object;
view._nativeView.setTag(data.newValue);
}
(<proxy.PropertyMetadata>viewCommon.View.idProperty.metadata).onSetNativeValue = onIdPropertyChanged;
function onIsEnabledPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var view = <View>data.object;
view._nativeView.setEnabled(data.newValue);
}
(<proxy.PropertyMetadata>viewCommon.View.isEnabledProperty.metadata).onSetNativeValue = onIsEnabledPropertyChanged;
function onIsUserInteractionEnabledPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var view = <View>data.object;
view._updateOnTouchListener(data.newValue);
}
(<proxy.PropertyMetadata>viewCommon.View.isUserInteractionEnabledProperty.metadata).onSetNativeValue = onIsUserInteractionEnabledPropertyChanged;
export var NativeViewGroup = (<any>android.view.ViewGroup).extend({
get owner() {
return this[OWNER];
},
onMeasure: function (widthMeasureSpec, heightMeasureSpec) {
var owner: viewDefinition.View = this.owner;
owner.onMeasure(widthMeasureSpec, heightMeasureSpec);
this.setMeasuredDimension(owner.getMeasuredWidth(), owner.getMeasuredHeight());
},
onLayout: function (changed: boolean, left: number, top: number, right: number, bottom: number): void {
var owner: viewDefinition.View = this.owner;
owner.onLayout(left, top, right, bottom);
}
});
export class View extends viewCommon.View {
private _disableUserInteractionListener: android.view.View.OnTouchListener = new android.view.View.OnTouchListener({
onTouch: function (view: android.view.View, event: android.view.MotionEvent) {
return true;
}
});
public _updateOnTouchListener(isUserInteractionEnabled: boolean) {
// User interaction is disabled -- we stop it and we do not care whether someone wants to listen for gestures.
if (!isUserInteractionEnabled) {
this._nativeView.setOnTouchListener(this._disableUserInteractionListener);
return;
}
// User interaction is enabled and someone wants to listen for gestures.
if (this._gesturesListener) {
this._nativeView.setOnTouchListener(this._gesturesListener);
return;
}
// User interaction is enabled and no one wants to listen for gestures.
this._nativeView.setOnTouchListener(null);
}
private _gesturesListener: android.view.View.OnTouchListener;
set gesturesListener(value: android.view.View.OnTouchListener) {
this._gesturesListener = value;
this._updateOnTouchListener(this.isUserInteractionEnabled);
}
public _addViewCore(view: viewCommon.View) {
if (this._context) {
view._onAttached(this._context);
}
super._addViewCore(view);
}
public _removeViewCore(view: viewCommon.View) {
super._removeViewCore(view);
// TODO: Detach from the context?
view._onDetached();
}
public _onAttached(context: android.content.Context) {
if (!context) {
throw new Error("Expected valid android.content.Context instance.");
}
trace.write("calling _onAttached on view " + this._domId, trace.categories.VisualTreeEvents);
if (this._context === context) {
return;
}
if (this._context) {
this._onDetached();
}
this._context = context;
this._onContextChanged();
trace.notifyEvent(this, "_onAttached");
if (this._childrenCount > 0) {
// Notify each child for the _onAttached event
var that = this;
var eachChild = function (child: View): boolean {
child._onAttached(context);
if (!child._isAddedToNativeVisualTree) {
// since we have lazy loading of the android widgets, we need to add the native instances at this point.
child._isAddedToNativeVisualTree = that._addViewToNativeVisualTree(child);
}
return true;
}
this._eachChildView(eachChild);
}
}
public _onDetached(force?: boolean) {
if (this._childrenCount > 0) {
// Detach children first
var that = this;
var eachChild = function (child: View): boolean {
if (child._isAddedToNativeVisualTree) {
that._removeViewFromNativeVisualTree(child);
}
child._onDetached(force);
return true;
}
this._eachChildView(eachChild);
}
trace.write("calling _onDetached on view " + this._domId, trace.categories.VisualTreeEvents);
this._clearAndroidReference();
this._context = undefined;
trace.notifyEvent(this, "_onDetached");
}
// TODO: revise this method
public _clearAndroidReference() {
// Widgets like buttons and such have reference to their native view in both properties.
if (this[NATIVE_VIEW] === this[ANDROID]) {
this[NATIVE_VIEW] = undefined;
}
// Handle layout and content view
if (this[VIEW_GROUP] === this[ANDROID]) {
this[VIEW_GROUP] = undefined;
}
this[ANDROID] = undefined;
}
public _onContextChanged() {
trace.write("calling _onContextChanged on view " + this._domId, trace.categories.VisualTreeEvents);
this._createUI();
utils.copyFrom(this._options, this);
delete this._options;
// copy all the locally cached values to the native android widget
this._syncNativeProperties();
trace.notifyEvent(this, "_onContextChanged");
}
get _nativeView(): android.view.View {
return this.android;
}
public layoutNativeView(left: number, top: number, right: number, bottom: number): void {
if (this._nativeView) {
this._nativeView.layout(left, top, right, bottom);
}
}
public requestLayout(): void {
super.requestLayout();
if (this._nativeView) {
return this._nativeView.requestLayout();
}
}
public measure(widthMeasureSpec: number, heightMeasureSpec: number): void {
super.measure(widthMeasureSpec, heightMeasureSpec);
this.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public layout(left: number, top: number, right: number, bottom: number): void {
super.layout(left, top, right, bottom);
this.onLayout(left, top, right, bottom);
}
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
var view = this._nativeView;
if (view) {
var width = utils.layout.getMeasureSpecSize(widthMeasureSpec);
var widthMode = utils.layout.getMeasureSpecMode(widthMeasureSpec);
var height = utils.layout.getMeasureSpecSize(heightMeasureSpec);
var heightMode = utils.layout.getMeasureSpecMode(heightMeasureSpec);
trace.write(this + " :onMeasure: " + utils.layout.getMode(widthMode) + " " + width + ", " + utils.layout.getMode(heightMode) + " " + height, trace.categories.Layout);
view.measure(widthMeasureSpec, heightMeasureSpec);
this.setMeasuredDimension(view.getMeasuredWidth(), view.getMeasuredHeight());
}
}
public onLayout(left: number, top: number, right: number, bottom: number): void {
var view = this._nativeView;
if (view) {
this.layoutNativeView(left, top, right, bottom);
trace.write(this + " :onLayout: " + left + ", " + top + ", " + (right - left) + ", " + (bottom - top), trace.categories.Layout);
}
}
public focus(): boolean {
if (this.android) {
return this.android.requestFocus();
}
return false;
}
}
export class CustomLayoutView extends View implements viewDefinition.CustomLayoutView {
private _viewGroup: android.view.ViewGroup;
get android(): android.view.ViewGroup {
return this._viewGroup;
}
get _nativeView(): android.view.ViewGroup {
return this._viewGroup;
}
public _createUI() {
this._viewGroup = new NativeViewGroup(this._context);
this._viewGroup[OWNER] = this;
}
//public _onDetached(force?: boolean) {
// delete this._viewGroup[OWNER];
// super._onDetached(force);
//}
public _addViewToNativeVisualTree(child: View): boolean {
super._addViewToNativeVisualTree(child);
if (this._nativeView && child._nativeView) {
this._nativeView.addView(child._nativeView);
return true;
}
return false;
}
public _removeViewFromNativeVisualTree(child: View): void {
super._removeViewFromNativeVisualTree(child);
if (this._nativeView && child._nativeView) {
this._nativeView.removeView(child._nativeView);
trace.notifyEvent(child, "childInLayoutRemovedFromNativeVisualTree");
}
}
public measure(widthMeasureSpec: number, heightMeasureSpec: number): void {
this._setCurrentMeasureSpecs(widthMeasureSpec, heightMeasureSpec);
var view = this._nativeView;
if (view) {
var width = utils.layout.getMeasureSpecSize(widthMeasureSpec);
var widthMode = utils.layout.getMeasureSpecMode(widthMeasureSpec);
var height = utils.layout.getMeasureSpecSize(heightMeasureSpec);
var heightMode = utils.layout.getMeasureSpecMode(heightMeasureSpec);
trace.write(this + " :measure: " + utils.layout.getMode(widthMode) + " " + width + ", " + utils.layout.getMode(heightMode) + " " + height, trace.categories.Layout);
view.measure(widthMeasureSpec, heightMeasureSpec);
}
}
public layout(left: number, top: number, right: number, bottom: number): void {
this._setCurrentLayoutBounds(left, top, right, bottom);
var view = this._nativeView;
if (view) {
this.layoutNativeView(left, top, right, bottom);
trace.write(this + " :layout: " + left + ", " + top + ", " + (right - left) + ", " + (bottom - top), trace.categories.Layout);
}
}
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
// Don't call super because it will trigger measure again.
var width = utils.layout.getMeasureSpecSize(widthMeasureSpec);
var widthMode = utils.layout.getMeasureSpecMode(widthMeasureSpec);
var height = utils.layout.getMeasureSpecSize(heightMeasureSpec);
var heightMode = utils.layout.getMeasureSpecMode(heightMeasureSpec);
trace.write(this + " :onMeasure: " + utils.layout.getMode(widthMode) + " " + width + ", " + utils.layout.getMode(heightMode) + " " + height, trace.categories.Layout);
}
public onLayout(left: number, top: number, right: number, bottom: number): void {
// Don't call super because it will trigger layout again.
trace.write(this + " :onLayout: " + left + ", " + top + ", " + (right - left) + ", " + (bottom - top), trace.categories.Layout);
}
}