You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by so...@apache.org on 2017/03/01 02:21:00 UTC

[3/7] incubator-weex git commit: * [android] Fix linear-gradient & border-radius & clipPath cannot work together if system version is 4.3 or 4.4. (#2759)

* [android] Fix linear-gradient & border-radius & clipPath cannot work together if system version is 4.3 or 4.4. (#2759)

Without this fix, the border-radius of linear-gradient div in the following page will not work.
http://dotwe.org/weex/963c9ade129f86757cecdd85651cd30e

This is mostly likely due to OpenGL ES 3.1, which provided  "Separate shader objects" is not supported until android 5.0.

Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/fc11bc58
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/fc11bc58
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/fc11bc58

Branch: refs/heads/0.11-dev
Commit: fc11bc58c4813be8f68bb696bf920e1980107bfd
Parents: 5a03143
Author: YorkShen <sh...@gmail.com>
Authored: Tue Feb 28 20:05:31 2017 +0800
Committer: sospartan zheng <so...@apache.org>
Committed: Tue Feb 28 20:05:31 2017 +0800

----------------------------------------------------------------------
 .../weex/ui/view/border/BorderDrawable.java     |  4 ++
 .../java/com/taobao/weex/utils/WXViewUtils.java | 71 ++++++++++++++++----
 2 files changed, 62 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/fc11bc58/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderDrawable.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderDrawable.java b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderDrawable.java
index 174b4f7..dd5f96d 100755
--- a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderDrawable.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderDrawable.java
@@ -455,6 +455,10 @@ public class BorderDrawable extends Drawable {
     invalidateSelf();
   }
 
+  public boolean hasImage(){
+    return mShader!=null;
+  }
+
   public boolean isRounded() {
     return mBorderRadius != null &&
            (!FloatUtil.floatsEqual(getBorderRadius(mBorderRadius, BORDER_TOP_LEFT_RADIUS), 0) ||

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/fc11bc58/android/sdk/src/main/java/com/taobao/weex/utils/WXViewUtils.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/WXViewUtils.java b/android/sdk/src/main/java/com/taobao/weex/utils/WXViewUtils.java
index 3dd5bcc..e075ee8 100755
--- a/android/sdk/src/main/java/com/taobao/weex/utils/WXViewUtils.java
+++ b/android/sdk/src/main/java/com/taobao/weex/utils/WXViewUtils.java
@@ -216,6 +216,7 @@ import android.os.Build;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 
 import com.taobao.weex.WXEnvironment;
@@ -535,22 +536,66 @@ public class WXViewUtils {
 
   public static void clipCanvasWithinBorderBox(View targetView, Canvas canvas) {
     Drawable drawable;
-    /* According to https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
-      API 18 or higher supports clipPath to canvas based on hardware acceleration.
-     */
-    /**
-     * According to https://code.google.com/p/android/issues/detail?id=225556&sort=-id&colspec=ID
-     * clipPath doesn't work with rotation nor scale when API level is 24 or higher.
-     */
-    if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 || !canvas.isHardwareAccelerated()) &&
-        Build.VERSION.SDK_INT <= Build.VERSION_CODES.M &&
+    if (clipCanvasDueToAndroidVersion(canvas) &&
+        clipCanvasIfAnimationExist() &&
         ((drawable = targetView.getBackground()) instanceof BorderDrawable)) {
       BorderDrawable borderDrawable = (BorderDrawable) drawable;
-      if(borderDrawable.isRounded()) {
-        Path path = borderDrawable.getContentPath(
-            new RectF(0, 0, targetView.getWidth(), targetView.getHeight()));
-        canvas.clipPath(path);
+      if (borderDrawable.isRounded()) {
+        if (clipCanvasIfBackgroundImageExist(targetView, borderDrawable)) {
+          Path path = borderDrawable.getContentPath(
+              new RectF(0, 0, targetView.getWidth(), targetView.getHeight()));
+          canvas.clipPath(path);
+        }
+      }
+    }
+  }
+
+  /**
+   * According to https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
+   API 18 or higher supports clipPath to canvas based on hardware acceleration.
+   * @param canvas
+   * @return
+   */
+  private static boolean clipCanvasDueToAndroidVersion(Canvas canvas) {
+    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 ||
+           !canvas.isHardwareAccelerated();
+  }
+
+  /**
+   * According to https://code.google.com/p/android/issues/detail?id=225556&sort=-id&colspec=ID
+   * clipPath doesn't work with rotation nor scale when API level is 24.
+   * As animation will not cause redraw if hardware-acceleration enabled, clipCanvas feature has
+   * to be disabled when API level is 24 without considering the animation property.
+   * As the compile version of weex_sdk is 23, so API level 24 has to be hard-code.
+   */
+  private static boolean clipCanvasIfAnimationExist() {
+    return Build.VERSION.SDK_INT != 24;
+  }
+
+  /**
+   * Due limitation in Android platform, the linear gradient in the following page will not be
+   * rounded if {@link Canvas#clipPath(Path)} of the parent view invoked when API level is lower
+   * than 21.
+   * http://dotwe.org/weex/963c9ade129f86757cecdd85651cd30e
+   * @param targetView
+   * @param borderDrawable
+   * @return
+   */
+  private static boolean clipCanvasIfBackgroundImageExist(@NonNull View targetView,
+                                                          @NonNull BorderDrawable borderDrawable) {
+    if (targetView instanceof ViewGroup) {
+      View child;
+      ViewGroup parent = ((ViewGroup) targetView);
+      int count = parent.getChildCount();
+      for (int i = 0; i < count; i++) {
+        child = parent.getChildAt(i);
+        if (child.getBackground() instanceof BorderDrawable &&
+            ((BorderDrawable) child.getBackground()).hasImage() &&
+            Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+          return false;
+        }
       }
     }
+    return true;
   }
 }