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 929f3282..01ab1b6f 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 @@ -1,7 +1,6 @@ package com.github.penfeizhou.doric.shader; import android.util.SparseArray; -import android.view.View; import android.view.ViewGroup; import com.github.penfeizhou.doric.DoricContext; @@ -26,50 +25,59 @@ public abstract class GroupNode extends ViewNode { } @Override - public void blend(JSObject jsObject, ViewGroup.LayoutParams layoutParams) { - super.blend(jsObject, layoutParams); - JSArray jsArray = jsObject.getProperty("children").asArray(); - int i; - for (i = 0; i < jsArray.size(); i++) { - JSValue jsValue = jsArray.get(i); - if (!jsValue.isObject()) { - continue; - } - JSObject childObj = jsValue.asObject(); - String type = childObj.getProperty("type").asString().value(); - String id = childObj.getProperty("id").asString().value(); - ViewNode child = mChildrenNode.get(id); - if (child == null) { - child = ViewNode.create(getDoricContext(), type); - child.index = i; - child.mParent = this; - child.mId = id; - mChildrenNode.put(id, child); - } else if (i != child.index) { - mIndexInfo.remove(i); - child.index = i; - mView.removeView(child.mView); - } - ViewGroup.LayoutParams params = child.getLayoutParams(); - if (params == null) { - params = generateDefaultLayoutParams(); - } - child.blend(childObj.getProperty("props").asObject(), params); - if (mIndexInfo.get(i) == null) { - mView.addView(child.mView, i); - mIndexInfo.put(i, child); - } - } - while (i < mView.getChildCount()) { - mView.removeViewAt(mView.getChildCount() - 1); - if (mIndexInfo.get(i) != null) { - mChildrenNode.remove(mIndexInfo.get(i).getId()); - mIndexInfo.remove(i); - } + protected void blend(F view, ViewGroup.LayoutParams layoutParams, String name, JSValue prop) { + super.blend(view, layoutParams, name, prop); + switch (name) { + case "children": + JSArray jsArray = prop.asArray(); + int i; + for (i = 0; i < jsArray.size(); i++) { + JSValue jsValue = jsArray.get(i); + if (!jsValue.isObject()) { + continue; + } + JSObject childObj = jsValue.asObject(); + String type = childObj.getProperty("type").asString().value(); + String id = childObj.getProperty("id").asString().value(); + ViewNode child = mChildrenNode.get(id); + if (child == null) { + child = ViewNode.create(getDoricContext(), type); + child.index = i; + child.mParent = this; + child.mId = id; + mChildrenNode.put(id, child); + } else if (i != child.index) { + mIndexInfo.remove(i); + child.index = i; + mView.removeView(child.mView); + } + ViewGroup.LayoutParams params = child.getLayoutParams(); + if (params == null) { + params = generateDefaultLayoutParams(); + } + child.blend(childObj.getProperty("props").asObject(), params); + if (mIndexInfo.get(i) == null) { + mView.addView(child.mView, i); + mIndexInfo.put(i, child); + } + } + while (i < mView.getChildCount()) { + mView.removeViewAt(mView.getChildCount() - 1); + if (mIndexInfo.get(i) != null) { + mChildrenNode.remove(mIndexInfo.get(i).getId()); + mIndexInfo.remove(i); + } + } + break; + default: + super.blend(view, layoutParams, name, prop); + break; } } protected ViewGroup.LayoutParams generateDefaultLayoutParams() { return new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); } + + public abstract void blendChild(ViewNode viewNode, JSObject jsObject); } diff --git a/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/LinearNode.java b/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/LinearNode.java index a1c32f4d..e3aedc5a 100644 --- a/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/LinearNode.java +++ b/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/LinearNode.java @@ -19,6 +19,14 @@ public class LinearNode extends GroupNode { super(doricContext); } + @Override + public void blendChild(ViewNode viewNode, JSObject layoutConfig) { + JSValue jsValue = layoutConfig.getProperty("alignment"); + if (jsValue.isNumber()) { + ((LinearLayout.LayoutParams) viewNode.getLayoutParams()).gravity = jsValue.asNumber().toInt(); + } + } + @Override public LinearLayout build(JSObject jsObject) { return new LinearLayout(getContext()); diff --git a/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/RootNode.java b/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/RootNode.java index 2dc96011..873c8eba 100644 --- a/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/RootNode.java +++ b/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/RootNode.java @@ -12,16 +12,11 @@ import com.github.pengfeizhou.jscore.JSObject; * @CreateDate: 2019-07-20 */ @DoricPlugin(name = "Root") -public class RootNode extends GroupNode { +public class RootNode extends StackNode { public RootNode(DoricContext doricContext) { super(doricContext); } - @Override - public FrameLayout build(JSObject jsObject) { - return new FrameLayout(getContext()); - } - public void setRootView(FrameLayout rootView) { this.mView = rootView; } diff --git a/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/StackNode.java b/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/StackNode.java index 46c3e6cb..a4b0516b 100644 --- a/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/StackNode.java +++ b/Android/doric/src/main/java/com/github/penfeizhou/doric/shader/StackNode.java @@ -19,6 +19,14 @@ public class StackNode extends GroupNode { super(doricContext); } + @Override + public void blendChild(ViewNode viewNode, JSObject jsObject) { + JSValue jsValue = jsObject.getProperty("alignment"); + if (jsValue.isNumber()) { + ((FrameLayout.LayoutParams) viewNode.getLayoutParams()).gravity = jsValue.asNumber().toInt(); + } + } + @Override public FrameLayout build(JSObject jsObject) { return new FrameLayout(getContext()); @@ -34,4 +42,9 @@ public class StackNode extends GroupNode { super.blend(view, layoutParams, name, prop); } } + + @Override + protected ViewGroup.LayoutParams generateDefaultLayoutParams() { + return new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + } } 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 9ba8c5c4..9bf8960c 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 @@ -25,8 +25,9 @@ import java.util.LinkedList; public abstract class ViewNode extends DoricComponent { protected T mView; int index; - ViewNode mParent; + GroupNode mParent; String mId; + private ViewGroup.LayoutParams mLayoutParams; public ViewNode(DoricContext doricContext) { super(doricContext); @@ -43,6 +44,7 @@ public abstract class ViewNode extends DoricComponent { public abstract T build(JSObject jsObject); void blend(JSObject jsObject, ViewGroup.LayoutParams layoutParams) { + mLayoutParams = layoutParams; if (mView == null) { mView = build(jsObject); } @@ -93,14 +95,8 @@ public abstract class ViewNode extends DoricComponent { }); break; case "layoutConfig": - JSObject layoutConfig = prop.asObject(); - JSValue jsValue = layoutConfig.getProperty("alignment"); - if (jsValue.isNumber()) { - if (layoutParams instanceof LinearLayout.LayoutParams) { - ((LinearLayout.LayoutParams) layoutParams).gravity = jsValue.asNumber().toInt(); - } else if (layoutParams instanceof FrameLayout.LayoutParams) { - ((FrameLayout.LayoutParams) layoutParams).gravity = jsValue.asNumber().toInt(); - } + if (prop.isObject() && mParent != null) { + mParent.blendChild(this, prop.asObject()); } break; default: @@ -136,10 +132,7 @@ public abstract class ViewNode extends DoricComponent { } public ViewGroup.LayoutParams getLayoutParams() { - if (mView != null) { - return mView.getLayoutParams(); - } - return null; + return mLayoutParams; } public String getId() { diff --git a/js-framework/demo.ts b/js-framework/demo.ts index fe9e9e7a..e7ed47e9 100644 --- a/js-framework/demo.ts +++ b/js-framework/demo.ts @@ -1,4 +1,5 @@ import { Gravity, Mutable, NativeCall, Text, Color, VLayout, Panel, log, logw, loge, Group, Stack, } from "./index" +import { WRAP_CONTENT } from "./src/ui/view"; @Entry @@ -7,14 +8,16 @@ export class MyPage extends Panel { build(rootView: Group): void { const state = Mutable.of(1) const numberView = new Text - numberView.width = 100 - numberView.height = 200 + numberView.width = WRAP_CONTENT + numberView.height = WRAP_CONTENT numberView.top = 50 state.bind((v) => { numberView.text = v.toString() }) numberView.textSize = 40 - numberView.centerX = rootView.width / 2 + numberView.layoutConfig = { + alignment: new Gravity().centerX() + } rootView.addChild(numberView) const click = new Text click.textSize = 20 @@ -22,7 +25,7 @@ export class MyPage extends Panel { click.onClick = () => { state.set(state.get() + 1) } - click.top = numberView.bottom + 20 + click.top = 200 click.layoutConfig = { alignment: new Gravity().centerX() @@ -33,24 +36,17 @@ export class MyPage extends Panel { const vlayout = new VLayout vlayout.width = this.getRootView().width vlayout.height = 500 - + vlayout.bgColor = Color.parse('#ff00ff') vlayout.top = 50 vlayout.centerX = this.getRootView().width / 2 vlayout.space = 0 vlayout.gravity = (new Gravity()).bottom() - const v = [1, 2, 3,].map(e => { + vlayout.onClick = () => { const stack = new Stack stack.width = stack.height = 50 stack.bgColor = Color.safeParse('#00ff00') vlayout.addChild(stack) - stack.onClick = () => { - loge('stack:onClick') - if (vlayout.space !== undefined) { - loge('change space') - vlayout.space += 10 - } - } - }) + } rootView.addChild(vlayout) } diff --git a/js-framework/src/ui/view.ts b/js-framework/src/ui/view.ts index d22286e7..bd4bf4e5 100644 --- a/js-framework/src/ui/view.ts +++ b/js-framework/src/ui/view.ts @@ -140,7 +140,7 @@ export abstract class View implements Modeling { } this.__dirty_props__[propKey] = newV if (this.parent instanceof Group) { - this.parent.onChildPropertyChanged(this, propKey, oldV, newV) + this.parent.onChildPropertyChanged(this) } } @@ -220,6 +220,10 @@ export abstract class Group extends View { const childrenModel = this.getDirtyChildrenModel() childrenModel[parseInt(index)] = value.nativeViewModel } + if (this.parent) { + this.parent.onChildPropertyChanged(this) + } + return Reflect.set(target, index, value) } }) @@ -246,9 +250,13 @@ export abstract class Group extends View { return super.toModel() } - onChildPropertyChanged(child: View, propKey: string, oldV: Model, newV: Model) { + onChildPropertyChanged(child: View) { this.getDirtyChildrenModel()[this.children.indexOf(child)] = child.nativeViewModel } + + isDirty() { + return super.isDirty() + } } export class Stack extends Group {