Group and view

This commit is contained in:
pengfei.zhou 2019-07-20 18:37:50 +08:00
parent e35ab68014
commit e85b60d05c
4 changed files with 112 additions and 12 deletions

View File

@ -5,7 +5,9 @@ import android.view.View;
import android.view.ViewGroup;
import com.github.penfeizhou.doric.DoricContext;
import com.github.penfeizhou.doric.DoricRegistry;
import com.github.penfeizhou.doric.utils.DoricComponent;
import com.github.penfeizhou.doric.utils.DoricMetaInfo;
import com.github.penfeizhou.doric.utils.DoricUtils;
import com.github.pengfeizhou.jscore.JSObject;
@ -15,18 +17,32 @@ import com.github.pengfeizhou.jscore.JSObject;
* @CreateDate: 2019-07-20
*/
public abstract class ViewNode<T extends View> extends DoricComponent {
private T mView;
private String mId;
public ViewNode(DoricContext doricContext) {
super(doricContext);
}
public abstract T build(JSObject jsObject);
public T getView() {
return mView;
}
private void setId(String id) {
mId = id;
}
public Context getContext() {
return getDoricContext().getContext();
}
public void config(T view, JSObject jsObject) {
setFrame(view.getLayoutParams(), jsObject);
public abstract T build(JSObject jsObject);
public void blend(JSObject jsObject) {
if (mView == null) {
mView = build(jsObject);
}
setFrame(mView.getLayoutParams(), jsObject);
}
public void setFrame(ViewGroup.LayoutParams layoutParams, JSObject jsObject) {
@ -41,4 +57,12 @@ public abstract class ViewNode<T extends View> extends DoricComponent {
((ViewGroup.MarginLayoutParams) layoutParams).topMargin = DoricUtils.dp2px(y);
}
}
public static ViewNode create(DoricContext doricContext, String id, String type) {
DoricRegistry registry = doricContext.getDriver().getRegistry();
DoricMetaInfo<ViewNode> clz = registry.acquireViewNodeInfo(type);
ViewNode node = clz.createInstance(doricContext);
node.setId(id);
return node;
}
}

View File

@ -7,21 +7,38 @@ import com.github.penfeizhou.doric.extension.render.ViewNode;
import com.github.pengfeizhou.jscore.JSArray;
import com.github.pengfeizhou.jscore.JSObject;
import java.util.HashMap;
import java.util.Map;
/**
* @Description: com.github.penfeizhou.doric.widget
* @Author: pengfei.zhou
* @CreateDate: 2019-07-20
*/
public abstract class GroupNode extends ViewNode<ViewGroup> {
private Map<String, ViewNode> mChildren = new HashMap<>();
public GroupNode(DoricContext doricContext) {
super(doricContext);
}
@Override
public void config(ViewGroup view, JSObject jsObject) {
super.config(view, jsObject);
public void blend(JSObject jsObject) {
super.blend(jsObject);
JSArray jsArray = jsObject.getProperty("children").asArray();
for (int i = 0; i < jsArray.size(); i++) {
JSObject childObj = jsArray.get(i).asObject();
String type = childObj.getProperty("type").asString().value();
String id = childObj.getProperty("id").asString().value();
ViewNode child = mChildren.get(id);
if (child == null) {
child = ViewNode.create(getDoricContext(), id, type);
mChildren.put(id, child);
}
if (getView().getChildAt(i) == null) {
getView().addView(child.getView());
}
child.blend(childObj.getProperty("props").asObject());
}
}
}

View File

@ -1,5 +1,5 @@
import { Color, GradientColor } from "../util/color"
import { Modeling, Model } from "../util/types";
import { Modeling, Model, obj2Model } from "../util/types";
import "reflect-metadata"
import { uniqueId } from "../util/uniqueId";
import { loge } from "../util/log";
@ -42,6 +42,8 @@ export abstract class View implements Modeling {
@Property
viewId = uniqueId('ViewId')
parent?: Group
callbacks: Map<String, Function> = new Map
private callback2Id(f: Function) {
@ -107,12 +109,21 @@ export abstract class View implements Modeling {
onPropertyChanged(propKey: string, oldV: Model, newV: Model): void {
if (newV instanceof Function) {
newV = this.callback2Id(newV)
} else if (newV instanceof Object
&& Reflect.has(newV, 'toModel')
&& Reflect.get(newV, 'toModel') instanceof Function) {
newV = Reflect.apply(Reflect.get(newV, 'toModel'), newV, [])
} else {
newV = obj2Model(newV)
}
this.__dirty_props__[propKey] = newV
if (this.parent instanceof Group) {
this.parent.onChildPropertyChanged(this, propKey, oldV, newV)
}
}
clean() {
for (const key in this.__dirty_props__) {
if (this.__dirty_props__.hasOwnProperty(key)) {
this.__dirty_props__[key] = undefined
}
}
}
responseCallback(id: string) {
@ -180,8 +191,43 @@ export interface LayoutConfig extends Config {
}
export abstract class Group extends View {
@Property
children: View[] = []
children: View[] = new Proxy([], {
set: (target, index, value) => {
if (typeof index === 'number' && value instanceof View) {
value.parent = this
const childrenModel = this.getDirtyChildrenModel()
childrenModel[index] = value.toModel()
} else if (index === 'length') {
this.getDirtyChildrenModel().length = value as number
}
return Reflect.set(target, index, value)
}
})
clean() {
this.children.forEach(e => { e.clean() })
super.clean()
}
getDirtyChildrenModel(): Model[] {
if (this.__dirty_props__.children === undefined) {
this.__dirty_props__.children = []
}
return this.__dirty_props__.children as Model[]
}
toModel() {
if (this.__dirty_props__.children != undefined) {
(this.__dirty_props__.children as Model[]).length = this.children.length
}
return super.toModel()
}
onChildPropertyChanged(child: View, propKey: string, oldV: Model, newV: Model) {
}
}
export class Stack extends Group {

View File

@ -1,5 +1,18 @@
export interface Modeling {
toModel(): Model
}
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 {
return obj
}
}
export type Model = string | number | boolean | Modeling | { [index: string]: Model | undefined }
type _M = string | number | boolean | Modeling | { [index: string]: Model | undefined }
export type Model = _M | Array<_M>