View lifecycle methods

This commit is contained in:
vakrilov
2017-01-04 09:55:19 +02:00
parent ebbf202a01
commit c30be0d606
40 changed files with 169 additions and 169 deletions

View File

@ -1,4 +1,4 @@
{
"name": "tns-samples-apps",
"main": "ui-tests-app/app.js"
"main": "cuteness.io/app.js"
}

View File

@ -13,7 +13,8 @@
}
},
"dependencies": {
"tns-core-modules": "2.4.2"
"tns-core-modules": "2.4.2",
"tns-core-modules-widgets": "file:///Users/vakrilov/Work/Projects/tns-core-modules-widgets/dist/tns-core-modules-widgets-2.5.0.tgz"
},
"devDependencies": {
"tns-platform-declarations": "*",

View File

@ -85,7 +85,7 @@ export class MyButton extends Button implements def.MyButton {
return this._layout;
}
public _createUI() {
public _createNativeView() {
this._layout = new NativeButton(this._context, this);
}
@ -138,7 +138,7 @@ export class MyStackLayout extends StackLayout implements def.MyStackLayout {
return this._layout;
}
public _createUI() {
public _createNativeView() {
this._layout = new NativeStackLayout(this._context, this);
}
@ -191,7 +191,7 @@ export class MyGridLayout extends GridLayout implements def.MyGridLayout {
return this._layout;
}
public _createUI() {
public _createNativeView() {
this._layout = new NativeGridLayout(this._context, this);
}

View File

@ -204,7 +204,8 @@ export var test_event_onContextChanged_IsNotRaised_WhenAttachedToSameContext = f
var listener = new Listener("_onContextChanged");
trace.addEventListener(listener);
views[2]._onAttached(views[0]._context);
// views[2]._onContextChanged(views[0]._context);
views[2]._setupUI(views[0]._context);
TKUnit.assertEqual(listener.receivedEvents.length, 0, "listener.receivedEvents.length");

View File

@ -115,7 +115,7 @@ export class ActionBar extends ActionBarBase {
return this._toolbar;
}
public _createUI() {
public _createNativeView() {
this._toolbar = new android.support.v7.widget.Toolbar(this._context);
this._menuItemClickListener = this._menuItemClickListener || new MenuItemClickListener(new WeakRef(this));
this._toolbar.setOnMenuItemClickListener(this._menuItemClickListener);
@ -302,7 +302,7 @@ export class ActionBar extends ActionBarBase {
}
}
public _clearAndroidReference() {
public _disposeNativeView() {
// don't clear _android field!
this.nativeView = undefined;
}

View File

@ -5,7 +5,7 @@ export * from "./activity-indicator-common";
export class ActivityIndicator extends ActivityIndicatorBase {
_progressBar: android.widget.ProgressBar;
public _createUI() {
public _createNativeView() {
this._progressBar = new android.widget.ProgressBar(this._context);
this._progressBar.setVisibility(android.view.View.INVISIBLE);
this._progressBar.setIndeterminate(true);

View File

@ -30,7 +30,7 @@ export class Button extends ButtonBase {
return this._button;
}
public _createUI() {
public _createNativeView() {
let weakRef = new WeakRef(this);
this._button = new android.widget.Button(this._context);
this._button.setOnClickListener(new ClickListener(weakRef));

View File

@ -1,6 +1,6 @@
import { ViewBase as ViewBaseDefinition } from "ui/core/view-base";
import { Observable, EventData } from "data/observable";
import { Property, InheritedProperty, Style, clearInheritedProperties, propagateInheritedProperties, resetCSSProperties, applyNativeSetters } from "./properties";
import { Property, InheritedProperty, Style, clearInheritedProperties, propagateInheritedProperties, resetCSSProperties, applyNativeSetters, resetStyleProperties } from "./properties";
import { Binding, BindingOptions, Bindable } from "ui/core/bindable";
import { isIOS, isAndroid } from "platform";
import { fromString as gestureFromString } from "ui/gestures";
@ -408,20 +408,16 @@ export class ViewBase extends Observable implements ViewBaseDefinition {
protected _addViewCore(view: ViewBase, atIndex?: number) {
if (this._context) {
view._onAttached(this._context);
view._setupUI(this._context, atIndex);
}
if (!view._isAddedToNativeVisualTree) {
let nativeIndex = this._childIndexToNativeChildIndex(atIndex);
view._isAddedToNativeVisualTree = this._addViewToNativeVisualTree(view, nativeIndex);
}
// TODO: Split this method - we want binding context before loaded.
propagateInheritedProperties(this);
// TODO: Discuss this.
if (this._isLoaded) {
view.onLoaded();
}
propagateInheritedProperties(this);
}
/**
@ -452,81 +448,77 @@ export class ViewBase extends Observable implements ViewBaseDefinition {
// view.unsetInheritedProperties();
// Remove the view from the native visual scene first
this._removeViewFromNativeVisualTree(view);
if (view._context) {
view._onDetached();
view._tearDownUI();
}
}
public _onAttached(context: any) {
if (!context) {
throw new Error("Expected valid android.content.Context instance.");
}
if (traceEnabled) {
traceWrite(`${this}._onAttached(context)`, traceCategories.VisualTreeEvents);
}
if (this._context === context) {
return;
}
if (this._context) {
this._onDetached(true);
}
this._context = context;
this._onContextChanged();
if (traceEnabled) {
traceNotifyEvent(this, "_onAttached");
}
// Notify each child for the _onAttached event
this.eachChild((child) => {
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 = this._addViewToNativeVisualTree(child);
}
return true;
});
// copy all the locally cached values to the native android widget
applyNativeSetters(this);
}
public _onDetached(force?: boolean) {
if (traceEnabled) {
traceWrite(`${this}._onDetached(force)`, traceCategories.VisualTreeEvents);
}
// Detach children first
this.eachChild((child: ViewBase) => {
if (child._isAddedToNativeVisualTree) {
this._removeViewFromNativeVisualTree(child);
}
if (child._context) {
child._onDetached(force);
}
return true;
});
this._context = undefined;
if (traceEnabled) {
traceNotifyEvent(this, "_onDetached");
}
}
public _onContextChanged(): void {
public _createNativeView() {
//
}
public _disposeNativeView() {
//
}
public _initNativeView(): void {
//
}
public _resetNativeView(): void {
//
}
public _setupUI(context: android.content.Context, atIndex?: number) {
this._context = context;
// TODO: refactor createUI to return native view
this._createNativeView();
this.nativeView = (<any>this)._nativeView;
this._initNativeView();
// TODO: Remove this
if (this.nativeView && !this.nativeView.getLayoutParams()) {
this.nativeView.setLayoutParams(new org.nativescript.widgets.CommonLayoutParams());
}
if (this.parent) {
this.parent._addViewToNativeVisualTree(this, atIndex);
}
applyNativeSetters(this);
this.eachChild((child) => {
child._setupUI(context);
return true;
});
// if (traceEnabled) {
// traceNotifyEvent(this, "_onAttached");
// }
}
public _tearDownUI(force?: boolean) {
this.eachChild((child) => {
child._tearDownUI(force);
return true;
});
// TODO: rename and implement this as resetNativeSetters
resetStyleProperties(this.style);
if (this.parent) {
this.parent._removeViewFromNativeVisualTree(this);
}
this._resetNativeView();
this._disposeNativeView();
this._context = null;
}
_childIndexToNativeChildIndex(index?: number): number {
return index;
}

View File

@ -765,7 +765,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
return { boundsChanged, sizeChanged };
}
public _createUI() {
public _createNativeView() {
//
}

View File

@ -106,15 +106,8 @@ export class View extends ViewCommon {
}
}
public _onDetached(force?: boolean) {
// Call super for recursive detach of all children.
super._onDetached(force);
this._clearAndroidReference();
}
// TODO: revise this method
public _clearAndroidReference() {
public _disposeNativeView() {
// Widgets like buttons and such have reference to their native view in both properties.
if (this[NATIVE_VIEW] === this[ANDROID]) {
@ -129,24 +122,6 @@ export class View extends ViewCommon {
this[ANDROID] = undefined;
}
public _onContextChanged() {
if (traceEnabled) {
traceWrite(`${this}._onContextChanged`, traceCategories.VisualTreeEvents);
}
this._createUI();
// Ensure layout params
if (this._nativeView && !this._nativeView.getLayoutParams()) {
this._nativeView.setLayoutParams(new org.nativescript.widgets.CommonLayoutParams());
}
this.nativeView = this._nativeView;
if (traceEnabled) {
traceNotifyEvent(this, "_onContextChanged");
}
}
get _nativeView(): android.view.View {
return this.android;
}
@ -573,7 +548,7 @@ export class CustomLayoutView extends View implements CustomLayoutViewDefinition
return this._viewGroup;
}
public _createUI() {
public _createNativeView() {
this._viewGroup = new org.nativescript.widgets.ContentLayout(this._context);
}

View File

@ -546,8 +546,6 @@ declare module "ui/core/view" {
_gestureObservers: any;
// _isInheritedChange(): boolean;
_createUI(): void;
_updateLayout(): void;
/**

View File

@ -48,7 +48,7 @@ export class DatePicker extends DatePickerBase {
return this._android;
}
public _createUI() {
public _createNativeView() {
this._android = new android.widget.DatePicker(this._context);
this._android.setCalendarViewShown(false);
this._listener = this._listener = new DateChangedListener(new WeakRef(this));

View File

@ -112,12 +112,40 @@ declare module "ui/core/view-base" {
_cancelAllAnimations();
_context: any /* android.content.Context */;
_onAttached(context: any /* android.content.Context */): void;
_onContextChanged(): void;
_onDetached(force?: boolean): void;
/**
* Setups the UI for ViewBase and all its children recursively.
* This method should *not* be overridden by derived views.
*/
_setupUI(context: any /* android.content.Context */, atIndex?: number): void;
/**
* Tears down the UI for ViewBase and all its children recursively.
* This method should *not* be overridden by derived views.
*/
_tearDownUI(force?: boolean): void;
/**
* Creates a native view
*/
_createNativeView(): void;
/**
* Clean up references to the native view.
*/
_disposeNativeView(): void;
/**
* Initializes properties/listeners of the native view.
*/
_initNativeView(): void;
/**
* Resets properties/listeners set to the native view.
*/
_resetNativeView(): void;
_isAddedToNativeVisualTree: boolean;
/**
* Performs the core logic of adding a child view to the native visual tree. Returns true if the view's native representation has been successfully added, false otherwise.
*/

View File

@ -147,7 +147,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
public abstract _onReturnPress(): void;
public _createUI() {
public _createNativeView() {
this._android = new android.widget.EditText(this._context);
this._configureEditText();
this._keyListenerCache = this.android.getKeyListener();
@ -164,7 +164,7 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
this._android.setOnEditorActionListener(this._editorActionListener);
}
public _onDetached(force?: boolean) {
public _resetNativeView(force?: boolean) {
if (this._android) {
if (this._textWatcher) {
this._android.removeTextChangedListener(this._textWatcher);
@ -178,9 +178,12 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
this._android.setOnEditorActionListener(null);
}
}
super._resetNativeView();
}
public _disposeNativeView(force?: boolean) {
this._android = undefined;
super._onDetached(force);
super._disposeNativeView();
}
public dismissSoftInput() {

View File

@ -294,7 +294,7 @@ export class Frame extends FrameBase {
}
}
public _createUI() {
public _createNativeView() {
let root = new org.nativescript.widgets.ContentLayout(this._context);
if (this._containerViewId < 0) {
this._containerViewId = android.view.View.generateViewId();
@ -327,8 +327,11 @@ export class Frame extends FrameBase {
}
}
public _clearAndroidReference() {
public _resetNativeView() {
this._android.rootViewGroup.removeOnAttachStateChangeListener(this._listener);
}
public _disposeNativeView() {
// we should keep the reference to underlying native object, since frame can contain many pages.
this._android.rootViewGroup = null;
}
@ -704,7 +707,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
const page = entry.resolvedPage;
if (savedInstanceState && savedInstanceState.getBoolean(HIDDEN, false)) {
fragment.getFragmentManager().beginTransaction().hide(fragment).commit();
page._onAttached(fragment.getActivity());
this.frame._addView(page);
}
else {
onFragmentShown(fragment);
@ -813,7 +816,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
this._rootView = rootView;
// Initialize native visual tree;
rootView._onAttached(activity);
rootView._setupUI(activity);
activity.setContentView(rootView._nativeView, new org.nativescript.widgets.CommonLayoutParams());
// frameId is negative w
if (frame) {
@ -858,7 +861,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
public onDestroy(activity: any, superFunc: Function): void {
let rootView = this._rootView;
if (rootView && rootView._context) {
rootView._onDetached(true);
rootView._tearDownUI(true);
}
superFunc.call(activity);

View File

@ -11,7 +11,7 @@ export class HtmlView extends HtmlViewBase {
return this._android;
}
public _createUI() {
public _createNativeView() {
this._android = new android.widget.TextView(this._context);
// This makes the html <a href...> work
this._android.setLinksClickable(true);

View File

@ -59,7 +59,7 @@ export class Image extends ImageBase {
return this._android;
}
public _createUI() {
public _createNativeView() {
if (!imageFetcher) {
initImageCache(this._context);
}

View File

@ -17,7 +17,7 @@ export class Label extends TextBase implements LabelDefinition {
return this._android;
}
public _createUI() {
public _createNativeView() {
this._android = new android.widget.TextView(this._context);
}
}

View File

@ -51,7 +51,7 @@ export class AbsoluteLayout extends AbsoluteLayoutBase {
return this._layout;
}
public _createUI() {
public _createNativeView() {
this._layout = new org.nativescript.widgets.AbsoluteLayout(this._context);
}
}

View File

@ -54,7 +54,7 @@ export class DockLayout extends DockLayoutBase {
return this._layout;
}
public _createUI() {
public _createNativeView() {
this._layout = new org.nativescript.widgets.DockLayout(this._context);
}

View File

@ -138,7 +138,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
get android(): FlexboxLayoutWidget { return this._layout; }
get _nativeView(): FlexboxLayoutWidget { return this._layout; }
public _createUI() {
public _createNativeView() {
this._layout = new org.nativescript.widgets.FlexboxLayout(this._context);
}

View File

@ -102,7 +102,7 @@ export class GridLayout extends GridLayoutBase {
return this._layout;
}
public _createUI() {
public _createNativeView() {
this._layout = new org.nativescript.widgets.GridLayout(this._context);
// Update native GridLayout

View File

@ -35,15 +35,15 @@ export class Layout extends LayoutBase implements LayoutDefinition {
return this._viewGroup;
}
public _createUI() {
public _createNativeView() {
ensureNativeViewGroupClass();
this._viewGroup = new NativeViewGroupClass(this._context);
this._viewGroup[OWNER] = this;
}
public _onDetached(force?: boolean) {
public _disposeNativeView() {
delete this._viewGroup[OWNER];
super._onDetached(force);
super._disposeNativeView();
}
public measure(widthMeasureSpec: number, heightMeasureSpec: number): void {

View File

@ -13,7 +13,7 @@ export class StackLayout extends StackLayoutBase {
return this._layout;
}
public _createUI() {
public _createNativeView() {
this._layout = new org.nativescript.widgets.StackLayout(this._context);
}

View File

@ -13,7 +13,7 @@ export class WrapLayout extends WrapLayoutBase {
return this._layout;
}
public _createUI() {
public _createNativeView() {
this._layout = new org.nativescript.widgets.WrapLayout(this._context);
}

View File

@ -67,7 +67,7 @@ export class ListPicker extends ListPickerBase {
return this._android;
}
public _createUI() {
public _createNativeView() {
this._android = new android.widget.NumberPicker(this._context);
let editText = getEditText(this._android);
this._editText = editText;

View File

@ -36,7 +36,7 @@ export class ListView extends ListViewBase {
public _realizedItems = new Map<android.view.View, View>();
public _realizedTemplates = new Map<string, Map<android.view.View, View>>();
public _createUI() {
public _createNativeView() {
this._android = new android.widget.ListView(this._context);
this._android.setDescendantFocusability(android.view.ViewGroup.FOCUS_AFTER_DESCENDANTS);
this.updateEffectiveRowHeight();
@ -80,8 +80,8 @@ export class ListView extends ListViewBase {
}
}
public _onDetached(force?: boolean) {
super._onDetached(force);
public _disposeNativeView() {
super._disposeNativeView();
this.clearRealizedCells();
}
@ -183,7 +183,7 @@ function ensureListViewAdapterClass() {
public getItem(i: number) {
if (this._listView && this._listView.items && i < this._listView.items.length) {
let getItem = (<ItemsSource>this._listView.items).getItem
let getItem = (<ItemsSource>this._listView.items).getItem;
return getItem ? getItem(i) : this._listView.items[i];
}

View File

@ -68,8 +68,7 @@ function ensureDialogFragmentClass() {
}
this._owner._isAddedToNativeVisualTree = false;
this._owner._onDetached(true);
this._owner._tearDownUI(true);
}
public onDismiss(dialog: android.content.IDialogInterface) {
@ -94,7 +93,7 @@ export class Page extends PageBase {
return this._grid;
}
public _createUI() {
public _createNativeView() {
this._grid = new org.nativescript.widgets.GridLayout(this._context);
this._grid.addRow(new org.nativescript.widgets.ItemSpec(1, org.nativescript.widgets.GridUnitType.auto));
this._grid.addRow(new org.nativescript.widgets.ItemSpec(1, org.nativescript.widgets.GridUnitType.star));
@ -123,11 +122,11 @@ export class Page extends PageBase {
}
}
public _onDetached(force?: boolean) {
public _tearDownUI(force?: boolean) {
const skipDetached = !force && this.frame.android.cachePagesOnNavigate && !this._isBackNavigation;
if (!skipDetached) {
super._onDetached();
super._tearDownUI();
}
}
@ -145,7 +144,7 @@ export class Page extends PageBase {
this.backgroundColor = new Color("White");
}
this._onAttached(parent._context);
this._setupUI(parent._context);
this._isAddedToNativeVisualTree = true;
applyNativeSetters(this);

View File

@ -5,7 +5,7 @@ export class Placeholder extends PlaceholderDefinition {
private _android: android.view.View;
public _createUI() {
public _createNativeView() {
let args = <CreateViewEventData>{ eventName: Placeholder.creatingViewEvent, object: this, view: undefined, context: this._context };
this.notify(args);
this._android = <android.view.View>args.view;

View File

@ -10,7 +10,7 @@ const R_ATTR_PROGRESS_BAR_STYLE_HORIZONTAL = 0x01010078;
export class Progress extends ProgressBase {
private _android: android.widget.ProgressBar;
public _createUI() {
public _createNativeView() {
this._android = new android.widget.ProgressBar(this._context, null, R_ATTR_PROGRESS_BAR_STYLE_HORIZONTAL);
}

View File

@ -32,7 +32,7 @@ export class ProxyViewContainer extends LayoutBase implements ProxyViewContainer
return false;
}
public _createUI() {
public _createNativeView() {
//
}

View File

@ -71,7 +71,7 @@ export class ScrollView extends ScrollViewBase {
}
}
public _createUI() {
public _createNativeView() {
if (this.orientation === "horizontal") {
this._android = new org.nativescript.widgets.HorizontalScrollView(this._context);
} else {

View File

@ -78,7 +78,7 @@ export class SearchBar extends SearchBarBase {
return result;
}
public _createUI() {
public _createNativeView() {
this._android = new android.widget.SearchView(this._context);
this._android.setIconified(false);

View File

@ -184,7 +184,7 @@ export class SegmentedBar extends SegmentedBarBase {
private listener: android.widget.TabHost.OnTabChangeListener;
private tabContentFactory: android.widget.TabHost.TabContentFactory;
public _createUI() {
public _createNativeView() {
ensureTabHostClass();
ensureSegmentedBarColorDrawableClass();

View File

@ -37,7 +37,7 @@ export class Slider extends SliderBase {
private _android: android.widget.SeekBar;
private changeListener: android.widget.SeekBar.OnSeekBarChangeListener;
public _createUI() {
public _createNativeView() {
this.changeListener = this.changeListener || new SeekBarChangeListener(new WeakRef(this));
this._android = new android.widget.SeekBar(this._context);
this._android.setOnSeekBarChangeListener(this.changeListener);

View File

@ -28,7 +28,7 @@ export class Switch extends SwitchBase {
return this._android;
}
public _createUI() {
public _createNativeView() {
this._android = new android.widget.Switch(this._context);
this.listener = this.listener || new CheckedChangeListener(new WeakRef(this));
this._android.setOnCheckedChangeListener(this.listener);

View File

@ -184,7 +184,7 @@ export class TabView extends TabViewBase {
return this._grid;
}
public _createUI() {
public _createNativeView() {
if (traceEnabled) {
traceWrite("TabView._createUI(" + this + ");", traceCategory);
}

View File

@ -23,7 +23,7 @@ export class TimePicker extends TimePickerBase {
private _android: android.widget.TimePicker;
private _listener: android.widget.TimePicker.OnTimeChangedListener;
public _createUI() {
public _createNativeView() {
this._android = new android.widget.TimePicker(this._context);
this._listener = this._listener || new TimeChangedListener(new WeakRef(this));
this._android.setOnTimeChangedListener(this._listener);

View File

@ -402,7 +402,7 @@ function _completePageRemoval(fragment: any, isBack: boolean) {
if (expandedFragment.isDestroyed) {
expandedFragment.isDestroyed = undefined;
if (page._context) {
page._onDetached(true);
page._tearDownUI(true);
if (traceEnabled) {
traceWrite(`DETACHMENT of ${page} completed`, traceCategories.Transition);
}
@ -425,7 +425,7 @@ export function _removePageNativeViewFromAndroidParent(page: Page): void {
if (traceEnabled) {
traceWrite(`REMOVED ${page}._nativeView from its Android parent`, traceCategories.Transition);
}
page._onDetached(true);
page._tearDownUI(true);
androidParent.removeView(page._nativeView);
}
}

View File

@ -97,18 +97,18 @@ export class WebView extends WebViewBase {
return this._android;
}
public _createUI() {
public _createNativeView() {
this._android = new android.webkit.WebView(this._context);
this._android.getSettings().setJavaScriptEnabled(true);
this._android.getSettings().setBuiltInZoomControls(true);
this._android.setWebViewClient(this._webViewClient);
}
public _onDetached(force?: boolean) {
public _resetNativeView() {
if (this.android) {
this.android.destroy();
}
super._onDetached(force);
super._resetNativeView();
}
public _loadUrl(url: string) {