add handling layoutconfig in flexlayout

This commit is contained in:
pengfei.zhou 2020-04-11 19:10:56 +08:00 committed by osborn
parent ee864620c1
commit d29ff4991d
9 changed files with 218 additions and 93 deletions

View File

@ -34,6 +34,7 @@ import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.DrawableImageViewTarget; import com.bumptech.glide.request.target.DrawableImageViewTarget;
import com.bumptech.glide.request.target.SizeReadyCallback; import com.bumptech.glide.request.target.SizeReadyCallback;
import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.target.Target;
import com.facebook.yoga.YogaNode;
import com.github.pengfeizhou.jscore.JSONBuilder; import com.github.pengfeizhou.jscore.JSONBuilder;
import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue; import com.github.pengfeizhou.jscore.JSValue;
@ -47,6 +48,7 @@ import androidx.annotation.Nullable;
import jp.wasabeef.glide.transformations.BlurTransformation; import jp.wasabeef.glide.transformations.BlurTransformation;
import pub.doric.DoricContext; import pub.doric.DoricContext;
import pub.doric.extension.bridge.DoricPlugin; import pub.doric.extension.bridge.DoricPlugin;
import pub.doric.shader.flex.FlexNode;
import pub.doric.utils.DoricLog; import pub.doric.utils.DoricLog;
import pub.doric.utils.DoricUtils; import pub.doric.utils.DoricUtils;
@ -83,7 +85,12 @@ public class ImageNode extends ViewNode<ImageView> {
@Override @Override
protected ImageView build() { protected ImageView build() {
ImageView imageView = new ImageView(getContext()); ImageView imageView = new ImageView(getContext()) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
};
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setAdjustViewBounds(true); imageView.setAdjustViewBounds(true);
return imageView; return imageView;
@ -223,6 +230,12 @@ public class ImageNode extends ViewNode<ImageView> {
@Override @Override
protected void setResource(@Nullable Drawable resource) { protected void setResource(@Nullable Drawable resource) {
super.setResource(resource); super.setResource(resource);
if (mSuperNode instanceof FlexNode) {
YogaNode node = ((FlexNode) mSuperNode).mView.getYogaNodeForView(mView);
if (node != null) {
node.dirty();
}
}
} }
}); });
} }

View File

@ -50,6 +50,7 @@ import java.util.LinkedList;
import pub.doric.DoricContext; import pub.doric.DoricContext;
import pub.doric.DoricRegistry; import pub.doric.DoricRegistry;
import pub.doric.R;
import pub.doric.async.AsyncResult; import pub.doric.async.AsyncResult;
import pub.doric.extension.bridge.DoricMethod; import pub.doric.extension.bridge.DoricMethod;
import pub.doric.extension.bridge.DoricPromise; import pub.doric.extension.bridge.DoricPromise;
@ -89,6 +90,7 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
this.mSuperNode = superNode; this.mSuperNode = superNode;
this.mLayoutParams = superNode.generateDefaultLayoutParams(); this.mLayoutParams = superNode.generateDefaultLayoutParams();
this.mView = build(); this.mView = build();
this.mView.setTag(R.id.doric_node, this);
this.mView.setLayoutParams(mLayoutParams); this.mView.setLayoutParams(mLayoutParams);
} }
@ -106,6 +108,10 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
return mType; return mType;
} }
public T getView() {
return mView;
}
public View getNodeView() { public View getNodeView() {
if (doricLayer != null) { if (doricLayer != null) {
return doricLayer; return doricLayer;
@ -466,6 +472,7 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
} else { } else {
doricLayer.addView(mView, params); doricLayer.addView(mView, params);
} }
this.doricLayer.setTag(R.id.doric_node, this);
} }
return doricLayer; return doricLayer;
} }

View File

@ -15,7 +15,9 @@
*/ */
package pub.doric.shader.flex; package pub.doric.shader.flex;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView;
import com.facebook.yoga.YogaAlign; import com.facebook.yoga.YogaAlign;
import com.facebook.yoga.YogaDirection; import com.facebook.yoga.YogaDirection;
@ -32,6 +34,7 @@ import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue; import com.github.pengfeizhou.jscore.JSValue;
import pub.doric.DoricContext; import pub.doric.DoricContext;
import pub.doric.R;
import pub.doric.extension.bridge.DoricPlugin; import pub.doric.extension.bridge.DoricPlugin;
import pub.doric.shader.GroupNode; import pub.doric.shader.GroupNode;
import pub.doric.shader.ViewNode; import pub.doric.shader.ViewNode;
@ -56,7 +59,56 @@ public class FlexNode extends GroupNode<YogaLayout> {
@Override @Override
protected YogaLayout build() { protected YogaLayout build() {
return new YogaLayout(getContext()); YogaLayout yogaLayout = 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) {
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);
} else if (layoutParams.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
childWidthMeasureSpec = View.MeasureSpec.makeMeasureSpec(
0,
View.MeasureSpec.UNSPECIFIED);
} else {
childWidthMeasureSpec = View.MeasureSpec.makeMeasureSpec(
layoutParams.width,
View.MeasureSpec.EXACTLY);
}
if (layoutParams.height == ViewGroup.LayoutParams.MATCH_PARENT) {
childHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
0,
View.MeasureSpec.AT_MOST);
} else if (layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
childHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
0,
View.MeasureSpec.UNSPECIFIED);
} else {
childHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
layoutParams.height,
View.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());
}
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
};
return yogaLayout;
} }
@Override @Override
@ -84,6 +136,9 @@ public class FlexNode extends GroupNode<YogaLayout> {
super.blend(jsObject); super.blend(jsObject);
for (ViewNode childNode : mChildNodes) { for (ViewNode childNode : mChildNodes) {
YogaNode yogaNode = this.mView.getYogaNodeForView(childNode.getNodeView()); YogaNode yogaNode = this.mView.getYogaNodeForView(childNode.getNodeView());
if (childNode.getFlexConfig() != null && childNode.getView() instanceof ImageView) {
((ImageView) childNode.getView()).setAdjustViewBounds(false);
}
if (yogaNode != null) { if (yogaNode != null) {
blendSubFlexConfig(yogaNode, childNode.getFlexConfig()); blendSubFlexConfig(yogaNode, childNode.getFlexConfig());
} }
@ -92,11 +147,11 @@ public class FlexNode extends GroupNode<YogaLayout> {
private void blendSubFlexConfig(YogaNode yogaNode, JSObject jsObject) { private void blendSubFlexConfig(YogaNode yogaNode, JSObject jsObject) {
if (jsObject == null) { if (jsObject == null) {
return; } else {
} for (String name : jsObject.propertySet()) {
for (String name : jsObject.propertySet()) { JSValue value = jsObject.getProperty(name);
JSValue value = jsObject.getProperty(name); blendFlexConfig(yogaNode, name, value);
blendFlexConfig(yogaNode, name, value); }
} }
} }

View File

@ -3,4 +3,5 @@
<item name="doric_mask_loading" type="id" /> <item name="doric_mask_loading" type="id" />
<item name="doric_mask_error" type="id" /> <item name="doric_mask_error" type="id" />
<item name="doric_mask_error_retry" type="id" /> <item name="doric_mask_error_retry" type="id" />
<item name="doric_node" type="id" />
</resources> </resources>

File diff suppressed because one or more lines are too long

View File

@ -27,6 +27,16 @@ @interface DoricFlexView : UIView
@implementation DoricFlexView @implementation DoricFlexView
- (CGSize)sizeThatFits:(CGSize)size { - (CGSize)sizeThatFits:(CGSize)size {
for (UIView *view in self.subviews) {
if (!view.doricLayout.disabled) {
[view.doricLayout apply];
[view configureLayoutWithBlock:^(YGLayout *layout) {
layout.isEnabled = YES;
layout.width = YGPointValue(view.doricLayout.measuredWidth);
layout.height = YGPointValue(view.doricLayout.measuredHeight);
}];
}
}
return [self.yoga intrinsicSize]; return [self.yoga intrinsicSize];
} }
@end @end
@ -53,6 +63,7 @@ - (void)blendSubNode:(DoricViewNode *)subNode flexConfig:(NSDictionary *)flexCon
[subNode.view configureLayoutWithBlock:^(YGLayout *_Nonnull layout) { [subNode.view configureLayoutWithBlock:^(YGLayout *_Nonnull layout) {
layout.isEnabled = YES; layout.isEnabled = YES;
}]; }];
subNode.view.doricLayout.disabled = YES;
[self blendYoga:subNode.view.yoga from:flexConfig]; [self blendYoga:subNode.view.yoga from:flexConfig];
} }
@ -195,6 +206,7 @@ - (YGValue)translateYGValueFromProperty:(id)prop {
- (void)requestLayout { - (void)requestLayout {
[super requestLayout]; [super requestLayout];
if (self.view.doricLayout.widthSpec != DoricLayoutFit) { if (self.view.doricLayout.widthSpec != DoricLayoutFit) {
self.view.yoga.width = YGPointValue(self.view.width); self.view.yoga.width = YGPointValue(self.view.width);
} }
@ -204,7 +216,7 @@ - (void)requestLayout {
[self.view.yoga applyLayoutPreservingOrigin:YES]; [self.view.yoga applyLayoutPreservingOrigin:YES];
/// Need layout again. /// Need layout again.
for (UIView *view in self.view.subviews) { for (UIView *view in self.view.subviews) {
if (view.yoga.isEnabled) { if ([view isKindOfClass:[DoricFlexView class]]) {
continue; continue;
} }
if (view.doricLayout.measuredWidth == view.width && view.doricLayout.measuredHeight == view.height) { if (view.doricLayout.measuredWidth == view.width && view.doricLayout.measuredHeight == view.height) {

View File

@ -1705,7 +1705,7 @@ var doric = (function (exports) {
(module.exports = function (key, value) { (module.exports = function (key, value) {
return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {}); return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {});
})('versions', []).push({ })('versions', []).push({
version: '3.6.5', version: '3.6.4',
mode: 'global', mode: 'global',
copyright: '© 2020 Denis Pushkarev (zloirock.ru)' copyright: '© 2020 Denis Pushkarev (zloirock.ru)'
}); });
@ -6489,13 +6489,7 @@ var doric = (function (exports) {
defer = functionBindContext(port.postMessage, port, 1); defer = functionBindContext(port.postMessage, port, 1);
// Browsers with postMessage, skip WebWorkers // Browsers with postMessage, skip WebWorkers
// IE8 has postMessage, but it's sync & typeof its postMessage is 'object' // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
} else if ( } else if (global_1.addEventListener && typeof postMessage == 'function' && !global_1.importScripts && !fails(post)) {
global_1.addEventListener &&
typeof postMessage == 'function' &&
!global_1.importScripts &&
!fails(post) &&
location.protocol !== 'file:'
) {
defer = post; defer = post;
global_1.addEventListener('message', listener, false); global_1.addEventListener('message', listener, false);
// IE8- // IE8-
@ -9867,7 +9861,7 @@ var doric = (function (exports) {
var INVALID_PORT = 'Invalid port'; var INVALID_PORT = 'Invalid port';
var ALPHA = /[A-Za-z]/; var ALPHA = /[A-Za-z]/;
var ALPHANUMERIC = /[\d+-.A-Za-z]/; var ALPHANUMERIC = /[\d+\-.A-Za-z]/;
var DIGIT = /\d/; var DIGIT = /\d/;
var HEX_START = /^(0x|0X)/; var HEX_START = /^(0x|0X)/;
var OCT = /^[0-7]+$/; var OCT = /^[0-7]+$/;

View File

@ -4055,7 +4055,7 @@ return __module.exports;
var doric_web = (function (exports, axios, sandbox) { var doric_web = (function (exports, axios, sandbox) {
'use strict'; 'use strict';
axios = axios && Object.prototype.hasOwnProperty.call(axios, 'default') ? axios['default'] : axios; axios = axios && axios.hasOwnProperty('default') ? axios['default'] : axios;
class DoricPlugin { class DoricPlugin {
constructor(context) { constructor(context) {

File diff suppressed because one or more lines are too long