render demo

This commit is contained in:
pengfei.zhou 2019-07-22 17:57:58 +08:00
parent 309dd4ff55
commit 7d08ceb8be
7 changed files with 104 additions and 34 deletions

View File

@ -8,6 +8,7 @@ import com.github.penfeizhou.doric.DoricContext;
import com.github.penfeizhou.doric.utils.DoricUtils; import com.github.penfeizhou.doric.utils.DoricUtils;
import com.github.pengfeizhou.jscore.JSONBuilder; import com.github.pengfeizhou.jscore.JSONBuilder;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
@Override @Override
@ -15,8 +16,11 @@ public class MainActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
DoricContext doricContext = DoricContext.create(this, DoricUtils.readAssetFile("demo.js"), "demo"); 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.callEntity("log");
doricContext.getRootNode().setRootView((FrameLayout) findViewById(R.id.root)); doricContext.getRootNode().setRootView((FrameLayout) findViewById(R.id.root));
} }
} }

View File

@ -44,16 +44,17 @@ public abstract class GroupNode<F extends ViewGroup> extends ViewNode<F> {
child.ids.addAll(this.ids); child.ids.addAll(this.ids);
child.ids.add(id); child.ids.add(id);
mChildrenNode.put(id, child); mChildrenNode.put(id, child);
mView.addView(child.mView, i);
} else if (i != child.index) { } else if (i != child.index) {
mIndexInfo.remove(child.index); mIndexInfo.remove(i);
child.index = i; child.index = i;
mView.removeView(child.mView); mView.removeView(child.mView);
mView.addView(child.mView, i);
} }
child.blend(childObj.getProperty("props").asObject()); child.blend(childObj.getProperty("props").asObject());
if (mIndexInfo.get(i) == null) {
mView.addView(child.mView, i);
mIndexInfo.put(i, child); mIndexInfo.put(i, child);
} }
}
while (i < mView.getChildCount()) { while (i < mView.getChildCount()) {
mView.removeViewAt(mView.getChildCount() - 1); mView.removeViewAt(mView.getChildCount() - 1);
if (mIndexInfo.get(i) != null) { if (mIndexInfo.get(i) != null) {

View File

@ -5,6 +5,7 @@ import android.widget.TextView;
import com.github.penfeizhou.doric.DoricContext; import com.github.penfeizhou.doric.DoricContext;
import com.github.penfeizhou.doric.extension.bridge.DoricPlugin; import com.github.penfeizhou.doric.extension.bridge.DoricPlugin;
import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue;
/** /**
* @Description: widget * @Description: widget
@ -21,4 +22,16 @@ public class TextNode extends ViewNode<TextView> {
public TextView build(JSObject jsObject) { public TextView build(JSObject jsObject) {
return new TextView(getContext()); 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;
}
}
} }

View File

@ -11,6 +11,7 @@ import com.github.penfeizhou.doric.utils.DoricConstant;
import com.github.penfeizhou.doric.utils.DoricMetaInfo; 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;
import com.github.pengfeizhou.jscore.JSValue;
import java.util.ArrayList; import java.util.ArrayList;
@ -39,7 +40,7 @@ public abstract class ViewNode<T extends View> extends DoricComponent {
public abstract T build(JSObject jsObject); public abstract T build(JSObject jsObject);
public void blend(JSObject jsObject) { void blend(JSObject jsObject) {
if (mView == null) { if (mView == null) {
mView = build(jsObject); mView = build(jsObject);
} }
@ -48,7 +49,38 @@ public abstract class ViewNode<T extends View> extends DoricComponent {
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,
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() { public String getId() {

View File

@ -5,13 +5,16 @@ import { Group } from "./src/ui/view";
@Entry @Entry
export class MyPage extends Panel { export class MyPage extends Panel {
text?: Text
build(rootView: Group): void { build(rootView: Group): void {
log('build view') this.text = new Text
const text = new Text this.text.text = "hello"
text.text = "hello" this.text.width = 50
rootView.children.push(text) this.text.height = 50
this.text.y = 100
rootView.children.push(this.text)
rootView.bgColor = Color.safeParse('#00ff00') rootView.bgColor = Color.safeParse('#00ff00')
log('build view:', JSON.stringify(rootView.toModel()))
} }
@NativeCall @NativeCall
@ -19,18 +22,29 @@ export class MyPage extends Panel {
log("Hello.HEGO") log("Hello.HEGO")
logw("Hello.HEGO") logw("Hello.HEGO")
loge("Hello.HEGO") loge("Hello.HEGO")
context.demo.testPromise(true).then((r) => { context.demo.testPromise(true).then((r) => {
log('resolve', r) log('resolve', r)
}, (e) => { }, (e) => {
log('reject', e) log('reject', e)
}) })
context.demo.testPromise(false).then((r) => { context.demo.testPromise(false).then((r) => {
log('resolve', r) log('resolve', r)
}, (e) => { }, (e) => {
log('reject', e) log('reject', e)
}) })
setTimeout(function () { setTimeout(function () {
log('settimeout') log('settimeout')
}, 1000) }, 1000)
setInterval(() => {
log('setInterval')
if (this.text) {
this.text.y += 10
}
log('build view:', JSON.stringify(this.getRootView().toModel()))
}, 1000)
} }
} }

View File

@ -25,10 +25,10 @@ export abstract class Panel {
abstract build(rootView: Group): void abstract build(rootView: Group): void
private __data__: any private __data__: any
private __rootView__ = new Root private __root__ = new Root
getRootView() { getRootView() {
return this.__rootView__ return this.__root__
} }
getInitData() { getInitData() {
return this.__data__ return this.__data__
@ -38,9 +38,9 @@ export abstract class Panel {
private __init__(frame: Frame, data: any) { private __init__(frame: Frame, data: any) {
log('__init__:', frame, data) log('__init__:', frame, data)
this.__data__ = data this.__data__ = data
this.__rootView__.width = frame.width this.__root__.width = frame.width
this.__rootView__.height = frame.height this.__root__.height = frame.height
this.build(this.__rootView__) this.build(this.__root__)
} }
@NativeCall @NativeCall
@ -65,7 +65,7 @@ export abstract class Panel {
@NativeCall @NativeCall
private __build__() { private __build__() {
this.build(this.__rootView__) this.build(this.__root__)
} }
@NativeCall @NativeCall
@ -87,7 +87,7 @@ export abstract class Panel {
return acc.children.filter(e => e.viewId === cur)[0] return acc.children.filter(e => e.viewId === cur)[0]
} }
return acc return acc
}, this.__rootView__) }, this.__root__)
} }
private nativeRender(model: Model) { private nativeRender(model: Model) {
@ -100,10 +100,10 @@ export abstract class Panel {
} }
private hookAfterNativeCall() { private hookAfterNativeCall() {
if (this.__rootView__.isDirty()) { if (this.__root__.isDirty()) {
const model = this.__rootView__.toModel() const model = this.__root__.toModel()
this.nativeRender(model) this.nativeRender(model)
this.__rootView__.clean() this.__root__.clean()
} }
} }

View File

@ -61,11 +61,11 @@ export abstract class View implements Modeling {
get: (target, p) => { get: (target, p) => {
return Reflect.get(target, p) return Reflect.get(target, p)
}, },
set: (target, p, v) => { set: (target, p, v, receiver) => {
const oldV = Reflect.get(target, p) const oldV = Reflect.get(target, p)
const ret = Reflect.set(target, p, v) const ret = Reflect.set(target, p, v)
if (Reflect.getMetadata(p, target)) { if (Reflect.getMetadata(p, target)) {
this.onPropertyChanged(p.toString(), oldV, v) receiver.onPropertyChanged(p.toString(), oldV, v)
} }
return ret return ret
} }
@ -105,6 +105,12 @@ export abstract class View implements Modeling {
__dirty_props__: { [index: string]: Model | undefined } = {} __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 { onPropertyChanged(propKey: string, oldV: Model, newV: Model): void {
if (newV instanceof Function) { if (newV instanceof Function) {
newV = this.callback2Id(newV) newV = this.callback2Id(newV)
@ -139,12 +145,9 @@ export abstract class View implements Modeling {
loge(`Cannot find callback:${id} for ${JSON.stringify(this.toModel())}`) loge(`Cannot find callback:${id} for ${JSON.stringify(this.toModel())}`)
} }
} }
toModel() { toModel() {
return { return this.nativeViewModel
id: this.viewId,
type: this.constructor.name,
props: this.__dirty_props__,
}
} }
@Property @Property
@ -196,12 +199,14 @@ export abstract class Group extends View {
@Property @Property
children: View[] = new Proxy([], { children: View[] = new Proxy([], {
set: (target, index, value) => { 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 value.parent = this
const childrenModel = this.getDirtyChildrenModel() const childrenModel = this.getDirtyChildrenModel()
childrenModel[index] = value.toModel() childrenModel[parseInt(index)] = value.nativeViewModel
} else if (index === 'length') {
this.getDirtyChildrenModel().length = value as number
} }
return Reflect.set(target, index, value) 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) { onChildPropertyChanged(child: View, propKey: string, oldV: Model, newV: Model) {
loge('onChildPropertyChanged:' + (this.children.indexOf(child)))
this.getDirtyChildrenModel()[this.children.indexOf(child)] = child.nativeViewModel
} }
} }