diff --git a/Android/app/src/main/java/com/github/penfeizhou/doricdemo/MainActivity.java b/Android/app/src/main/java/com/github/penfeizhou/doricdemo/MainActivity.java index 6918a85f..31ce23db 100644 --- a/Android/app/src/main/java/com/github/penfeizhou/doricdemo/MainActivity.java +++ b/Android/app/src/main/java/com/github/penfeizhou/doricdemo/MainActivity.java @@ -8,6 +8,7 @@ import com.github.penfeizhou.doric.DoricContext; import com.github.penfeizhou.doric.utils.DoricUtils; import com.github.pengfeizhou.jscore.JSONBuilder; + public class MainActivity extends AppCompatActivity { @Override @@ -15,8 +16,11 @@ public class MainActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DoricContext doricContext = DoricContext.create(this, DoricUtils.readAssetFile("demo.js"), "demo"); - doricContext.callEntity("__init__", new JSONBuilder().put("width", 100).put("height", 100)); + doricContext.callEntity("__init__", new JSONBuilder() + .put("width", DoricUtils.px2dp(DoricUtils.getScreenWidth())) + .put("height", DoricUtils.px2dp(DoricUtils.getScreenHeight()))); doricContext.callEntity("log"); doricContext.getRootNode().setRootView((FrameLayout) findViewById(R.id.root)); } + } diff --git a/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/GroupNode.java b/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/GroupNode.java index 4e1c4580..5e69303e 100644 --- a/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/GroupNode.java +++ b/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/GroupNode.java @@ -44,15 +44,16 @@ public abstract class GroupNode extends ViewNode { child.ids.addAll(this.ids); child.ids.add(id); mChildrenNode.put(id, child); - mView.addView(child.mView, i); } else if (i != child.index) { - mIndexInfo.remove(child.index); + mIndexInfo.remove(i); child.index = i; mView.removeView(child.mView); - mView.addView(child.mView, i); } child.blend(childObj.getProperty("props").asObject()); - mIndexInfo.put(i, child); + if (mIndexInfo.get(i) == null) { + mView.addView(child.mView, i); + mIndexInfo.put(i, child); + } } while (i < mView.getChildCount()) { mView.removeViewAt(mView.getChildCount() - 1); diff --git a/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/TextNode.java b/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/TextNode.java index 731cfdf6..f6e55430 100644 --- a/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/TextNode.java +++ b/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/TextNode.java @@ -5,6 +5,7 @@ import android.widget.TextView; import com.github.penfeizhou.doric.DoricContext; import com.github.penfeizhou.doric.extension.bridge.DoricPlugin; import com.github.pengfeizhou.jscore.JSObject; +import com.github.pengfeizhou.jscore.JSValue; /** * @Description: widget @@ -21,4 +22,16 @@ public class TextNode extends ViewNode { public TextView build(JSObject jsObject) { return new TextView(getContext()); } + + @Override + protected void blend(TextView view, String name, JSValue prop) { + switch (name) { + case "text": + view.setText(prop.asString().toString()); + break; + default: + super.blend(view, name, prop); + break; + } + } } diff --git a/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/ViewNode.java b/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/ViewNode.java index a20bd3c9..c6b6c4cf 100644 --- a/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/ViewNode.java +++ b/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/ViewNode.java @@ -11,6 +11,7 @@ import com.github.penfeizhou.doric.utils.DoricConstant; import com.github.penfeizhou.doric.utils.DoricMetaInfo; import com.github.penfeizhou.doric.utils.DoricUtils; import com.github.pengfeizhou.jscore.JSObject; +import com.github.pengfeizhou.jscore.JSValue; import java.util.ArrayList; @@ -39,7 +40,7 @@ public abstract class ViewNode extends DoricComponent { public abstract T build(JSObject jsObject); - public void blend(JSObject jsObject) { + void blend(JSObject jsObject) { if (mView == null) { mView = build(jsObject); } @@ -48,7 +49,38 @@ public abstract class ViewNode extends DoricComponent { ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); } - setFrame(mView.getLayoutParams(), jsObject); + for (String prop : jsObject.propertySet()) { + blend(mView, prop, jsObject.getProperty(prop)); + } + mView.setLayoutParams(mView.getLayoutParams()); + } + + protected void blend(T view, String name, JSValue prop) { + switch (name) { + case "width": + view.getLayoutParams().width = DoricUtils.dp2px(prop.asNumber().toFloat()); + break; + case "height": + view.getLayoutParams().height = DoricUtils.dp2px(prop.asNumber().toFloat()); + break; + case "x": + if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) { + float x = prop.asNumber().toFloat(); + ((ViewGroup.MarginLayoutParams) mView.getLayoutParams()).leftMargin = DoricUtils.dp2px(x); + } + break; + case "y": + if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) { + float y = prop.asNumber().toFloat(); + ((ViewGroup.MarginLayoutParams) mView.getLayoutParams()).topMargin = DoricUtils.dp2px(y); + } + break; + case "bgColor": + view.setBackgroundColor(prop.asNumber().toInt()); + break; + default: + break; + } } public String getId() { diff --git a/js-framework/demo.ts b/js-framework/demo.ts index 6695eb0f..7b27fc0e 100644 --- a/js-framework/demo.ts +++ b/js-framework/demo.ts @@ -5,13 +5,16 @@ import { Group } from "./src/ui/view"; @Entry export class MyPage extends Panel { - + text?: Text build(rootView: Group): void { - log('build view') - const text = new Text - text.text = "hello" - rootView.children.push(text) + this.text = new Text + this.text.text = "hello" + this.text.width = 50 + this.text.height = 50 + this.text.y = 100 + rootView.children.push(this.text) rootView.bgColor = Color.safeParse('#00ff00') + log('build view:', JSON.stringify(rootView.toModel())) } @NativeCall @@ -19,18 +22,29 @@ export class MyPage extends Panel { log("Hello.HEGO") logw("Hello.HEGO") loge("Hello.HEGO") + context.demo.testPromise(true).then((r) => { log('resolve', r) }, (e) => { log('reject', e) }) + context.demo.testPromise(false).then((r) => { log('resolve', r) }, (e) => { log('reject', e) }) + setTimeout(function () { log('settimeout') }, 1000) + + setInterval(() => { + log('setInterval') + if (this.text) { + this.text.y += 10 + } + log('build view:', JSON.stringify(this.getRootView().toModel())) + }, 1000) } } \ No newline at end of file diff --git a/js-framework/src/ui/panel.ts b/js-framework/src/ui/panel.ts index 306449ba..654e30a2 100644 --- a/js-framework/src/ui/panel.ts +++ b/js-framework/src/ui/panel.ts @@ -25,10 +25,10 @@ export abstract class Panel { abstract build(rootView: Group): void private __data__: any - private __rootView__ = new Root + private __root__ = new Root getRootView() { - return this.__rootView__ + return this.__root__ } getInitData() { return this.__data__ @@ -38,9 +38,9 @@ export abstract class Panel { private __init__(frame: Frame, data: any) { log('__init__:', frame, data) this.__data__ = data - this.__rootView__.width = frame.width - this.__rootView__.height = frame.height - this.build(this.__rootView__) + this.__root__.width = frame.width + this.__root__.height = frame.height + this.build(this.__root__) } @NativeCall @@ -65,7 +65,7 @@ export abstract class Panel { @NativeCall private __build__() { - this.build(this.__rootView__) + this.build(this.__root__) } @NativeCall @@ -87,7 +87,7 @@ export abstract class Panel { return acc.children.filter(e => e.viewId === cur)[0] } return acc - }, this.__rootView__) + }, this.__root__) } private nativeRender(model: Model) { @@ -100,10 +100,10 @@ export abstract class Panel { } private hookAfterNativeCall() { - if (this.__rootView__.isDirty()) { - const model = this.__rootView__.toModel() + if (this.__root__.isDirty()) { + const model = this.__root__.toModel() this.nativeRender(model) - this.__rootView__.clean() + this.__root__.clean() } } diff --git a/js-framework/src/ui/view.ts b/js-framework/src/ui/view.ts index 184ac3ee..e37bf41a 100644 --- a/js-framework/src/ui/view.ts +++ b/js-framework/src/ui/view.ts @@ -61,11 +61,11 @@ export abstract class View implements Modeling { get: (target, p) => { return Reflect.get(target, p) }, - set: (target, p, v) => { + set: (target, p, v, receiver) => { const oldV = Reflect.get(target, p) const ret = Reflect.set(target, p, v) if (Reflect.getMetadata(p, target)) { - this.onPropertyChanged(p.toString(), oldV, v) + receiver.onPropertyChanged(p.toString(), oldV, v) } return ret } @@ -105,6 +105,12 @@ export abstract class View implements Modeling { __dirty_props__: { [index: string]: Model | undefined } = {} + nativeViewModel = { + id: this.viewId, + type: this.constructor.name, + props: this.__dirty_props__, + } + onPropertyChanged(propKey: string, oldV: Model, newV: Model): void { if (newV instanceof Function) { newV = this.callback2Id(newV) @@ -139,12 +145,9 @@ export abstract class View implements Modeling { loge(`Cannot find callback:${id} for ${JSON.stringify(this.toModel())}`) } } + toModel() { - return { - id: this.viewId, - type: this.constructor.name, - props: this.__dirty_props__, - } + return this.nativeViewModel } @Property @@ -196,12 +199,14 @@ export abstract class Group extends View { @Property children: View[] = new Proxy([], { set: (target, index, value) => { - if (typeof index === 'number' && value instanceof View) { + if (index === 'length') { + this.getDirtyChildrenModel().length = value as number + } else if (typeof index === 'string' + && parseInt(index) >= 0 + && value instanceof View) { value.parent = this const childrenModel = this.getDirtyChildrenModel() - childrenModel[index] = value.toModel() - } else if (index === 'length') { - this.getDirtyChildrenModel().length = value as number + childrenModel[parseInt(index)] = value.nativeViewModel } return Reflect.set(target, index, value) } @@ -227,7 +232,8 @@ export abstract class Group extends View { } onChildPropertyChanged(child: View, propKey: string, oldV: Model, newV: Model) { - + loge('onChildPropertyChanged:' + (this.children.indexOf(child))) + this.getDirtyChildrenModel()[this.children.indexOf(child)] = child.nativeViewModel } }