diff --git a/Android/doric/src/main/java/pub/doric/shader/ImageNode.java b/Android/doric/src/main/java/pub/doric/shader/ImageNode.java index 3d2ac126..690573d3 100644 --- a/Android/doric/src/main/java/pub/doric/shader/ImageNode.java +++ b/Android/doric/src/main/java/pub/doric/shader/ImageNode.java @@ -19,6 +19,7 @@ import android.graphics.drawable.Drawable; import androidx.annotation.Nullable; +import android.text.TextUtils; import android.widget.ImageView; import com.bumptech.glide.Glide; @@ -30,6 +31,7 @@ import com.bumptech.glide.request.target.Target; import pub.doric.DoricContext; import pub.doric.extension.bridge.DoricPlugin; +import com.github.pengfeizhou.jscore.JSONBuilder; import com.github.pengfeizhou.jscore.JSValue; /** @@ -39,6 +41,8 @@ import com.github.pengfeizhou.jscore.JSValue; */ @DoricPlugin(name = "Image") public class ImageNode extends ViewNode { + private String loadCallbackId = ""; + public ImageNode(DoricContext doricContext) { super(doricContext); } @@ -50,35 +54,51 @@ public class ImageNode extends ViewNode { @Override protected void blend(ImageView view, String name, JSValue prop) { - if ("imageUrl".equals(name)) { - Glide.with(getContext()).load(prop.asString().value()) - .listener(new RequestListener() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - return false; - } + switch (name) { + case "imageUrl": + Glide.with(getContext()).load(prop.asString().value()) + .listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + if (!TextUtils.isEmpty(loadCallbackId)) { + callJSResponse(loadCallbackId); + } + return false; + } - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - return false; - } - }) - .into(view); - } else if ("scaleType".equals(name)) { - int scaleType = prop.asNumber().toInt(); - switch (scaleType) { - case 1: - view.setScaleType(ImageView.ScaleType.FIT_CENTER); - break; - case 2: - view.setScaleType(ImageView.ScaleType.CENTER_CROP); - break; - default: - view.setScaleType(ImageView.ScaleType.FIT_XY); - break; - } - } else { - super.blend(view, name, prop); + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + if (!TextUtils.isEmpty(loadCallbackId)) { + callJSResponse(loadCallbackId, new JSONBuilder() + .put("width", resource.getIntrinsicWidth()) + .put("height", resource.getIntrinsicHeight()) + .toJSONObject()); + } + return false; + } + }) + .into(view); + break; + case "scaleType": + int scaleType = prop.asNumber().toInt(); + switch (scaleType) { + case 1: + view.setScaleType(ImageView.ScaleType.FIT_CENTER); + break; + case 2: + view.setScaleType(ImageView.ScaleType.CENTER_CROP); + break; + default: + view.setScaleType(ImageView.ScaleType.FIT_XY); + break; + } + break; + case "loadCallback": + this.loadCallbackId = prop.asString().value(); + break; + default: + super.blend(view, name, prop); + break; } } } diff --git a/Android/doric/src/main/java/pub/doric/shader/TextNode.java b/Android/doric/src/main/java/pub/doric/shader/TextNode.java index 246a16f9..78f95906 100644 --- a/Android/doric/src/main/java/pub/doric/shader/TextNode.java +++ b/Android/doric/src/main/java/pub/doric/shader/TextNode.java @@ -57,6 +57,8 @@ public class TextNode extends ViewNode { case "textAlignment": view.setGravity(prop.asNumber().toInt() | Gravity.CENTER_VERTICAL); break; + case "numberOfLines": + break; default: super.blend(view, name, prop); break; diff --git a/demo/src/ImageDemo.ts b/demo/src/ImageDemo.ts index ff3b3313..5e155cc5 100644 --- a/demo/src/ImageDemo.ts +++ b/demo/src/ImageDemo.ts @@ -25,6 +25,9 @@ class ImageDemo extends Panel { }, scaleType: ScaleType.ScaleToFill, layoutConfig: layoutConfig().exactly(), + loadCallback: (ret) => { + log('loadCallback', ret) + } }), label('ScaleAspectFit'), image({ diff --git a/iOS/Pod/Classes/Shader/DoricImageNode.m b/iOS/Pod/Classes/Shader/DoricImageNode.m index c2ec2a5b..dfa204ef 100644 --- a/iOS/Pod/Classes/Shader/DoricImageNode.m +++ b/iOS/Pod/Classes/Shader/DoricImageNode.m @@ -24,6 +24,10 @@ #import "Doric.h" #import +@interface DoricImageNode () +@property(nonatomic, copy) NSString *loadCallbackId; +@end + @implementation DoricImageNode - (UIImageView *)build { @@ -37,7 +41,19 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id __weak typeof(self) _self = self; [view sd_setImageWithURL:[NSURL URLWithString:prop] completed:^(UIImage *_Nullable image, NSError *_Nullable error, SDImageCacheType cacheType, NSURL *_Nullable imageURL) { __strong typeof(_self) self = _self; - [self requestLayout]; + if (error) { + if (self.loadCallbackId.length > 0) { + [self callJSResponse:self.loadCallbackId, nil]; + } + } else { + if (self.loadCallbackId.length > 0) { + [self callJSResponse:self.loadCallbackId, + @{@"width": @(image.size.width), @"height": @(image.size.height)}, + nil]; + } + [self requestLayout]; + } + }]; } else if ([@"scaleType" isEqualToString:name]) { switch ([prop integerValue]) { @@ -54,6 +70,8 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id break; } } + } else if ([@"loadCallback" isEqualToString:name]) { + self.loadCallbackId = prop; } else { [super blendView:view forPropName:name propValue:prop]; } diff --git a/js-framework/src/ui/widgets.ts b/js-framework/src/ui/widgets.ts index 008847c5..6790b604 100644 --- a/js-framework/src/ui/widgets.ts +++ b/js-framework/src/ui/widgets.ts @@ -51,6 +51,7 @@ export enum ScaleType { export interface IImage extends IView { imageUrl?: string scaleType?: ScaleType + loadCallback?: (image: { width: number; height: number } | undefined) => void } export class Image extends View implements IImage { @@ -59,4 +60,7 @@ export class Image extends View implements IImage { @Property scaleType?: ScaleType + + @Property + loadCallback?: (image: { width: number; height: number } | undefined) => void } \ No newline at end of file