diff --git a/Android/doric/src/main/java/pub/doric/plugin/PopoverPlugin.java b/Android/doric/src/main/java/pub/doric/plugin/PopoverPlugin.java index 136d5c28..457b168b 100644 --- a/Android/doric/src/main/java/pub/doric/plugin/PopoverPlugin.java +++ b/Android/doric/src/main/java/pub/doric/plugin/PopoverPlugin.java @@ -1,15 +1,26 @@ package pub.doric.plugin; +import android.app.Activity; +import android.graphics.Color; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; + import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSValue; import com.github.pengfeizhou.jscore.JavaValue; +import java.util.concurrent.Callable; + import pub.doric.DoricContext; +import pub.doric.async.AsyncCall; +import pub.doric.async.AsyncResult; import pub.doric.extension.bridge.DoricMethod; import pub.doric.extension.bridge.DoricPlugin; import pub.doric.extension.bridge.DoricPromise; import pub.doric.shader.ViewNode; +import pub.doric.utils.ThreadMode; /** * @Description: pub.doric.plugin @@ -18,15 +29,54 @@ import pub.doric.shader.ViewNode; */ @DoricPlugin(name = "popover") public class PopoverPlugin extends DoricJavaPlugin { + private FrameLayout mFullScreenView; public PopoverPlugin(DoricContext doricContext) { super(doricContext); } @DoricMethod - public void show(JSDecoder decoder, DoricPromise promise) { + public void show(JSDecoder decoder, final DoricPromise promise) { try { - JSObject jsObject = decoder.decode().asObject(); + final JSObject jsObject = decoder.decode().asObject(); + getDoricContext().getDriver().asyncCall(new Callable() { + @Override + public Object call() throws Exception { + if (mFullScreenView == null) { + mFullScreenView = new FrameLayout(getDoricContext().getContext()); + ViewGroup decorView = (ViewGroup) getDoricContext().getRootNode().getNodeView().getRootView(); + decorView.addView(mFullScreenView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + } + mFullScreenView.setVisibility(View.VISIBLE); + mFullScreenView.bringToFront(); + String viewId = jsObject.getProperty("id").asString().value(); + String type = jsObject.getProperty("type").asString().value(); + ViewNode node = ViewNode.create(getDoricContext(), type); + node.setId(viewId); + node.init(new FrameLayout.LayoutParams(0, 0)); + node.blend(jsObject.getProperty("props").asObject()); + mFullScreenView.addView(node.getNodeView()); + getDoricContext().addHeadNode(node); + return null; + } + }, ThreadMode.UI).setCallback(new AsyncResult.Callback() { + @Override + public void onResult(Object result) { + promise.resolve(); + } + + @Override + public void onError(Throwable t) { + t.printStackTrace(); + promise.reject(new JavaValue(t.getLocalizedMessage())); + } + + @Override + public void onFinish() { + + } + }); } catch (Exception e) { e.printStackTrace(); promise.reject(new JavaValue(e.getLocalizedMessage())); @@ -34,17 +84,39 @@ public class PopoverPlugin extends DoricJavaPlugin { } @DoricMethod - public void dismiss(JSDecoder decoder, DoricPromise promise) { + public void dismiss(final JSValue value, final DoricPromise promise) { try { - JSObject jsObject = decoder.decode().asObject(); - JSValue value = jsObject.getProperty("id"); - if (value.isString()) { - String viewId = value.asString().value(); - ViewNode node = getDoricContext().targetViewNode(viewId); - dismissViewNode(node); - } else { + getDoricContext().getDriver().asyncCall(new Callable() { + @Override + public Object call() throws Exception { + if (value.isObject()) { + String viewId = value.asObject().getProperty("id").asString().value(); + ViewNode node = getDoricContext().targetViewNode(viewId); + dismissViewNode(node); + } else { + dismissPopover(); + } + return null; + } + }, ThreadMode.UI).setCallback(new AsyncResult.Callback() { + @Override + public void onResult(Object result) { + promise.resolve(); + } + + @Override + public void onError(Throwable t) { + t.printStackTrace(); + promise.reject(new JavaValue(t.getLocalizedMessage())); + } + + @Override + public void onFinish() { + + } + }); + - } } catch (Exception e) { e.printStackTrace(); promise.reject(new JavaValue(e.getLocalizedMessage())); @@ -52,6 +124,16 @@ public class PopoverPlugin extends DoricJavaPlugin { } private void dismissViewNode(ViewNode node) { + getDoricContext().removeHeadNode(node); + mFullScreenView.removeView(node.getNodeView()); + if (getDoricContext().allHeadNodes().isEmpty()) { + mFullScreenView.setVisibility(View.GONE); + } + } + private void dismissPopover() { + for (ViewNode node : getDoricContext().allHeadNodes()) { + dismissViewNode(node); + } } } diff --git a/Android/doric/src/main/java/pub/doric/shader/ViewNode.java b/Android/doric/src/main/java/pub/doric/shader/ViewNode.java index 39decdcf..204291be 100644 --- a/Android/doric/src/main/java/pub/doric/shader/ViewNode.java +++ b/Android/doric/src/main/java/pub/doric/shader/ViewNode.java @@ -66,6 +66,12 @@ public abstract class ViewNode extends DoricContextHolder { this.mView.setLayoutParams(mLayoutParams); } + public void init(ViewGroup.LayoutParams layoutParams) { + this.mLayoutParams = layoutParams; + this.mView = build(); + this.mView.setLayoutParams(layoutParams); + } + public void setId(String id) { this.mId = id; } @@ -265,6 +271,61 @@ public abstract class ViewNode extends DoricContextHolder { protected void setLayoutConfig(JSObject layoutConfig) { if (mSuperNode != null) { mSuperNode.blendSubLayoutConfig(this, layoutConfig); + } else { + blendLayoutConfig(layoutConfig); + } + } + + private void blendLayoutConfig(JSObject jsObject) { + JSValue margin = jsObject.getProperty("margin"); + JSValue widthSpec = jsObject.getProperty("widthSpec"); + JSValue heightSpec = jsObject.getProperty("heightSpec"); + ViewGroup.LayoutParams layoutParams = getLayoutParams(); + if (widthSpec.isNumber()) { + switch (widthSpec.asNumber().toInt()) { + case 1: + layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT; + break; + case 2: + layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT; + break; + default: + break; + } + } + if (heightSpec.isNumber()) { + switch (heightSpec.asNumber().toInt()) { + case 1: + layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; + break; + case 2: + layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT; + break; + default: + break; + } + } + if (margin.isObject() && layoutParams instanceof ViewGroup.MarginLayoutParams) { + JSValue topVal = margin.asObject().getProperty("top"); + if (topVal.isNumber()) { + ((ViewGroup.MarginLayoutParams) layoutParams).topMargin = DoricUtils.dp2px(topVal.asNumber().toFloat()); + } + JSValue leftVal = margin.asObject().getProperty("left"); + if (leftVal.isNumber()) { + ((ViewGroup.MarginLayoutParams) layoutParams).leftMargin = DoricUtils.dp2px(leftVal.asNumber().toFloat()); + } + JSValue rightVal = margin.asObject().getProperty("right"); + if (rightVal.isNumber()) { + ((ViewGroup.MarginLayoutParams) layoutParams).rightMargin = DoricUtils.dp2px(rightVal.asNumber().toFloat()); + } + JSValue bottomVal = margin.asObject().getProperty("bottom"); + if (bottomVal.isNumber()) { + ((ViewGroup.MarginLayoutParams) layoutParams).bottomMargin = DoricUtils.dp2px(bottomVal.asNumber().toFloat()); + } + } + JSValue jsValue = jsObject.getProperty("alignment"); + if (jsValue.isNumber() && layoutParams instanceof FrameLayout.LayoutParams) { + ((FrameLayout.LayoutParams) layoutParams).gravity = jsValue.asNumber().toInt(); } } diff --git a/demo/src/PopoverDemo.ts b/demo/src/PopoverDemo.ts index ca95c458..b78a5c63 100644 --- a/demo/src/PopoverDemo.ts +++ b/demo/src/PopoverDemo.ts @@ -21,17 +21,15 @@ class PopoverDemo extends Panel { textColor: Color.WHITE, layoutConfig: layoutConfig().exactly().a(Gravity.Center), text: "This is PopOver Window", - onClick: () => { - modal(context).toast('Dismissed after 3 seconds') - setTimeout(() => { - popover(context).dismiss() - }, 3000) - }, }).also(v => { let idx = 0 v.onClick = () => { v.bgColor = colors[(++idx) % colors.length] } + modal(context).toast('Dismissed after 3 seconds') + setTimeout(() => { + popover(context).dismiss() + }, 3000) })) } } as IText),