diff --git a/Android/app/src/main/res/layout/activity_main.xml b/Android/app/src/main/res/layout/activity_main.xml index 04dce6cd..8cef2709 100644 --- a/Android/app/src/main/res/layout/activity_main.xml +++ b/Android/app/src/main/res/layout/activity_main.xml @@ -1,22 +1,12 @@ - - + android:layout_height="match_parent" /> \ No newline at end of file diff --git a/Android/doric/src/main/java/com/github/penfeizhou/doric/plugin/ShaderPlugin.java b/Android/doric/src/main/java/com/github/penfeizhou/doric/plugin/ShaderPlugin.java index d0a602ce..7919aa72 100644 --- a/Android/doric/src/main/java/com/github/penfeizhou/doric/plugin/ShaderPlugin.java +++ b/Android/doric/src/main/java/com/github/penfeizhou/doric/plugin/ShaderPlugin.java @@ -30,7 +30,7 @@ public class ShaderPlugin extends DoricJavaPlugin { @Override public Object call() throws Exception { RootNode rootNode = getDoricContext().getRootNode(); - rootNode.blend(jsObject.getProperty("props").asObject()); + rootNode.render(jsObject.getProperty("props").asObject()); return null; } }, ThreadMode.UI); 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 5e69303e..929f3282 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,6 +1,7 @@ package com.github.penfeizhou.doric.shader; import android.util.SparseArray; +import android.view.View; import android.view.ViewGroup; import com.github.penfeizhou.doric.DoricContext; @@ -25,8 +26,8 @@ public abstract class GroupNode extends ViewNode { } @Override - public void blend(JSObject jsObject) { - super.blend(jsObject); + 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++) { @@ -41,15 +42,19 @@ public abstract class GroupNode extends ViewNode { if (child == null) { child = ViewNode.create(getDoricContext(), type); child.index = i; - child.ids.addAll(this.ids); - child.ids.add(id); + 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); } - child.blend(childObj.getProperty("props").asObject()); + 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); @@ -63,4 +68,8 @@ public abstract class GroupNode extends ViewNode { } } } + + protected ViewGroup.LayoutParams generateDefaultLayoutParams() { + return new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + } } 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 35fb7a77..a1c32f4d 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 @@ -1,6 +1,7 @@ package com.github.penfeizhou.doric.shader; import android.graphics.drawable.ShapeDrawable; +import android.view.ViewGroup; import android.widget.LinearLayout; import com.github.penfeizhou.doric.DoricContext; @@ -24,7 +25,7 @@ public class LinearNode extends GroupNode { } @Override - protected void blend(LinearLayout view, String name, JSValue prop) { + protected void blend(LinearLayout view, ViewGroup.LayoutParams params, String name, JSValue prop) { switch (name) { case "space": ShapeDrawable shapeDrawable; @@ -47,7 +48,7 @@ public class LinearNode extends GroupNode { view.setGravity(prop.asNumber().toInt()); break; default: - super.blend(view, name, prop); + super.blend(view, params, name, prop); break; } } 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 4a571fac..2dc96011 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 @@ -25,4 +25,8 @@ public class RootNode extends GroupNode { public void setRootView(FrameLayout rootView) { this.mView = rootView; } + + public void render(JSObject props) { + blend(props, mView.getLayoutParams()); + } } 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 5d3274ab..46c3e6cb 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 @@ -1,5 +1,6 @@ package com.github.penfeizhou.doric.shader; +import android.view.ViewGroup; import android.widget.FrameLayout; import com.github.penfeizhou.doric.DoricContext; @@ -24,13 +25,13 @@ public class StackNode extends GroupNode { } @Override - protected void blend(FrameLayout view, String name, JSValue prop) { + protected void blend(FrameLayout view, ViewGroup.LayoutParams layoutParams, String name, JSValue prop) { switch (name) { case "gravity": view.setForegroundGravity(prop.asNumber().toInt()); break; default: - super.blend(view, name, prop); + super.blend(view, layoutParams, name, prop); } } } 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 5d31b856..62b623e2 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 @@ -1,6 +1,7 @@ package com.github.penfeizhou.doric.shader; import android.util.TypedValue; +import android.view.ViewGroup; import android.widget.TextView; import com.github.penfeizhou.doric.DoricContext; @@ -25,7 +26,7 @@ public class TextNode extends ViewNode { } @Override - protected void blend(TextView view, String name, JSValue prop) { + protected void blend(TextView view, ViewGroup.LayoutParams params, String name, JSValue prop) { switch (name) { case "text": view.setText(prop.asString().toString()); @@ -37,7 +38,7 @@ public class TextNode extends ViewNode { view.setTextColor(prop.asNumber().toInt()); break; default: - super.blend(view, name, prop); + super.blend(view, params, 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 45904cb2..9ba8c5c4 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 @@ -3,6 +3,8 @@ package com.github.penfeizhou.doric.shader; import android.content.Context; import android.view.View; import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.LinearLayout; import com.github.penfeizhou.doric.DoricContext; import com.github.penfeizhou.doric.DoricRegistry; @@ -13,7 +15,7 @@ import com.github.penfeizhou.doric.utils.DoricUtils; import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSValue; -import java.util.ArrayList; +import java.util.LinkedList; /** * @Description: Render @@ -23,8 +25,8 @@ import java.util.ArrayList; public abstract class ViewNode extends DoricComponent { protected T mView; int index; - - ArrayList ids = new ArrayList<>(); + ViewNode mParent; + String mId; public ViewNode(DoricContext doricContext) { super(doricContext); @@ -40,47 +42,42 @@ public abstract class ViewNode extends DoricComponent { public abstract T build(JSObject jsObject); - void blend(JSObject jsObject) { + void blend(JSObject jsObject, ViewGroup.LayoutParams layoutParams) { if (mView == null) { mView = build(jsObject); } - if (mView.getLayoutParams() == null) { - mView.setLayoutParams(new ViewGroup.MarginLayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT)); - } for (String prop : jsObject.propertySet()) { - blend(mView, prop, jsObject.getProperty(prop)); + blend(mView, layoutParams, prop, jsObject.getProperty(prop)); } - mView.setLayoutParams(mView.getLayoutParams()); + mView.setLayoutParams(layoutParams); } - protected void blend(T view, String name, JSValue prop) { + protected void blend(T view, ViewGroup.LayoutParams layoutParams, String name, JSValue prop) { switch (name) { case "width": if (prop.asNumber().toInt() < 0) { - view.getLayoutParams().width = prop.asNumber().toInt(); + layoutParams.width = prop.asNumber().toInt(); } else { - view.getLayoutParams().width = DoricUtils.dp2px(prop.asNumber().toFloat()); + layoutParams.width = DoricUtils.dp2px(prop.asNumber().toFloat()); } break; case "height": if (prop.asNumber().toInt() < 0) { - view.getLayoutParams().height = prop.asNumber().toInt(); + layoutParams.height = prop.asNumber().toInt(); } else { - view.getLayoutParams().height = DoricUtils.dp2px(prop.asNumber().toFloat()); + layoutParams.height = DoricUtils.dp2px(prop.asNumber().toFloat()); } break; case "x": - if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) { + if (layoutParams instanceof ViewGroup.MarginLayoutParams) { float x = prop.asNumber().toFloat(); - ((ViewGroup.MarginLayoutParams) mView.getLayoutParams()).leftMargin = DoricUtils.dp2px(x); + ((ViewGroup.MarginLayoutParams) layoutParams).leftMargin = DoricUtils.dp2px(x); } break; case "y": - if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) { + if (layoutParams instanceof ViewGroup.MarginLayoutParams) { float y = prop.asNumber().toFloat(); - ((ViewGroup.MarginLayoutParams) mView.getLayoutParams()).topMargin = DoricUtils.dp2px(y); + ((ViewGroup.MarginLayoutParams) layoutParams).topMargin = DoricUtils.dp2px(y); } break; case "bgColor": @@ -95,31 +92,36 @@ 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(); + } + } + break; default: break; } } - public String getId() { - return ids.get(ids.size() - 1); - } + String[] getIdList() { + LinkedList ids = new LinkedList<>(); + ViewNode viewNode = this; + do { + ids.push(viewNode.mId); + viewNode = viewNode.mParent; + } while (viewNode != null && !(viewNode instanceof RootNode)); - public void setFrame(ViewGroup.LayoutParams layoutParams, JSObject jsObject) { - float width = jsObject.getProperty("width").asNumber().toFloat(); - float height = jsObject.getProperty("height").asNumber().toFloat(); - layoutParams.width = DoricUtils.dp2px(width); - layoutParams.height = DoricUtils.dp2px(height); - if (layoutParams instanceof ViewGroup.MarginLayoutParams) { - float x = jsObject.getProperty("x").asNumber().toFloat(); - float y = jsObject.getProperty("y").asNumber().toFloat(); - ((ViewGroup.MarginLayoutParams) layoutParams).leftMargin = DoricUtils.dp2px(x); - ((ViewGroup.MarginLayoutParams) layoutParams).topMargin = DoricUtils.dp2px(y); - } + return ids.toArray(new String[0]); } public void callJSResponse(String funcId, Object... args) { final Object[] nArgs = new Object[args.length + 2]; - nArgs[0] = ids.toArray(new String[0]); + nArgs[0] = getIdList(); nArgs[1] = funcId; if (args.length > 0) { System.arraycopy(args, 0, nArgs, 2, args.length); @@ -132,4 +134,15 @@ public abstract class ViewNode extends DoricComponent { DoricMetaInfo clz = registry.acquireViewNodeInfo(type); return clz.createInstance(doricContext); } + + public ViewGroup.LayoutParams getLayoutParams() { + if (mView != null) { + return mView.getLayoutParams(); + } + return null; + } + + public String getId() { + return mId; + } } diff --git a/js-framework/demo.ts b/js-framework/demo.ts index d3255c76..fe9e9e7a 100644 --- a/js-framework/demo.ts +++ b/js-framework/demo.ts @@ -23,6 +23,11 @@ export class MyPage extends Panel { state.set(state.get() + 1) } click.top = numberView.bottom + 20 + + click.layoutConfig = { + alignment: new Gravity().centerX() + } + rootView.addChild(click) const vlayout = new VLayout diff --git a/js-framework/src/ui/view.ts b/js-framework/src/ui/view.ts index 11e12799..d22286e7 100644 --- a/js-framework/src/ui/view.ts +++ b/js-framework/src/ui/view.ts @@ -182,7 +182,7 @@ export abstract class View implements Modeling { } @Property - config?: Config + layoutConfig?: Config @Property onClick?: Function diff --git a/js-framework/src/util/types.ts b/js-framework/src/util/types.ts index b42a90bb..477f6147 100644 --- a/js-framework/src/util/types.ts +++ b/js-framework/src/util/types.ts @@ -4,11 +4,17 @@ export interface Modeling { export function obj2Model(obj: Model): Model { if (obj instanceof Array) { return obj.map(e => obj2Model(e)) as Model - } else if (obj instanceof Object - && Reflect.has(obj, 'toModel') - && Reflect.get(obj, 'toModel') instanceof Function) { - obj = Reflect.apply(Reflect.get(obj, 'toModel'), obj, []) - return obj + } else if (obj instanceof Object) { + if (Reflect.has(obj, 'toModel') && Reflect.get(obj, 'toModel') instanceof Function) { + obj = Reflect.apply(Reflect.get(obj, 'toModel'), obj, []) + return obj + } else { + for (let key in obj) { + const val = Reflect.get(obj, key) + Reflect.set(obj, key, obj2Model(val)) + } + return obj + } } else { return obj } diff --git a/js-framework/src/vm/viewmodel.ts b/js-framework/src/vm/viewmodel.ts new file mode 100644 index 00000000..74b28ed2 --- /dev/null +++ b/js-framework/src/vm/viewmodel.ts @@ -0,0 +1,11 @@ +export class ViewModel { + data: T + constructor(obj: T) { + this.data = new Proxy(obj, { + get: () => { + + } + }) + } + +} \ No newline at end of file