feat:Android use ObjectAnimator to implement animate plugin
This commit is contained in:
parent
dd69a3f150
commit
410ad72d71
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package pub.doric;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.content.Context;
|
||||
|
||||
import com.github.pengfeizhou.jscore.JSDecoder;
|
||||
@ -193,4 +195,15 @@ public class DoricContext {
|
||||
public IDoricNavBar getDoricNavBar() {
|
||||
return this.doricNavBar;
|
||||
}
|
||||
|
||||
private AnimatorSet animatorSet;
|
||||
|
||||
public void setAnimatorSet(AnimatorSet animatorSet) {
|
||||
this.animatorSet = animatorSet;
|
||||
}
|
||||
|
||||
public AnimatorSet getAnimatorSet() {
|
||||
return this.animatorSet;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import android.text.TextUtils;
|
||||
import pub.doric.loader.DoricAssetJSLoader;
|
||||
import pub.doric.loader.DoricHttpJSLoader;
|
||||
import pub.doric.loader.IDoricJSLoader;
|
||||
import pub.doric.plugin.AnimatePlugin;
|
||||
import pub.doric.plugin.NavBarPlugin;
|
||||
import pub.doric.plugin.NavigatorPlugin;
|
||||
import pub.doric.plugin.NetworkPlugin;
|
||||
@ -89,6 +90,7 @@ public class DoricRegistry {
|
||||
this.registerNativePlugin(NavigatorPlugin.class);
|
||||
this.registerNativePlugin(NavBarPlugin.class);
|
||||
this.registerNativePlugin(PopoverPlugin.class);
|
||||
this.registerNativePlugin(AnimatePlugin.class);
|
||||
|
||||
this.registerViewNode(RootNode.class);
|
||||
this.registerViewNode(TextNode.class);
|
||||
|
@ -0,0 +1,86 @@
|
||||
package pub.doric.plugin;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.pengfeizhou.jscore.JSObject;
|
||||
import com.github.pengfeizhou.jscore.JavaValue;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import pub.doric.DoricContext;
|
||||
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.RootNode;
|
||||
import pub.doric.shader.ViewNode;
|
||||
import pub.doric.utils.DoricLog;
|
||||
import pub.doric.utils.ThreadMode;
|
||||
|
||||
/**
|
||||
* @Description: pub.doric.plugin
|
||||
* @Author: pengfei.zhou
|
||||
* @CreateDate: 2019-11-29
|
||||
*/
|
||||
@DoricPlugin(name = "animate")
|
||||
public class AnimatePlugin extends DoricJavaPlugin {
|
||||
public AnimatePlugin(DoricContext doricContext) {
|
||||
super(doricContext);
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
public void submit(DoricPromise promise) {
|
||||
promise.resolve();
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
public void animateRender(final JSObject jsObject, final DoricPromise promise) {
|
||||
getDoricContext().getDriver().asyncCall(new Callable<Object>() {
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
final long duration = jsObject.getProperty("duration").asNumber().toLong();
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
getDoricContext().setAnimatorSet(animatorSet);
|
||||
String viewId = jsObject.getProperty("id").asString().value();
|
||||
RootNode rootNode = getDoricContext().getRootNode();
|
||||
if (TextUtils.isEmpty(rootNode.getId())) {
|
||||
rootNode.setId(viewId);
|
||||
rootNode.blend(jsObject.getProperty("props").asObject());
|
||||
} else {
|
||||
ViewNode viewNode = getDoricContext().targetViewNode(viewId);
|
||||
if (viewNode != null) {
|
||||
viewNode.blend(jsObject.getProperty("props").asObject());
|
||||
}
|
||||
}
|
||||
getDoricContext().setAnimatorSet(null);
|
||||
animatorSet.setDuration(duration);
|
||||
animatorSet.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
promise.resolve();
|
||||
}
|
||||
});
|
||||
animatorSet.start();
|
||||
return null;
|
||||
}
|
||||
}, ThreadMode.UI).setCallback(new AsyncResult.Callback<Object>() {
|
||||
@Override
|
||||
public void onResult(Object result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable t) {
|
||||
t.printStackTrace();
|
||||
DoricLog.e("Shader.render:error%s", t.getLocalizedMessage());
|
||||
promise.reject(new JavaValue(t.getLocalizedMessage()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package pub.doric.shader;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -123,16 +125,48 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
||||
protected void blend(T view, String name, JSValue prop) {
|
||||
switch (name) {
|
||||
case "width":
|
||||
setWidth(prop.asNumber().toFloat());
|
||||
if (isAnimating()) {
|
||||
addAnimator(ObjectAnimator.ofFloat(
|
||||
this,
|
||||
name,
|
||||
getWidth(),
|
||||
prop.asNumber().toFloat()));
|
||||
} else {
|
||||
setWidth(prop.asNumber().toFloat());
|
||||
}
|
||||
break;
|
||||
case "height":
|
||||
setHeight(prop.asNumber().toFloat());
|
||||
if (isAnimating()) {
|
||||
addAnimator(ObjectAnimator.ofFloat(
|
||||
this,
|
||||
name,
|
||||
getHeight(),
|
||||
prop.asNumber().toFloat()));
|
||||
} else {
|
||||
setHeight(prop.asNumber().toFloat());
|
||||
}
|
||||
break;
|
||||
case "x":
|
||||
setX(prop.asNumber().toFloat());
|
||||
if (isAnimating()) {
|
||||
addAnimator(ObjectAnimator.ofFloat(
|
||||
this,
|
||||
name,
|
||||
getX(),
|
||||
prop.asNumber().toFloat()));
|
||||
} else {
|
||||
setX(prop.asNumber().toFloat());
|
||||
}
|
||||
break;
|
||||
case "y":
|
||||
setY(prop.asNumber().toFloat());
|
||||
if (isAnimating()) {
|
||||
addAnimator(ObjectAnimator.ofFloat(
|
||||
this,
|
||||
name,
|
||||
getY(),
|
||||
prop.asNumber().toFloat()));
|
||||
} else {
|
||||
setY(prop.asNumber().toFloat());
|
||||
}
|
||||
break;
|
||||
case "bgColor":
|
||||
view.setBackgroundColor(prop.asNumber().toInt());
|
||||
@ -244,30 +278,6 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
||||
return mId;
|
||||
}
|
||||
|
||||
protected void setWidth(float width) {
|
||||
if (mLayoutParams.width >= 0) {
|
||||
mLayoutParams.width = DoricUtils.dp2px(width);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setHeight(float height) {
|
||||
if (mLayoutParams.height >= 0) {
|
||||
mLayoutParams.height = DoricUtils.dp2px(height);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setX(float x) {
|
||||
if (mLayoutParams instanceof ViewGroup.MarginLayoutParams) {
|
||||
((ViewGroup.MarginLayoutParams) mLayoutParams).leftMargin = DoricUtils.dp2px(x);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setY(float y) {
|
||||
if (mLayoutParams instanceof ViewGroup.MarginLayoutParams) {
|
||||
((ViewGroup.MarginLayoutParams) mLayoutParams).topMargin = DoricUtils.dp2px(y);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setLayoutConfig(JSObject layoutConfig) {
|
||||
if (mSuperNode != null) {
|
||||
mSuperNode.blendSubLayoutConfig(this, layoutConfig);
|
||||
@ -329,14 +339,25 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
||||
}
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
public int getWidth() {
|
||||
return getNodeView().getWidth();
|
||||
protected boolean isAnimating() {
|
||||
return getDoricContext().getAnimatorSet() != null;
|
||||
}
|
||||
|
||||
protected void addAnimator(Animator animator) {
|
||||
if (getDoricContext().getAnimatorSet() == null) {
|
||||
return;
|
||||
}
|
||||
getDoricContext().getAnimatorSet().play(animator);
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
public int getHeight() {
|
||||
return getNodeView().getHeight();
|
||||
public float getWidth() {
|
||||
return DoricUtils.px2dp(getNodeView().getWidth());
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
public float getHeight() {
|
||||
return DoricUtils.px2dp(getNodeView().getHeight());
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
@ -355,4 +376,53 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
||||
public float getRotation() {
|
||||
return getNodeView().getRotation() / 360;
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
protected void setWidth(float width) {
|
||||
if (mLayoutParams.width >= 0) {
|
||||
mLayoutParams.width = DoricUtils.dp2px(width);
|
||||
mView.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
protected void setHeight(float height) {
|
||||
if (mLayoutParams.height >= 0) {
|
||||
mLayoutParams.height = DoricUtils.dp2px(height);
|
||||
mView.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
protected void setX(float x) {
|
||||
if (mLayoutParams instanceof ViewGroup.MarginLayoutParams) {
|
||||
((ViewGroup.MarginLayoutParams) mLayoutParams).leftMargin = DoricUtils.dp2px(x);
|
||||
mView.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
protected void setY(float y) {
|
||||
if (mLayoutParams instanceof ViewGroup.MarginLayoutParams) {
|
||||
((ViewGroup.MarginLayoutParams) mLayoutParams).topMargin = DoricUtils.dp2px(y);
|
||||
mView.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
public float getX() {
|
||||
if (mLayoutParams instanceof ViewGroup.MarginLayoutParams) {
|
||||
return DoricUtils.px2dp(((ViewGroup.MarginLayoutParams) mLayoutParams).leftMargin);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
public float getY() {
|
||||
if (mLayoutParams instanceof ViewGroup.MarginLayoutParams) {
|
||||
return DoricUtils.px2dp(((ViewGroup.MarginLayoutParams) mLayoutParams).topMargin);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { title, label, colors, box } from "./utils";
|
||||
class AnimatorDemo extends Panel {
|
||||
build(rootView: Group): void {
|
||||
const view = box(2)
|
||||
scroller(vlayout([
|
||||
vlayout([
|
||||
title("Animator Demo"),
|
||||
label('Reset').apply({
|
||||
width: 100,
|
||||
@ -79,11 +79,9 @@ class AnimatorDemo extends Panel {
|
||||
bgColor: colors[1].alpha(0.3 * 255),
|
||||
}),
|
||||
]).apply({
|
||||
layoutConfig: layoutConfig().atmost().h(LayoutSpec.WRAP_CONTENT),
|
||||
layoutConfig: layoutConfig().atmost(),
|
||||
gravity: gravity().center(),
|
||||
space: 10,
|
||||
} as IVLayout)).apply({
|
||||
layoutConfig: layoutConfig().atmost(),
|
||||
}).in(rootView)
|
||||
} as IVLayout).in(rootView)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user