render demo
This commit is contained in:
parent
309dd4ff55
commit
7d08ceb8be
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user