Group and view
This commit is contained in:
parent
e35ab68014
commit
e85b60d05c
@ -5,7 +5,9 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.github.penfeizhou.doric.DoricContext;
|
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.DoricComponent;
|
||||||
|
import com.github.penfeizhou.doric.utils.DoricMetaInfo;
|
||||||
import com.github.penfeizhou.doric.utils.DoricUtils;
|
import com.github.penfeizhou.doric.utils.DoricUtils;
|
||||||
import com.github.pengfeizhou.jscore.JSObject;
|
import com.github.pengfeizhou.jscore.JSObject;
|
||||||
|
|
||||||
@ -15,18 +17,32 @@ import com.github.pengfeizhou.jscore.JSObject;
|
|||||||
* @CreateDate: 2019-07-20
|
* @CreateDate: 2019-07-20
|
||||||
*/
|
*/
|
||||||
public abstract class ViewNode<T extends View> extends DoricComponent {
|
public abstract class ViewNode<T extends View> extends DoricComponent {
|
||||||
|
private T mView;
|
||||||
|
private String mId;
|
||||||
|
|
||||||
public ViewNode(DoricContext doricContext) {
|
public ViewNode(DoricContext doricContext) {
|
||||||
super(doricContext);
|
super(doricContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract T build(JSObject jsObject);
|
public T getView() {
|
||||||
|
return mView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setId(String id) {
|
||||||
|
mId = id;
|
||||||
|
}
|
||||||
|
|
||||||
public Context getContext() {
|
public Context getContext() {
|
||||||
return getDoricContext().getContext();
|
return getDoricContext().getContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void config(T view, JSObject jsObject) {
|
public abstract T build(JSObject jsObject);
|
||||||
setFrame(view.getLayoutParams(), jsObject);
|
|
||||||
|
public void blend(JSObject jsObject) {
|
||||||
|
if (mView == null) {
|
||||||
|
mView = build(jsObject);
|
||||||
|
}
|
||||||
|
setFrame(mView.getLayoutParams(), jsObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFrame(ViewGroup.LayoutParams layoutParams, JSObject 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);
|
((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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,21 +7,38 @@ import com.github.penfeizhou.doric.extension.render.ViewNode;
|
|||||||
import com.github.pengfeizhou.jscore.JSArray;
|
import com.github.pengfeizhou.jscore.JSArray;
|
||||||
import com.github.pengfeizhou.jscore.JSObject;
|
import com.github.pengfeizhou.jscore.JSObject;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: com.github.penfeizhou.doric.widget
|
* @Description: com.github.penfeizhou.doric.widget
|
||||||
* @Author: pengfei.zhou
|
* @Author: pengfei.zhou
|
||||||
* @CreateDate: 2019-07-20
|
* @CreateDate: 2019-07-20
|
||||||
*/
|
*/
|
||||||
public abstract class GroupNode extends ViewNode<ViewGroup> {
|
public abstract class GroupNode extends ViewNode<ViewGroup> {
|
||||||
|
private Map<String, ViewNode> mChildren = new HashMap<>();
|
||||||
|
|
||||||
public GroupNode(DoricContext doricContext) {
|
public GroupNode(DoricContext doricContext) {
|
||||||
super(doricContext);
|
super(doricContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void config(ViewGroup view, JSObject jsObject) {
|
public void blend(JSObject jsObject) {
|
||||||
super.config(view, jsObject);
|
super.blend(jsObject);
|
||||||
JSArray jsArray = jsObject.getProperty("children").asArray();
|
JSArray jsArray = jsObject.getProperty("children").asArray();
|
||||||
for (int i = 0; i < jsArray.size(); i++) {
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Color, GradientColor } from "../util/color"
|
import { Color, GradientColor } from "../util/color"
|
||||||
import { Modeling, Model } from "../util/types";
|
import { Modeling, Model, obj2Model } from "../util/types";
|
||||||
import "reflect-metadata"
|
import "reflect-metadata"
|
||||||
import { uniqueId } from "../util/uniqueId";
|
import { uniqueId } from "../util/uniqueId";
|
||||||
import { loge } from "../util/log";
|
import { loge } from "../util/log";
|
||||||
@ -42,6 +42,8 @@ export abstract class View implements Modeling {
|
|||||||
@Property
|
@Property
|
||||||
viewId = uniqueId('ViewId')
|
viewId = uniqueId('ViewId')
|
||||||
|
|
||||||
|
parent?: Group
|
||||||
|
|
||||||
callbacks: Map<String, Function> = new Map
|
callbacks: Map<String, Function> = new Map
|
||||||
|
|
||||||
private callback2Id(f: Function) {
|
private callback2Id(f: Function) {
|
||||||
@ -107,12 +109,21 @@ export abstract class View implements Modeling {
|
|||||||
onPropertyChanged(propKey: string, oldV: Model, newV: Model): void {
|
onPropertyChanged(propKey: string, oldV: Model, newV: Model): void {
|
||||||
if (newV instanceof Function) {
|
if (newV instanceof Function) {
|
||||||
newV = this.callback2Id(newV)
|
newV = this.callback2Id(newV)
|
||||||
} else if (newV instanceof Object
|
} else {
|
||||||
&& Reflect.has(newV, 'toModel')
|
newV = obj2Model(newV)
|
||||||
&& Reflect.get(newV, 'toModel') instanceof Function) {
|
|
||||||
newV = Reflect.apply(Reflect.get(newV, 'toModel'), newV, [])
|
|
||||||
}
|
}
|
||||||
this.__dirty_props__[propKey] = 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) {
|
responseCallback(id: string) {
|
||||||
@ -180,8 +191,43 @@ export interface LayoutConfig extends Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export abstract class Group extends View {
|
export abstract class Group extends View {
|
||||||
|
|
||||||
@Property
|
@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 {
|
export class Stack extends Group {
|
||||||
|
@ -1,5 +1,18 @@
|
|||||||
export interface Modeling {
|
export interface Modeling {
|
||||||
toModel(): Model
|
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>
|
Reference in New Issue
Block a user