From 9a95e17de202c8b9c77a181317582787584b831b Mon Sep 17 00:00:00 2001 From: liliang Date: Thu, 22 Jul 2021 14:56:14 +0800 Subject: [PATCH 1/3] add api benchmarking --- animation/AnimatorHelp.md | 176 ++++++++++++++++++++++++++++++++++++ animation/BoomMenuButton.md | 35 +++++++ app/ActionBarAbility.md | 48 ++++++++++ util/Sequenceable.md | 18 ++++ 4 files changed, 277 insertions(+) create mode 100644 animation/AnimatorHelp.md create mode 100644 animation/BoomMenuButton.md create mode 100644 app/ActionBarAbility.md create mode 100644 util/Sequenceable.md diff --git a/animation/AnimatorHelp.md b/animation/AnimatorHelp.md new file mode 100644 index 0000000..6770a9d --- /dev/null +++ b/animation/AnimatorHelp.md @@ -0,0 +1,176 @@ +### **实现缩放动画** +>+ openharmony SDK版本:2.1.1.18 +>+ IDE版本:2.1.0.301 +>+ 实现方案: + +追加AnimatorHelp类,在AnimationManager类中调用AnimatorHelp的getPropertyAnimator方法,实现缩放动画 + +步骤一: 追加AnimatorHelp类 +```java + public final class AnimatorHelp { + + private AnimatorHelp() { + } + + private static DecimalFormat decFormat = new DecimalFormat("0.00"); + + public static PropertyValuesHolder onf(String property, float... values) { + + Keyframe[] keyframes = new Keyframe[values.length]; + for (int i = 0; i < values.length; i++) { + float pro = (float) (i + 1) / values.length; + keyframes[i] = Keyframe.ofFloat(Float.parseFloat(decFormat.format(pro)), values[i]); + } + return new PropertyValuesHolder(property, keyframes); + } + + public static AnimatorValue getPropertyAnimator(Component component, String property, Keyframe... frames) { + return getPropertyAnimator(component, new PropertyValuesHolder(property, frames)); + } + + public static AnimatorValue getPropertyAnimator(final Component component, PropertyValuesHolder... holders) { + + AnimatorValue animatorValue = new AnimatorValue(); + + animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() { + @Override + public void onUpdate(AnimatorValue animatorValue, float v) { + valueUpdate(animatorValue, v, component, holders); + } + }); + return animatorValue; + } + + public static void valueUpdate(AnimatorValue animatorValue, float v, final Component component, PropertyValuesHolder... holders) { + for (PropertyValuesHolder holder : holders) { + Keyframe[] frames = holder.getFrames(); + for (int i = 0; i < frames.length; i++) { + float value; + float value2; + float progress = i == 0 ? 0 : frames[i - 1].getProgress();//动画进度 + float incremental = i == 0 ? frames[i].getProgress() : frames[i].getProgress() - frames[i - 1].getProgress();//增量 + + if (v >= progress && v <= (frames[i].getProgress())) { + float rate = (v - progress) / incremental;//增量进度 + value = i == 0 ? 0 : frames[i - 1].getValue(); + value2 = frames[i].getValue(); + switch (holder.getProperty()) { + case "scaleX": + component.setScaleX(value + (value2 - value) * rate); + break; + case "scaleY": + component.setScaleY(value + (value2 - value) * rate); + break; + case "alpha": + component.setAlpha(value + (value2 - value) * rate); + break; + case "translationX": + component.setTranslationX(value + (value2 - value) * rate); + break; + case "translationY": + component.setTranslationY(value + (value2 - value) * rate); + break; + case "rotation": + component.setRotation(value + (value2 - value) * rate); + break; + case "pivotX": + component.setPivotX(value2); + break; + case "pivotY": + component.setPivotY(value2); + break; + case "showProcess": + case "hideProcess": + Util.InvokeProperty(component, holder.getProperty(), value2); + break; + default: + break; + + } + } + } + } + } + + public static class Keyframe { + private float progress; + private float value; + + public Keyframe(float newProgress, float newValue) { + this.progress = newProgress; + this.value = newValue; + } + + public static Keyframe ofFloat(float progress, float value) { + return new Keyframe(progress, value); + } + + /** + * @params + * @return + * @description get the progress + */ + public float getProgress() { + return this.progress; + } + + /** + * @params + * @return + * @description get the value + */ + public float getValue() { + return this.value; + } + } + + public static class PropertyValuesHolder { + private String property; + private Keyframe[] frames; + + public PropertyValuesHolder(String newProperty, Keyframe[] newFrames) { + this.property = newProperty; + this.frames = newFrames.clone(); + } + + /** + * @params + * @return + * @description get the property + */ + public String getProperty() { + return this.property; + } + + /** + * @params + * @return + * @description get the frames + */ + public Keyframe[] getFrames() { + return this.frames.clone(); + } + } + + } +``` + +步骤二: 在AnimationManager类中调用AnimatorHelp的getPropertyAnimator方法 +```java +public final class AnimationManager { + + private AnimationManager(){} + + public static Animator animate(Component component, String property, long delay, long duration, + Animator.TimelineCurve interpolator, + StateChangedListener listenerAdapter, float... values) { + AnimatorValue animator = AnimatorHelp.getPropertyAnimator(component, AnimatorHelp.onf(property, values)); + animator.setDelay(delay); + animator.setDuration(duration); + if (interpolator != null) animator.setCurve(interpolator); + if (listenerAdapter != null) animator.setStateChangedListener(listenerAdapter); + animator.start(); + return animator; + } + } + ``` \ No newline at end of file diff --git a/animation/BoomMenuButton.md b/animation/BoomMenuButton.md new file mode 100644 index 0000000..12af358 --- /dev/null +++ b/animation/BoomMenuButton.md @@ -0,0 +1,35 @@ +### **获取菜单的layout属性** +>+ openharmony SDK版本:2.1.1.18 +>+ IDE版本:2.1.0.301 +>+ 实现方案: +```java + private void attrsLayout(Context context, AttrSet attrSet) { + this.context = context; + + for (int i = 0; i < attrSet.getLength(); i++) { + Attr attr = attrSet.getAttr(i).get(); + String attrName = attr.getName(); + String attrValue = attr.getStringValue(); + switch (attrName) { + case BMB_CACHE_OPTIMIZATION: + if(attrValue != null && !"".equals(attrValue)){ + cacheOptimization = attr.getBoolValue(); + } + break; + case BMB_BOOM_IN_WHOLE_SCREEN: + if(attrValue != null && !"".equals(attrValue)){ + boomInWholeScreen = attr.getBoolValue(); + } + break; + ..... + break; + case BMB_BOTTOM_HAM_BUTTON_TOP_MARGIN: + if(attrValue != null && !"".equals(attrValue)){ + bottomHamButtonTopMargin = attr.getFloatValue(); + } + break; + } + } + } +``` +>+ 补充说明:在BoomMenuButton类的initAttrs方法里追加调用attrsLayout方法来获取菜单layout的属性。 \ No newline at end of file diff --git a/app/ActionBarAbility.md b/app/ActionBarAbility.md new file mode 100644 index 0000000..04f8a35 --- /dev/null +++ b/app/ActionBarAbility.md @@ -0,0 +1,48 @@ +### **动画页面调用方式** +>+ openharmony API: ohos.aafwk.ability.Ability +>+ openharmony SDK版本:2.1.1.18 +>+ IDE版本:2.1.0.301 +>+ 实现方案: +* 原库实现 +ActionBarActivity里面直接调用xml页面文件, +```java +public class ActionBarActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + View actionBar = mInflater.inflate(R.layout.custom_actionbar, null); + TextView mTitleTextView = (TextView) actionBar.findViewById(R.id.title_text); + } +} +``` + +* 替换实现 +需要通过ActionBarAbility调用ActionBarAbilitySlice再调用xml文件 +```java +public class ActionBarAbility extends Ability { + + @Override + public void onStart(Intent intent) { + super.onStart(intent); + super.setMainRoute(ActionBarAbilitySlice.class.getName()); + } +} + +public class ActionBarAbilitySlice extends AbilitySlice { + + private ToolBar toolBar; + private BoomMenuButton bmb; + + @Override + public void onStart(Intent intent) { + super.onStart(intent); + + ComponentContainer cc = initView(); + super.setUIContent(cc); + LayoutScatter mInflater = LayoutScatter.getInstance(this); + + Component actionBar = mInflater.parse(ResourceTable.Layout_custom_actionbar, null,true); + } + +} +``` diff --git a/util/Sequenceable.md b/util/Sequenceable.md new file mode 100644 index 0000000..317e5a5 --- /dev/null +++ b/util/Sequenceable.md @@ -0,0 +1,18 @@ +### **Rect** +>+ openharmony API: ohos.utils.Sequenceable +>+ openharmony SDK版本:2.1.1.21 以上 +>+ IDE版本:2.1.0.501 +>+ 实现方案:实现Sequenceable接口,并实现Producer()方法: + +```java +public class Rect implements Sequenceable { + public static final Producer PRODUCER = new Producer() { + @Override + public Rect createFromParcel(Parcel source) { + return new Rect(source); + } + }; +} +``` + +>+ 补充说明:新做成的类需要序列化和反序列化,实现Sequenceable接口和Producer,实现Sequenceable接口和Producer()方法。 -- Gitee From 5fc04d8fb25dc8efa759e44fa4930c1b4df34e42 Mon Sep 17 00:00:00 2001 From: liliang Date: Thu, 22 Jul 2021 15:19:47 +0800 Subject: [PATCH 2/3] remove files --- animation/AnimatorHelp.md | 176 ------------------------------------ animation/BoomMenuButton.md | 35 ------- app/ActionBarAbility.md | 48 ---------- 3 files changed, 259 deletions(-) delete mode 100644 animation/AnimatorHelp.md delete mode 100644 animation/BoomMenuButton.md delete mode 100644 app/ActionBarAbility.md diff --git a/animation/AnimatorHelp.md b/animation/AnimatorHelp.md deleted file mode 100644 index 6770a9d..0000000 --- a/animation/AnimatorHelp.md +++ /dev/null @@ -1,176 +0,0 @@ -### **实现缩放动画** ->+ openharmony SDK版本:2.1.1.18 ->+ IDE版本:2.1.0.301 ->+ 实现方案: - -追加AnimatorHelp类,在AnimationManager类中调用AnimatorHelp的getPropertyAnimator方法,实现缩放动画 - -步骤一: 追加AnimatorHelp类 -```java - public final class AnimatorHelp { - - private AnimatorHelp() { - } - - private static DecimalFormat decFormat = new DecimalFormat("0.00"); - - public static PropertyValuesHolder onf(String property, float... values) { - - Keyframe[] keyframes = new Keyframe[values.length]; - for (int i = 0; i < values.length; i++) { - float pro = (float) (i + 1) / values.length; - keyframes[i] = Keyframe.ofFloat(Float.parseFloat(decFormat.format(pro)), values[i]); - } - return new PropertyValuesHolder(property, keyframes); - } - - public static AnimatorValue getPropertyAnimator(Component component, String property, Keyframe... frames) { - return getPropertyAnimator(component, new PropertyValuesHolder(property, frames)); - } - - public static AnimatorValue getPropertyAnimator(final Component component, PropertyValuesHolder... holders) { - - AnimatorValue animatorValue = new AnimatorValue(); - - animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() { - @Override - public void onUpdate(AnimatorValue animatorValue, float v) { - valueUpdate(animatorValue, v, component, holders); - } - }); - return animatorValue; - } - - public static void valueUpdate(AnimatorValue animatorValue, float v, final Component component, PropertyValuesHolder... holders) { - for (PropertyValuesHolder holder : holders) { - Keyframe[] frames = holder.getFrames(); - for (int i = 0; i < frames.length; i++) { - float value; - float value2; - float progress = i == 0 ? 0 : frames[i - 1].getProgress();//动画进度 - float incremental = i == 0 ? frames[i].getProgress() : frames[i].getProgress() - frames[i - 1].getProgress();//增量 - - if (v >= progress && v <= (frames[i].getProgress())) { - float rate = (v - progress) / incremental;//增量进度 - value = i == 0 ? 0 : frames[i - 1].getValue(); - value2 = frames[i].getValue(); - switch (holder.getProperty()) { - case "scaleX": - component.setScaleX(value + (value2 - value) * rate); - break; - case "scaleY": - component.setScaleY(value + (value2 - value) * rate); - break; - case "alpha": - component.setAlpha(value + (value2 - value) * rate); - break; - case "translationX": - component.setTranslationX(value + (value2 - value) * rate); - break; - case "translationY": - component.setTranslationY(value + (value2 - value) * rate); - break; - case "rotation": - component.setRotation(value + (value2 - value) * rate); - break; - case "pivotX": - component.setPivotX(value2); - break; - case "pivotY": - component.setPivotY(value2); - break; - case "showProcess": - case "hideProcess": - Util.InvokeProperty(component, holder.getProperty(), value2); - break; - default: - break; - - } - } - } - } - } - - public static class Keyframe { - private float progress; - private float value; - - public Keyframe(float newProgress, float newValue) { - this.progress = newProgress; - this.value = newValue; - } - - public static Keyframe ofFloat(float progress, float value) { - return new Keyframe(progress, value); - } - - /** - * @params - * @return - * @description get the progress - */ - public float getProgress() { - return this.progress; - } - - /** - * @params - * @return - * @description get the value - */ - public float getValue() { - return this.value; - } - } - - public static class PropertyValuesHolder { - private String property; - private Keyframe[] frames; - - public PropertyValuesHolder(String newProperty, Keyframe[] newFrames) { - this.property = newProperty; - this.frames = newFrames.clone(); - } - - /** - * @params - * @return - * @description get the property - */ - public String getProperty() { - return this.property; - } - - /** - * @params - * @return - * @description get the frames - */ - public Keyframe[] getFrames() { - return this.frames.clone(); - } - } - - } -``` - -步骤二: 在AnimationManager类中调用AnimatorHelp的getPropertyAnimator方法 -```java -public final class AnimationManager { - - private AnimationManager(){} - - public static Animator animate(Component component, String property, long delay, long duration, - Animator.TimelineCurve interpolator, - StateChangedListener listenerAdapter, float... values) { - AnimatorValue animator = AnimatorHelp.getPropertyAnimator(component, AnimatorHelp.onf(property, values)); - animator.setDelay(delay); - animator.setDuration(duration); - if (interpolator != null) animator.setCurve(interpolator); - if (listenerAdapter != null) animator.setStateChangedListener(listenerAdapter); - animator.start(); - return animator; - } - } - ``` \ No newline at end of file diff --git a/animation/BoomMenuButton.md b/animation/BoomMenuButton.md deleted file mode 100644 index 12af358..0000000 --- a/animation/BoomMenuButton.md +++ /dev/null @@ -1,35 +0,0 @@ -### **获取菜单的layout属性** ->+ openharmony SDK版本:2.1.1.18 ->+ IDE版本:2.1.0.301 ->+ 实现方案: -```java - private void attrsLayout(Context context, AttrSet attrSet) { - this.context = context; - - for (int i = 0; i < attrSet.getLength(); i++) { - Attr attr = attrSet.getAttr(i).get(); - String attrName = attr.getName(); - String attrValue = attr.getStringValue(); - switch (attrName) { - case BMB_CACHE_OPTIMIZATION: - if(attrValue != null && !"".equals(attrValue)){ - cacheOptimization = attr.getBoolValue(); - } - break; - case BMB_BOOM_IN_WHOLE_SCREEN: - if(attrValue != null && !"".equals(attrValue)){ - boomInWholeScreen = attr.getBoolValue(); - } - break; - ..... - break; - case BMB_BOTTOM_HAM_BUTTON_TOP_MARGIN: - if(attrValue != null && !"".equals(attrValue)){ - bottomHamButtonTopMargin = attr.getFloatValue(); - } - break; - } - } - } -``` ->+ 补充说明:在BoomMenuButton类的initAttrs方法里追加调用attrsLayout方法来获取菜单layout的属性。 \ No newline at end of file diff --git a/app/ActionBarAbility.md b/app/ActionBarAbility.md deleted file mode 100644 index 04f8a35..0000000 --- a/app/ActionBarAbility.md +++ /dev/null @@ -1,48 +0,0 @@ -### **动画页面调用方式** ->+ openharmony API: ohos.aafwk.ability.Ability ->+ openharmony SDK版本:2.1.1.18 ->+ IDE版本:2.1.0.301 ->+ 实现方案: -* 原库实现 -ActionBarActivity里面直接调用xml页面文件, -```java -public class ActionBarActivity extends AppCompatActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - View actionBar = mInflater.inflate(R.layout.custom_actionbar, null); - TextView mTitleTextView = (TextView) actionBar.findViewById(R.id.title_text); - } -} -``` - -* 替换实现 -需要通过ActionBarAbility调用ActionBarAbilitySlice再调用xml文件 -```java -public class ActionBarAbility extends Ability { - - @Override - public void onStart(Intent intent) { - super.onStart(intent); - super.setMainRoute(ActionBarAbilitySlice.class.getName()); - } -} - -public class ActionBarAbilitySlice extends AbilitySlice { - - private ToolBar toolBar; - private BoomMenuButton bmb; - - @Override - public void onStart(Intent intent) { - super.onStart(intent); - - ComponentContainer cc = initView(); - super.setUIContent(cc); - LayoutScatter mInflater = LayoutScatter.getInstance(this); - - Component actionBar = mInflater.parse(ResourceTable.Layout_custom_actionbar, null,true); - } - -} -``` -- Gitee From 74ddde900565e538b31f7f0c4a9d07a9fcfc1847 Mon Sep 17 00:00:00 2001 From: liliang Date: Fri, 23 Jul 2021 15:05:09 +0800 Subject: [PATCH 3/3] modify sequencaeable.md --- util/Sequenceable.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/util/Sequenceable.md b/util/Sequenceable.md index 317e5a5..5a5f44d 100644 --- a/util/Sequenceable.md +++ b/util/Sequenceable.md @@ -15,4 +15,15 @@ public class Rect implements Sequenceable { } ``` ->+ 补充说明:新做成的类需要序列化和反序列化,实现Sequenceable接口和Producer,实现Sequenceable接口和Producer()方法。 +>+ 补充说明: +>+ 鸿蒙的ohos.agp.utils.Rect类的反序列化失败 +>+ 安卓实现对应类:Parcel.writeParcelable Parcel.readParcelable , +>+ 鸿蒙对应的实现方法: +```java + Rect rect = new Rect(10, 20, 30, 40); + MessageParcel _data = MessageParcel.obtain(); + _data.writeTypedSequenceable(rect); + Object obj = _data.createSequenceable(); +``` +>+ 结果鸿蒙的ohos.agp.utils.Rect类的反序列化失败(报 Exception message: ohos.utils.ParcelException: fail to create sequenceable creator due to NoSuchFieldException: PRODUCER, class:ohos.agp.utils.Rect错误), +>+ 问题原因:需要实现这个类Sequenceable接口和Producer,实现Sequenceable接口和Producer()方法。 -- Gitee