diff --git a/android/sdk/src/main/java/com/tencent/mtt/hippy/dom/node/HippyImageSpan.java b/android/sdk/src/main/java/com/tencent/mtt/hippy/dom/node/HippyImageSpan.java index 2464ab981a5..2e99fed2aed 100644 --- a/android/sdk/src/main/java/com/tencent/mtt/hippy/dom/node/HippyImageSpan.java +++ b/android/sdk/src/main/java/com/tencent/mtt/hippy/dom/node/HippyImageSpan.java @@ -15,6 +15,10 @@ */ package com.tencent.mtt.hippy.dom.node; +import static com.tencent.mtt.hippy.views.image.HippyImageView.ImageEvent.ONERROR; +import static com.tencent.mtt.hippy.views.image.HippyImageView.ImageEvent.ONLOAD; +import static com.tencent.mtt.hippy.views.image.HippyImageView.ImageEvent.ONLOAD_END; + import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Movie; @@ -25,41 +29,45 @@ import android.text.style.DynamicDrawableSpan; import android.text.style.ImageSpan; +import com.tencent.mtt.hippy.HippyEngineContext; import com.tencent.mtt.hippy.adapter.image.HippyDrawable; import com.tencent.mtt.hippy.adapter.image.HippyImageLoader; import com.tencent.mtt.hippy.common.HippyMap; import com.tencent.mtt.hippy.dom.flex.FlexSpacing; +import com.tencent.mtt.hippy.uimanager.HippyViewEvent; import com.tencent.mtt.hippy.utils.UIThreadUtils; import com.tencent.mtt.hippy.utils.UrlUtils; +import com.tencent.mtt.hippy.views.image.HippyImageView.ImageEvent; import java.lang.ref.WeakReference; import java.lang.reflect.Field; public class HippyImageSpan extends ImageSpan { + public final static int STATE_UNLOAD = 0; + public final static int STATE_LOADING = 1; + public final static int STATE_LOADED = 2; + private int mLeft; private int mTop; private int mWidth; private int mHeight; private String mUrl; private final WeakReference mImageNodeWeakRefrence; - //private int mImageLoadState = 0; + private int mImageLoadState = STATE_UNLOAD; private int mVerticalAlignment; private final HippyImageLoader mImageAdapter; - + private final HippyEngineContext engineContext; private Movie mGifMovie = null; private int mGifProgress = 0; private long mGifLastPlayTime = -1; public HippyImageSpan(Drawable d, String source, ImageNode node, - HippyImageLoader imageAdapter) { + HippyImageLoader imageAdapter, HippyEngineContext context) { super(d, source, node.getVerticalAlignment()); - - mImageNodeWeakRefrence = new WeakReference(node); + engineContext = context; + mImageNodeWeakRefrence = new WeakReference<>(node); mImageAdapter = imageAdapter; - - if(!TextUtils.isEmpty(source)) { - setUrl(source); - } + setUrl(source); } private void updateBoundsAttribute() { @@ -87,8 +95,12 @@ protected boolean shouldUseFetchImageMode(String url) { } private void loadImageWithUrl(String url) { + if (!TextUtils.isEmpty(mUrl) && mUrl.equals(url) && mImageLoadState != STATE_UNLOAD) { + return; + } + mUrl = url; - //mImageLoadState = STATE_UNLOAD; + mImageLoadState = STATE_UNLOAD; updateBoundsAttribute(); @@ -108,6 +120,10 @@ private void loadImageWithUrl(String url) { } public void setUrl(final String url) { + if (TextUtils.isEmpty(url)) { + return; + } + if (UIThreadUtils.isOnUiThread()) { loadImageWithUrl(url); } else { @@ -219,17 +235,45 @@ private void shouldReplaceDrawable(HippyDrawable hippyDrawable) { } catch (NoSuchFieldException e) { e.printStackTrace(); } + + mImageLoadState = STATE_LOADED; } else if (hippyDrawable.isAnimated()) { mGifMovie = hippyDrawable.getGIF(); + mImageLoadState = STATE_LOADED; + } else { + mImageLoadState = STATE_UNLOAD; } - postInvalidateDelayed(0); - //mImageLoadState = STATE_LOADED; + } else { + mImageLoadState = STATE_UNLOAD; + } + } + + private void sendImageLoadEvent(ImageEvent eventType) { + if (mImageNodeWeakRefrence == null) { + return; + } + + ImageNode node = mImageNodeWeakRefrence.get(); + if (node == null) { + return; + } + + String eventName = null; + if (eventType == ONLOAD) { + eventName = "onLoad"; + } else if (eventType == ONERROR) { + eventName = "onError"; + } + + if (!TextUtils.isEmpty(eventName) && node.isEnableImageEvent(eventType)) { + HippyViewEvent event = new HippyViewEvent(eventName); + event.send(node.getId(), engineContext, null); } } private void doFetchImage(String url, HippyMap props, HippyImageLoader imageAdapter) { - //mImageLoadState = STATE_LOADING; + mImageLoadState = STATE_LOADING; imageAdapter.fetchImage(url, new HippyImageLoader.Callback() { @Override @@ -239,11 +283,13 @@ public void onRequestStart(HippyDrawable hippyDrawable) { @Override public void onRequestSuccess(HippyDrawable hippyDrawable) { shouldReplaceDrawable(hippyDrawable); + sendImageLoadEvent(ONLOAD); } @Override public void onRequestFail(Throwable throwable, String source) { - //mImageLoadState = STATE_UNLOAD; + mImageLoadState = STATE_UNLOAD; + sendImageLoadEvent(ONERROR); } }, props); } diff --git a/android/sdk/src/main/java/com/tencent/mtt/hippy/dom/node/ImageNode.java b/android/sdk/src/main/java/com/tencent/mtt/hippy/dom/node/ImageNode.java index 2a72cc20624..c0888db2699 100644 --- a/android/sdk/src/main/java/com/tencent/mtt/hippy/dom/node/ImageNode.java +++ b/android/sdk/src/main/java/com/tencent/mtt/hippy/dom/node/ImageNode.java @@ -20,154 +20,147 @@ import com.tencent.mtt.hippy.annotation.HippyControllerProps; +import com.tencent.mtt.hippy.views.image.HippyImageView; +import com.tencent.mtt.hippy.views.image.HippyImageView.ImageEvent; import java.util.ArrayList; -public class ImageNode extends StyleNode -{ - public static final String PROP_VERTICAL_ALIGNMENT = "verticalAlignment"; - - private final boolean mIsVirtual; - private HippyImageSpan mImageSpan = null; - private int mVerticalAlignment = ImageSpan.ALIGN_BASELINE; - - private ArrayList mGestureTypes = null; - - public ImageNode(boolean mIsVirtual) { - this.mIsVirtual = mIsVirtual; - } - - public void setImageSpan(HippyImageSpan imageSpan) { - mImageSpan = imageSpan; - } - - public int getVerticalAlignment() { - return mVerticalAlignment; - } - - public boolean isVirtual() - { - return mIsVirtual; - } - - public ArrayList getGestureTypes() { - return mGestureTypes; - } - - @HippyControllerProps(name = NodeProps.ON_CLICK, defaultType = HippyControllerProps.BOOLEAN) - public void clickEnable(boolean flag) - { - if (flag) - { - if (mGestureTypes == null) - { - mGestureTypes = new ArrayList<>(); - } - mGestureTypes.add(NodeProps.ON_CLICK); - } - } - - @HippyControllerProps(name = NodeProps.ON_LONG_CLICK, defaultType = HippyControllerProps.BOOLEAN) - public void longClickEnable(boolean flag) - { - if (flag) - { - if (mGestureTypes == null) - { - mGestureTypes = new ArrayList<>(); - } - mGestureTypes.add(NodeProps.ON_LONG_CLICK); - } - } - - @HippyControllerProps(name = NodeProps.ON_PRESS_IN, defaultType = HippyControllerProps.BOOLEAN) - public void pressInEnable(boolean flag) - { - if (flag) - { - if (mGestureTypes == null) - { - mGestureTypes = new ArrayList<>(); - } - mGestureTypes.add(NodeProps.ON_PRESS_IN); - } - } - - @HippyControllerProps(name = NodeProps.ON_PRESS_OUT) - public void pressOutEnable(boolean flag) - { - if (flag) - { - if (mGestureTypes == null) - { - mGestureTypes = new ArrayList<>(); - } - mGestureTypes.add(NodeProps.ON_PRESS_OUT); - } - } - - @HippyControllerProps(name = NodeProps.ON_TOUCH_DOWN, defaultType = HippyControllerProps.BOOLEAN) - public void touchDownEnable(boolean flag) - { - if (flag) - { - if (mGestureTypes == null) - { - mGestureTypes = new ArrayList<>(); - } - mGestureTypes.add(NodeProps.ON_TOUCH_DOWN); - } - } - - @HippyControllerProps(name = NodeProps.ON_TOUCH_MOVE, defaultType = HippyControllerProps.BOOLEAN) - public void touchUpEnable(boolean flag) - { - if (flag) - { - if (mGestureTypes == null) - { - mGestureTypes = new ArrayList<>(); - } - mGestureTypes.add(NodeProps.ON_TOUCH_MOVE); - } - } - - @HippyControllerProps(name = NodeProps.ON_TOUCH_END, defaultType = HippyControllerProps.BOOLEAN) - public void touchEndEnable(boolean flag) - { - if (flag) - { - if (mGestureTypes == null) - { - mGestureTypes = new ArrayList<>(); - } - mGestureTypes.add(NodeProps.ON_TOUCH_END); - } - } - - @HippyControllerProps(name = NodeProps.ON_TOUCH_CANCEL, defaultType = HippyControllerProps.BOOLEAN) - public void touchCancelable(boolean flag) - { - if (flag) - { - if (mGestureTypes == null) - { - mGestureTypes = new ArrayList<>(); - } - mGestureTypes.add(NodeProps.ON_TOUCH_CANCEL); - } - } - - @HippyControllerProps(name = PROP_VERTICAL_ALIGNMENT, defaultType = HippyControllerProps.NUMBER, defaultNumber = ImageSpan.ALIGN_BASELINE) - public void setVerticalAlignment(int verticalAlignment) - { - mVerticalAlignment = verticalAlignment; - } - - @HippyControllerProps(name = "src", defaultType = HippyControllerProps.STRING) - public void setUrl(String url) - { - if (mImageSpan != null) { - mImageSpan.setUrl(url); - } - } +public class ImageNode extends StyleNode { + + public static final String PROP_VERTICAL_ALIGNMENT = "verticalAlignment"; + + private final boolean mIsVirtual; + private HippyImageSpan mImageSpan = null; + private int mVerticalAlignment = ImageSpan.ALIGN_BASELINE; + private final boolean[] shouldSendImageEvent; + + private ArrayList mGestureTypes = null; + + public ImageNode(boolean mIsVirtual) { + this.mIsVirtual = mIsVirtual; + shouldSendImageEvent = new boolean[ImageEvent.values().length]; + } + + public void setImageSpan(HippyImageSpan imageSpan) { + mImageSpan = imageSpan; + } + + public boolean isEnableImageEvent(ImageEvent event) { + return shouldSendImageEvent[event.ordinal()]; + } + + public int getVerticalAlignment() { + return mVerticalAlignment; + } + + public boolean isVirtual() { + return mIsVirtual; + } + + public ArrayList getGestureTypes() { + return mGestureTypes; + } + + @HippyControllerProps(name = NodeProps.ON_CLICK, defaultType = HippyControllerProps.BOOLEAN) + public void clickEnable(boolean flag) { + if (flag) { + if (mGestureTypes == null) { + mGestureTypes = new ArrayList<>(); + } + mGestureTypes.add(NodeProps.ON_CLICK); + } + } + + @HippyControllerProps(name = NodeProps.ON_LONG_CLICK, defaultType = HippyControllerProps.BOOLEAN) + public void longClickEnable(boolean flag) { + if (flag) { + if (mGestureTypes == null) { + mGestureTypes = new ArrayList<>(); + } + mGestureTypes.add(NodeProps.ON_LONG_CLICK); + } + } + + @HippyControllerProps(name = NodeProps.ON_PRESS_IN, defaultType = HippyControllerProps.BOOLEAN) + public void pressInEnable(boolean flag) { + if (flag) { + if (mGestureTypes == null) { + mGestureTypes = new ArrayList<>(); + } + mGestureTypes.add(NodeProps.ON_PRESS_IN); + } + } + + @HippyControllerProps(name = NodeProps.ON_PRESS_OUT) + public void pressOutEnable(boolean flag) { + if (flag) { + if (mGestureTypes == null) { + mGestureTypes = new ArrayList<>(); + } + mGestureTypes.add(NodeProps.ON_PRESS_OUT); + } + } + + @HippyControllerProps(name = NodeProps.ON_TOUCH_DOWN, defaultType = HippyControllerProps.BOOLEAN) + public void touchDownEnable(boolean flag) { + if (flag) { + if (mGestureTypes == null) { + mGestureTypes = new ArrayList<>(); + } + mGestureTypes.add(NodeProps.ON_TOUCH_DOWN); + } + } + + @HippyControllerProps(name = NodeProps.ON_TOUCH_MOVE, defaultType = HippyControllerProps.BOOLEAN) + public void touchUpEnable(boolean flag) { + if (flag) { + if (mGestureTypes == null) { + mGestureTypes = new ArrayList<>(); + } + mGestureTypes.add(NodeProps.ON_TOUCH_MOVE); + } + } + + @HippyControllerProps(name = NodeProps.ON_TOUCH_END, defaultType = HippyControllerProps.BOOLEAN) + public void touchEndEnable(boolean flag) { + if (flag) { + if (mGestureTypes == null) { + mGestureTypes = new ArrayList<>(); + } + mGestureTypes.add(NodeProps.ON_TOUCH_END); + } + } + + @HippyControllerProps(name = NodeProps.ON_TOUCH_CANCEL, defaultType = HippyControllerProps.BOOLEAN) + public void touchCancelable(boolean flag) { + if (flag) { + if (mGestureTypes == null) { + mGestureTypes = new ArrayList<>(); + } + mGestureTypes.add(NodeProps.ON_TOUCH_CANCEL); + } + } + + @HippyControllerProps(name = PROP_VERTICAL_ALIGNMENT, defaultType = HippyControllerProps.NUMBER, defaultNumber = ImageSpan.ALIGN_BASELINE) + public void setVerticalAlignment(int verticalAlignment) { + mVerticalAlignment = verticalAlignment; + } + + @HippyControllerProps(name = "src", defaultType = HippyControllerProps.STRING) + public void setUrl(String url) { + if (mImageSpan != null) { + mImageSpan.setUrl(url); + } + } + + @SuppressWarnings("unused") + @HippyControllerProps(name = "onLoad", defaultType = HippyControllerProps.BOOLEAN) + public void setOnLoadEnd(boolean enable) { + shouldSendImageEvent[ImageEvent.ONLOAD.ordinal()] = enable; + } + + @SuppressWarnings("unused") + @HippyControllerProps(name = "onError", defaultType = HippyControllerProps.BOOLEAN) + public void setOnError(boolean enable) { + shouldSendImageEvent[ImageEvent.ONERROR.ordinal()] = enable; + } } diff --git a/android/sdk/src/main/java/com/tencent/mtt/hippy/dom/node/TextNode.java b/android/sdk/src/main/java/com/tencent/mtt/hippy/dom/node/TextNode.java index 8eb5338fa39..2779e240644 100644 --- a/android/sdk/src/main/java/com/tencent/mtt/hippy/dom/node/TextNode.java +++ b/android/sdk/src/main/java/com/tencent/mtt/hippy/dom/node/TextNode.java @@ -448,12 +448,14 @@ public void setNumberOfLines(int numberOfLines) } protected HippyFontScaleAdapter mFontScaleAdapter; - + protected HippyEngineContext engineContext; protected HippyImageLoader mImageAdapter; @Override public void layoutBefore(HippyEngineContext context) { super.layoutBefore(context); + + engineContext = context; if (mFontScaleAdapter == null) { mFontScaleAdapter = context.getGlobalConfigs().getFontScaleAdapter(); } @@ -529,7 +531,7 @@ private void createImageSpanOperation(List ops, SpannableStringBu int height = Math.round(imageNode.getStyleHeight()); drawable.setBounds(0, 0, width, height); - HippyImageSpan imageSpan = new HippyImageSpan(drawable, url, imageNode, mImageAdapter); + HippyImageSpan imageSpan = new HippyImageSpan(drawable, url, imageNode, mImageAdapter, engineContext); imageNode.setImageSpan(imageSpan); int start = sb.length(); diff --git a/android/sdk/src/main/java/com/tencent/mtt/hippy/uimanager/HippyViewEvent.java b/android/sdk/src/main/java/com/tencent/mtt/hippy/uimanager/HippyViewEvent.java index 6b2804cadbd..9e902de42c6 100644 --- a/android/sdk/src/main/java/com/tencent/mtt/hippy/uimanager/HippyViewEvent.java +++ b/android/sdk/src/main/java/com/tencent/mtt/hippy/uimanager/HippyViewEvent.java @@ -22,35 +22,29 @@ import com.tencent.mtt.hippy.modules.HippyModuleManager; import com.tencent.mtt.hippy.modules.javascriptmodules.EventDispatcher; -/** - * FileName: HippyViewEvent - * Description: - * History: - */ -public class HippyViewEvent -{ +public class HippyViewEvent { - private final String mEventName; + private final String mEventName; - public HippyViewEvent(String eventName) - { - this.mEventName = eventName; - } + public HippyViewEvent(String eventName) { + this.mEventName = eventName; + } + + public void send(View view, Object param) { + if (view != null && view.getContext() instanceof HippyInstanceContext) { + HippyEngineContext context = ((HippyInstanceContext)view.getContext()).getEngineContext(); + send(view.getId(), context, param); + } + } + + public void send(int id, HippyEngineContext context, Object param) { + if (context == null) { + return; + } - public void send(View view, Object param) - { - if (view != null && view.getContext() instanceof HippyInstanceContext) - { - HippyEngineContext context = ((HippyInstanceContext) view.getContext()).getEngineContext(); - if (context == null) - { - return; - } - HippyModuleManager hmm = context.getModuleManager(); - if (hmm != null) - { - hmm.getJavaScriptModule(EventDispatcher.class).receiveUIComponentEvent(view.getId(), mEventName, param); - } + HippyModuleManager hmm = context.getModuleManager(); + if (hmm != null) { + hmm.getJavaScriptModule(EventDispatcher.class).receiveUIComponentEvent(id, mEventName, param); } } } diff --git a/android/sdk/src/main/java/com/tencent/mtt/hippy/views/image/HippyImageView.java b/android/sdk/src/main/java/com/tencent/mtt/hippy/views/image/HippyImageView.java index 8030af802ed..4ed715d5400 100644 --- a/android/sdk/src/main/java/com/tencent/mtt/hippy/views/image/HippyImageView.java +++ b/android/sdk/src/main/java/com/tencent/mtt/hippy/views/image/HippyImageView.java @@ -100,7 +100,7 @@ public void clear() mTintColor = 0; } - enum ImageEvent + public enum ImageEvent { ONLOAD, ONLOAD_START,