From 7a2bffdb645dd4e06311a0c93d3f9dc998c30b6b Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Mon, 13 Apr 2020 14:30:14 +0800 Subject: [PATCH] android:fix mix use layoutConfig and flexConfig --- .../main/java/pub/doric/shader/ImageNode.java | 1 + .../main/java/pub/doric/shader/ViewNode.java | 2 +- .../java/pub/doric/shader/flex/FlexNode.java | 101 ++++++++-- doric-demo/src/FlexDemo.ts | 190 ++++++++++-------- doric-js/index.d.ts | 1 + doric-js/lib/src/util/flexbox.d.ts | 1 + doric-js/lib/src/util/flexbox.js | 12 +- doric-js/src/util/flexbox.ts | 13 +- 8 files changed, 205 insertions(+), 116 deletions(-) diff --git a/doric-android/doric/src/main/java/pub/doric/shader/ImageNode.java b/doric-android/doric/src/main/java/pub/doric/shader/ImageNode.java index 438b421d..1b5e880d 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/ImageNode.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/ImageNode.java @@ -235,6 +235,7 @@ public class ImageNode extends ViewNode { if (node != null) { node.dirty(); } + mView.requestLayout(); } } }); diff --git a/doric-android/doric/src/main/java/pub/doric/shader/ViewNode.java b/doric-android/doric/src/main/java/pub/doric/shader/ViewNode.java index 6993a3d0..da157878 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/ViewNode.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/ViewNode.java @@ -71,7 +71,7 @@ public abstract class ViewNode extends DoricContextHolder { String mId; protected ViewGroup.LayoutParams mLayoutParams; private String mType; - private JSObject mFlexConfig; + protected JSObject mFlexConfig; public JSObject getFlexConfig() { return mFlexConfig; diff --git a/doric-android/doric/src/main/java/pub/doric/shader/flex/FlexNode.java b/doric-android/doric/src/main/java/pub/doric/shader/flex/FlexNode.java index 47cb2e8e..3a7e3276 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/flex/FlexNode.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/flex/FlexNode.java @@ -28,6 +28,7 @@ import com.facebook.yoga.YogaJustify; import com.facebook.yoga.YogaNode; import com.facebook.yoga.YogaOverflow; import com.facebook.yoga.YogaPositionType; +import com.facebook.yoga.YogaUnit; import com.facebook.yoga.YogaWrap; import com.facebook.yoga.android.YogaLayout; import com.github.pengfeizhou.jscore.JSObject; @@ -59,56 +60,111 @@ public class FlexNode extends GroupNode { @Override protected YogaLayout build() { - YogaLayout yogaLayout = new YogaLayout(getContext()) { + return new YogaLayout(getContext()) { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); ViewNode childNode = (ViewNode) child.getTag(R.id.doric_node); - if (childNode != null && childNode.getFlexConfig() == null) { + if (childNode != null) { ViewGroup.LayoutParams layoutParams = child.getLayoutParams(); int childWidthMeasureSpec; int childHeightMeasureSpec; if (layoutParams.width == ViewGroup.LayoutParams.MATCH_PARENT) { - childWidthMeasureSpec = View.MeasureSpec.makeMeasureSpec( - 0, - View.MeasureSpec.AT_MOST); + childWidthMeasureSpec = MeasureSpec.makeMeasureSpec( + getMeasuredWidth(), + MeasureSpec.AT_MOST); } else if (layoutParams.width == ViewGroup.LayoutParams.WRAP_CONTENT) { - childWidthMeasureSpec = View.MeasureSpec.makeMeasureSpec( - 0, - View.MeasureSpec.UNSPECIFIED); + childWidthMeasureSpec = MeasureSpec.makeMeasureSpec( + getMeasuredHeight(), + MeasureSpec.UNSPECIFIED); } else { - childWidthMeasureSpec = View.MeasureSpec.makeMeasureSpec( + childWidthMeasureSpec = MeasureSpec.makeMeasureSpec( layoutParams.width, - View.MeasureSpec.EXACTLY); + MeasureSpec.EXACTLY); } if (layoutParams.height == ViewGroup.LayoutParams.MATCH_PARENT) { - childHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec( + childHeightMeasureSpec = MeasureSpec.makeMeasureSpec( 0, - View.MeasureSpec.AT_MOST); + MeasureSpec.AT_MOST); } else if (layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) { - childHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec( + childHeightMeasureSpec = MeasureSpec.makeMeasureSpec( 0, - View.MeasureSpec.UNSPECIFIED); + MeasureSpec.UNSPECIFIED); } else { - childHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec( + childHeightMeasureSpec = MeasureSpec.makeMeasureSpec( layoutParams.height, - View.MeasureSpec.EXACTLY); + MeasureSpec.EXACTLY); } child.measure(childWidthMeasureSpec, childHeightMeasureSpec); - if (layoutParams.width != ViewGroup.LayoutParams.MATCH_PARENT) { - getYogaNodeForView(child).setWidth(childNode.getView().getMeasuredWidth()); - } - if (layoutParams.height != ViewGroup.LayoutParams.MATCH_PARENT) { - getYogaNodeForView(child).setHeight(childNode.getView().getMeasuredHeight()); + YogaNode node = getYogaNodeForView(child); + if (node != null) { + JSObject flexConfig = childNode.getFlexConfig(); + YogaUnit widthUnit = YogaUnit.AUTO; + YogaUnit heightUnit = YogaUnit.AUTO; + if (flexConfig != null) { + JSValue widthValue = flexConfig.getProperty("width"); + if (widthValue.isNumber()) { + widthUnit = YogaUnit.POINT; + } else if (widthValue.isObject()) { + JSValue typeValue = widthValue.asObject().getProperty("type"); + if (typeValue.isNumber()) { + widthUnit = YogaUnit.fromInt(typeValue.asNumber().toInt()); + } + } + JSValue heightValue = flexConfig.getProperty("height"); + if (heightValue.isNumber()) { + heightUnit = YogaUnit.POINT; + } else if (heightValue.isObject()) { + JSValue typeValue = heightValue.asObject().getProperty("type"); + if (typeValue.isNumber()) { + heightUnit = YogaUnit.fromInt(typeValue.asNumber().toInt()); + } + } + } + if (widthUnit == YogaUnit.AUTO) { + node.setWidth(childNode.getView().getMeasuredWidth()); + } + if (heightUnit == YogaUnit.AUTO) { + node.setHeight(childNode.getView().getMeasuredHeight()); + } } } } + YogaUnit widthUnit = YogaUnit.AUTO; + YogaUnit heightUnit = YogaUnit.AUTO; + JSObject flexConfig = getFlexConfig(); + if (flexConfig != null) { + JSValue widthValue = flexConfig.getProperty("width"); + if (widthValue.isNumber()) { + widthUnit = YogaUnit.POINT; + } else if (widthValue.isObject()) { + JSValue typeValue = widthValue.asObject().getProperty("type"); + if (typeValue.isNumber()) { + widthUnit = YogaUnit.fromInt(typeValue.asNumber().toInt()); + } + } + JSValue heightValue = flexConfig.getProperty("height"); + if (heightValue.isNumber()) { + heightUnit = YogaUnit.POINT; + } else if (heightValue.isObject()) { + JSValue typeValue = heightValue.asObject().getProperty("type"); + if (typeValue.isNumber()) { + heightUnit = YogaUnit.fromInt(typeValue.asNumber().toInt()); + } + } + } + // Because in onLayout yogaNode's width and height would be set to exactly. + if (widthUnit == YogaUnit.AUTO) { + getYogaNode().setWidthAuto(); + } + if (heightUnit == YogaUnit.AUTO) { + getYogaNode().setHeightAuto(); + } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }; - return yogaLayout; } @Override @@ -126,6 +182,7 @@ public class FlexNode extends GroupNode { protected void blend(YogaLayout view, String name, JSValue prop) { if ("flexConfig".equals(name)) { blendSubFlexConfig(mView.getYogaNode(), prop.asObject()); + this.mFlexConfig = prop.asObject(); } else { super.blend(view, name, prop); } diff --git a/doric-demo/src/FlexDemo.ts b/doric-demo/src/FlexDemo.ts index 64eb9ace..0ba2ff59 100644 --- a/doric-demo/src/FlexDemo.ts +++ b/doric-demo/src/FlexDemo.ts @@ -40,92 +40,122 @@ export const ICON_BUBBLE_WHITE_ARROW_UP = "data:image/png;base64,iVBORw0KGgoAAAA @Entry class LayoutDemo extends Panel { build(root: Group) { - flexlayout( - [ - // image({ - // imageBase64: ICON_GENDER_MAN, - // scaleType: ScaleType.ScaleAspectFit, - // // flexConfig: { - // // width: FlexTypedValue.Auto, - // // height: FlexTypedValue.Auto, - // // }, - // backgroundColor: Color.GRAY, - // layoutConfig: { - // widthSpec: LayoutSpec.FIT, - // heightSpec: LayoutSpec.JUST, - // alignment: Gravity.Center, - // }, - // height: 30, - // }), - // text({ - // text: "1234343434343456", - // backgroundColor: Color.RED, - // flexConfig: { - // width: FlexTypedValue.Auto, - // height: FlexTypedValue.Auto, - // }, - // }), - text({ - text: "123456", - backgroundColor: Color.RED, - flexConfig: { - - }, - }), - image({ - imageBase64: ICON_GENDER_MAN, - scaleType: ScaleType.ScaleAspectFit, - layoutConfig: { - widthSpec: LayoutSpec.FIT, - heightSpec: LayoutSpec.JUST, - }, - height: 20, - backgroundColor: Color.GRAY, - }), - image({ - imageBase64: ICON_GENDER_MAN, - scaleType: ScaleType.ScaleAspectFit, - flexConfig: { - width: 80, - }, - backgroundColor: Color.GRAY, - }), - image({ - imageBase64: ICON_GENDER_MAN, - scaleType: ScaleType.ScaleAspectFit, - flexConfig: { + scroller( + flexlayout( + [ + image({ + imageBase64: ICON_GENDER_MAN, + scaleType: ScaleType.ScaleAspectFit, + // flexConfig: { + // width: FlexTypedValue.Auto, + // height: FlexTypedValue.Auto, + // }, + backgroundColor: Color.GRAY, + layoutConfig: { + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.JUST, + alignment: Gravity.Center, + }, + height: 30, + }), + text({ + text: "1234343434343456", + backgroundColor: Color.RED, + flexConfig: { + width: FlexTypedValue.Auto, + height: 100, + }, + }), + vlayout( + [ + text({ + text: "11111" + }), + text({ + text: "22222" + }), + text({ + text: "33333" + }), + ], + { + backgroundColor: Color.GRAY, + flexConfig: { + alignSelf: Align.CENTER, + } + }), + text({ + text: "123456sdfdsfdsfdsfdsfsdfsdfsdfsdfdsfs", + backgroundColor: Color.RED, + }), + image({ + imageBase64: ICON_GENDER_MAN, + scaleType: ScaleType.ScaleAspectFit, + layoutConfig: { + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.JUST, + }, height: 20, - }, - backgroundColor: Color.RED, - }), - image({ - imageBase64: ICON_GENDER_MAN, - scaleType: ScaleType.ScaleAspectFit, + backgroundColor: Color.GRAY, + }), + image({ + imageBase64: ICON_GENDER_MAN, + scaleType: ScaleType.ScaleAspectFit, + flexConfig: { + width: 80, + }, + backgroundColor: Color.GRAY, + }), + flexlayout( + [ + image({ + imageBase64: ICON_GENDER_MAN, + scaleType: ScaleType.ScaleAspectFit, + backgroundColor: Color.BLUE, + }), + image({ + imageBase64: ICON_GENDER_MAN, + scaleType: ScaleType.ScaleAspectFit, + backgroundColor: Color.BLUE, + }), + ], + { + flexConfig: { + width: 100, + height: 100, + }, + backgroundColor: Color.YELLOW, + }), + image({ + imageBase64: ICON_GENDER_MAN, + scaleType: ScaleType.ScaleAspectFit, + flexConfig: { + height: 20, + }, + backgroundColor: Color.GRAY, + }), + ], + { flexConfig: { - height: 20, + flexDirection: FlexDirection.ROW, }, - backgroundColor: Color.GRAY, - }), - ], + backgroundColor: Color.GRAY.alpha(0.1), + } + ), { - flexConfig: { - width: 300, - height: 300, - flexDirection: FlexDirection.ROW, - }, - backgroundColor: Color.GRAY.alpha(0.1), + layoutConfig: layoutConfig().most() } ).in(root) - image({ - imageBase64: ICON_GENDER_MAN, - backgroundColor: Color.GRAY, - layoutConfig: { - widthSpec: LayoutSpec.FIT, - heightSpec: LayoutSpec.JUST, - alignment: Gravity.Center, - }, - height: 30, - }).in(root) + // image({ + // imageBase64: ICON_GENDER_MAN, + // backgroundColor: Color.GRAY, + // layoutConfig: { + // widthSpec: LayoutSpec.FIT, + // heightSpec: LayoutSpec.JUST, + // alignment: Gravity.Center, + // }, + // height: 30, + // }).in(root) } } \ No newline at end of file diff --git a/doric-js/index.d.ts b/doric-js/index.d.ts index 2f56faa6..85fa8637 100644 --- a/doric-js/index.d.ts +++ b/doric-js/index.d.ts @@ -1333,6 +1333,7 @@ declare module 'doric/lib/src/util/flexbox' { export class FlexTypedValue implements Modeling { type: ValueType; value: number; + constructor(type: ValueType); static Auto: FlexTypedValue; static percent(v: number): FlexTypedValue; static point(v: number): FlexTypedValue; diff --git a/doric-js/lib/src/util/flexbox.d.ts b/doric-js/lib/src/util/flexbox.d.ts index d2a9850e..e59e2de0 100644 --- a/doric-js/lib/src/util/flexbox.d.ts +++ b/doric-js/lib/src/util/flexbox.d.ts @@ -8,6 +8,7 @@ declare enum ValueType { export declare class FlexTypedValue implements Modeling { type: ValueType; value: number; + constructor(type: ValueType); static Auto: FlexTypedValue; static percent(v: number): FlexTypedValue; static point(v: number): FlexTypedValue; diff --git a/doric-js/lib/src/util/flexbox.js b/doric-js/lib/src/util/flexbox.js index e0e0c624..cff12a70 100644 --- a/doric-js/lib/src/util/flexbox.js +++ b/doric-js/lib/src/util/flexbox.js @@ -6,19 +6,17 @@ var ValueType; ValueType[ValueType["Auto"] = 3] = "Auto"; })(ValueType || (ValueType = {})); export class FlexTypedValue { - constructor() { - this.type = ValueType.Auto; + constructor(type) { this.value = 0; + this.type = type; } static percent(v) { - const ret = new FlexTypedValue; - ret.type = ValueType.Percent; + const ret = new FlexTypedValue(ValueType.Percent); ret.value = v; return ret; } static point(v) { - const ret = new FlexTypedValue; - ret.type = ValueType.Point; + const ret = new FlexTypedValue(ValueType.Point); ret.value = v; return ret; } @@ -29,7 +27,7 @@ export class FlexTypedValue { }; } } -FlexTypedValue.Auto = new FlexTypedValue; +FlexTypedValue.Auto = new FlexTypedValue(ValueType.Auto); export var FlexDirection; (function (FlexDirection) { FlexDirection[FlexDirection["COLUMN"] = 0] = "COLUMN"; diff --git a/doric-js/src/util/flexbox.ts b/doric-js/src/util/flexbox.ts index 359856f6..7bf82555 100644 --- a/doric-js/src/util/flexbox.ts +++ b/doric-js/src/util/flexbox.ts @@ -24,21 +24,22 @@ enum ValueType { export class FlexTypedValue implements Modeling { - type = ValueType.Auto + type: ValueType value = 0 + constructor(type: ValueType) { + this.type = type + } - static Auto = new FlexTypedValue + static Auto = new FlexTypedValue(ValueType.Auto) static percent(v: number) { - const ret = new FlexTypedValue - ret.type = ValueType.Percent + const ret = new FlexTypedValue(ValueType.Percent) ret.value = v return ret } static point(v: number) { - const ret = new FlexTypedValue - ret.type = ValueType.Point + const ret = new FlexTypedValue(ValueType.Point) ret.value = v return ret }