http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/TextWidget.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/TextWidget.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/TextWidget.java
index 2a69b46..fee01b9 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/TextWidget.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/TextWidget.java
@@ -24,6 +24,7 @@ import android.support.annotation.NonNull;
 import android.support.annotation.RestrictTo;
 import android.support.annotation.RestrictTo.Scope;
 import android.text.Layout;
+
 import com.taobao.weex.ui.flat.FlatGUIContext;
 
 @RestrictTo(Scope.LIBRARY)

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/Widget.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/Widget.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/Widget.java
index 761d3b0..ac9eb6f 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/Widget.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/Widget.java
@@ -26,6 +26,7 @@ import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RestrictTo;
 import android.support.annotation.RestrictTo.Scope;
+
 import com.taobao.weex.ui.view.border.BorderDrawable;
 
 @RestrictTo(Scope.LIBRARY)
@@ -43,9 +44,12 @@ public interface Widget {
 
   void setContentBox(int leftOffset, int topOffset, int rightOffset, int 
bottomOffset);
 
-  @NonNull Point getLocInFlatContainer();
+  @NonNull
+  Point getLocInFlatContainer();
 
-  @Nullable BorderDrawable getBackgroundAndBorder();
+  @Nullable
+  BorderDrawable getBackgroundAndBorder();
 
-  @NonNull Rect getBorderBox();
+  @NonNull
+  Rect getBorderBox();
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/WidgetGroup.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/WidgetGroup.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/WidgetGroup.java
index 42ca263..942a4b1 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/WidgetGroup.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/WidgetGroup.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -23,7 +23,9 @@ import android.graphics.Canvas;
 import android.support.annotation.NonNull;
 import android.support.annotation.RestrictTo;
 import android.support.annotation.RestrictTo.Scope;
+
 import com.taobao.weex.ui.flat.FlatGUIContext;
+
 import java.util.LinkedList;
 import java.util.List;
 

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/module/WXDomModule.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXDomModule.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXDomModule.java
new file mode 100644
index 0000000..38daf3f
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXDomModule.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.ui.module;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.taobao.weex.WXSDKInstance;
+import com.taobao.weex.bridge.WXBridgeManager;
+import com.taobao.weex.common.WXModule;
+import com.taobao.weex.ui.action.ActionAddRule;
+import com.taobao.weex.ui.action.ActionGetComponentRect;
+import com.taobao.weex.ui.action.ActionInvokeMethod;
+import com.taobao.weex.ui.action.GraphicActionScrollToElement;
+import com.taobao.weex.utils.WXLogUtils;
+
+/**
+ * <p>
+ * Module class for dom operation.
+ * </p>
+ * <p>
+ *   This module is work different with other regular module, method is 
invoked directly, without reflection.
+ * </p>
+ */
+public final class WXDomModule extends WXModule {
+
+  /** package **/
+  public static final String SCROLL_TO_ELEMENT = "scrollToElement";
+  public static final String ADD_RULE = "addRule";
+  public static final String GET_COMPONENT_RECT = "getComponentRect";
+  public static final String WXDOM = "dom";
+  public static final String INVOKE_METHOD = "invokeMethod";
+
+  /**
+   * Methods expose to js. Every method which will be called in js should add 
to this array.
+   */
+  public static final String[] METHODS = {SCROLL_TO_ELEMENT, ADD_RULE, 
GET_COMPONENT_RECT,
+      INVOKE_METHOD};
+
+  public WXDomModule(WXSDKInstance instance){
+    mWXSDKInstance = instance;
+  }
+
+  public void callDomMethod(JSONObject task, long... parseNanos) {
+    if (task == null) {
+      return;
+    }
+    String method = (String) task.get(WXBridgeManager.METHOD);
+    JSONArray args = (JSONArray) task.get(WXBridgeManager.ARGS);
+    callDomMethod(method,args,parseNanos);
+  }
+
+  public Object callDomMethod(String method, JSONArray args, long... 
parseNanos) {
+
+    if (method == null) {
+      return null;
+    }
+
+    try {
+      switch (method) {
+        case SCROLL_TO_ELEMENT:{
+          if (args == null) {
+            return null;
+          }
+          String ref = args.size() >= 1 ? args.getString(0) : null;
+          JSONObject options = args.size() >= 2 ? args.getJSONObject(1) : null;
+          new GraphicActionScrollToElement(mWXSDKInstance.getInstanceId(), 
ref, options)
+                  .executeActionOnRender();
+          break;
+        }
+        case ADD_RULE:{
+          if (args == null) {
+            return null;
+          }
+          new ActionAddRule(mWXSDKInstance.getInstanceId(), args.getString(0), 
args.getJSONObject(1))
+                  .executeAction();
+          break;
+        }
+        case GET_COMPONENT_RECT:{
+            if(args == null){
+                return null;
+            }
+            new ActionGetComponentRect(mWXSDKInstance.getInstanceId(), 
args.getString(0), args.getString(1))
+                    .executeActionOnRender();
+            break;
+        }
+        case INVOKE_METHOD: {
+          if(args == null){
+            return null;
+          }
+          // todo:no sure where the request com from
+          new ActionInvokeMethod(mWXSDKInstance.getInstanceId(), 
args.getString(0), args.getString(1), args.getJSONArray(2))
+                  .executeAction();
+          break;
+        }
+        default:
+          WXLogUtils.e("Unknown dom action.");
+          break;
+      }
+
+      // todo TraceableAction
+//      if (WXTracing.isAvailable() && action instanceof TraceableAction) {
+//        String ref = null;
+//        String type = null;
+//        if (args.size() > 0) {
+//          if (args.size() >= 1) {
+//            if (args.get(0) instanceof String) {
+//              ref = args.getString(0);
+//            } else if (args.get(0) instanceof JSONObject) {
+//              ref = ((JSONObject) args.get(0)).getString("ref");
+//              type = ((JSONObject) args.get(0)).getString("type");
+//            }
+//          }
+//
+//          if (args.size() >= 2) {
+//            if (args.get(1) instanceof JSONObject) {
+//              ref = ((JSONObject) args.get(1)).getString("ref");
+//              type = ((JSONObject) args.get(1)).getString("type");
+//            }
+//          }
+//        }
+//        if (parseNanos != null && parseNanos.length == 1) {
+//          ((TraceableAction) action).mParseJsonNanos = parseNanos[0];
+//          ((TraceableAction) action).mStartMillis -= 
Stopwatch.nanosToMillis(parseNanos[0]);
+//        }
+//        ((TraceableAction) 
action).onStartDomExecute(mWXSDKInstance.getInstanceId(), method, ref, type, 
args.toJSONString());
+//      }
+    } catch (IndexOutOfBoundsException e) {
+      // no enougn args
+      e.printStackTrace();
+      WXLogUtils.e("Dom module call miss arguments.");
+    } catch (ClassCastException cce) {
+      WXLogUtils.e("Dom module call arguments format error!!");
+    }
+    return null;
+  }
+
+  public void invokeMethod(String ref, String method, JSONArray args){
+    if(ref == null || method == null){
+      return;
+    }
+
+    new ActionInvokeMethod(mWXSDKInstance.getInstanceId(), ref, method, args)
+            .executeAction();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/module/WXMetaModule.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXMetaModule.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXMetaModule.java
index b3c5034..93a01c7 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXMetaModule.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXMetaModule.java
@@ -37,7 +37,6 @@ import com.taobao.weex.utils.WXUtils;
 import com.taobao.weex.utils.WXViewUtils;
 
 import java.net.URLDecoder;
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -58,24 +57,25 @@ public class WXMetaModule extends WXModule {
                 param = URLDecoder.decode(param, "utf-8");
                 JSONObject jsObj = JSON.parseObject(param);
                 Context cxt = mWXSDKInstance.getContext();
+                // todo maybe getString(WIDTH) is "device-height"
                 if (DEVICE_WIDTH.endsWith(jsObj.getString(WIDTH))) {
                     int width = 
(int)(WXViewUtils.getScreenWidth(cxt)/WXViewUtils.getScreenDensity(cxt));
-                    mWXSDKInstance.setViewPortWidth(width);
                     mWXSDKInstance.setInstanceViewPortWidth(width);
+                    WXLogUtils.d("[WXMetaModule] setViewport 
success[device-width]=" + width);
                 } else {
                     int width = jsObj.getInteger(WIDTH);
                     if (width > 0) {
-                        mWXSDKInstance.setViewPortWidth(width);
+                        // todo 问题:js -> java -> 
native,应该在native就拦截下请求,并修改ViewPortWidth
                         mWXSDKInstance.setInstanceViewPortWidth(width);
                     }
+                    WXLogUtils.d("[WXMetaModule] setViewport success[width]=" 
+ width);
                 }
             } catch (Exception e) {
-                WXLogUtils.e("[WXModalUIModule] alert param parse error ", e);
+                WXLogUtils.e("[WXMetaModule] alert param parse error ", e);
             }
         }
     }
 
-
     @JSMethod(uiThread = true)
     public void openLog(String open) {
         Application application = WXEnvironment.getApplication();

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java
index 2a29a29..de5a135 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java
@@ -41,14 +41,13 @@ import com.taobao.weex.bridge.WXHashMap;
 import com.taobao.weex.bridge.WXJSObject;
 import com.taobao.weex.common.Destroyable;
 import com.taobao.weex.common.WXModule;
-import com.taobao.weex.common.WXPerformance;
-import com.taobao.weex.dom.action.Actions;
 import com.taobao.weex.utils.WXJsonUtils;
 import com.taobao.weex.utils.WXLogUtils;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.HashMap;
+import com.taobao.weex.utils.WXUtils;
 
 public class WXTimerModule extends WXModule implements Destroyable, 
Handler.Callback {
 
@@ -69,20 +68,30 @@ public class WXTimerModule extends WXModule implements 
Destroyable, Handler.Call
   @JSMethod(uiThread = false)
   public void setTimeout(@IntRange(from = 1) int funcId, @FloatRange(from = 0) 
float delay) {
     if(mWXSDKInstance != null) {
-      postOrHoldMessage(MODULE_TIMEOUT, funcId, (int) delay, 
Integer.parseInt(mWXSDKInstance.getInstanceId()));
-      if (null != mWXSDKInstance.getWXPerformance()){
-        mWXSDKInstance.getWXPerformance().timerInvokeCount++;
-      }
+      postOrHoldMessage(MODULE_TIMEOUT, funcId, (int) delay, 
WXUtils.parseInt(mWXSDKInstance.getInstanceId()));
+      WXSDKManager.getInstance().postOnUiThread(new Runnable() {
+        @Override
+        public void run() {
+          if (null != mWXSDKInstance){
+            mWXSDKInstance.getWXPerformance().timerInvokeCount++;
+          }
+        }
+      },0);
     }
   }
 
   @JSMethod(uiThread = false)
   public void setInterval(@IntRange(from = 1) int funcId, @FloatRange(from = 
0) float interval) {
     if(mWXSDKInstance != null) {
-      postOrHoldMessage(MODULE_INTERVAL, funcId, (int) interval, 
Integer.parseInt(mWXSDKInstance.getInstanceId()));
-      if (null != mWXSDKInstance.getWXPerformance()){
-        mWXSDKInstance.getWXPerformance().timerInvokeCount++;
-      }
+      postOrHoldMessage(MODULE_INTERVAL, funcId, (int) interval, 
WXUtils.parseInt(mWXSDKInstance.getInstanceId()));
+      WXSDKManager.getInstance().postOnUiThread(new Runnable() {
+        @Override
+        public void run() {
+          if (null != mWXSDKInstance){
+            mWXSDKInstance.getWXPerformance().timerInvokeCount++;
+          }
+        }
+      },0);
     }
   }
 
@@ -120,7 +129,7 @@ public class WXTimerModule extends WXModule implements 
Destroyable, Handler.Call
     if (msg != null) {
       int what = msg.what;
       if(WXEnvironment.isApkDebugable()) {
-          WXLogUtils.d(TAG, "Timer Module handleMessage : " + msg.what);
+        WXLogUtils.d(TAG, "Timer Module handleMessage : " + msg.what);
       }
       switch (what) {
         case MODULE_TIMEOUT:
@@ -162,19 +171,14 @@ public class WXTimerModule extends WXModule implements 
Destroyable, Handler.Call
     task.put(KEY_ARGS, argsList);
     Object[] tasks = {task};
     return new WXJSObject[]{
-        new WXJSObject(WXJSObject.String, String.valueOf(instanceId)),
-        new WXJSObject(WXJSObject.JSON,
-                       WXJsonUtils.fromObjectToJSONString(tasks))};
+            new WXJSObject(WXJSObject.String, String.valueOf(instanceId)),
+            new WXJSObject(WXJSObject.JSON,
+                    WXJsonUtils.fromObjectToJSONString(tasks))};
   }
 
   private void postOrHoldMessage(@MessageType final int what,final int 
funcId,final int interval,final int instanceId) {
     if(mWXSDKInstance.isPreRenderMode()) {
-      
WXSDKManager.getInstance().getWXDomManager().postAction(mWXSDKInstance.getInstanceId(),
 Actions.getExecutableRenderAction(new Runnable() {
-        @Override
-        public void run() {
-          postMessage(what,funcId,interval,instanceId);
-        }
-      }),false);
+      postMessage(what,funcId,interval,instanceId);
     } else {
       postMessage(what,funcId,interval,instanceId);
     }
@@ -182,20 +186,15 @@ public class WXTimerModule extends WXModule implements 
Destroyable, Handler.Call
 
   private void removeOrHoldMessage(@MessageType final int what,final int 
funcId) {
     if(mWXSDKInstance.isPreRenderMode()) {
-      
WXSDKManager.getInstance().getWXDomManager().postAction(mWXSDKInstance.getInstanceId(),
 Actions.getExecutableRenderAction(new Runnable() {
-        @Override
-        public void run() {
-          handler.removeMessages(what, antiIntAutoBoxing.get(funcId, funcId));
-        }
-      }),false);
+      handler.removeMessages(what, antiIntAutoBoxing.get(funcId, funcId));
     } else {
       handler.removeMessages(what, antiIntAutoBoxing.get(funcId, funcId));
     }
   }
 
   private void postMessage(@MessageType int what,
-      @IntRange(from = 1) int funcId,
-      @IntRange(from = 0) int interval, int instanceId) {
+                           @IntRange(from = 1) int funcId,
+                           @IntRange(from = 0) int interval, int instanceId) {
     if (interval < 0 || funcId <= 0) {
       WXLogUtils.e(TAG, "interval < 0 or funcId <=0");
     } else {
@@ -203,7 +202,7 @@ public class WXTimerModule extends WXModule implements 
Destroyable, Handler.Call
         antiIntAutoBoxing.put(funcId, funcId);
       }
       Message message = handler
-          .obtainMessage(what, instanceId, interval, 
antiIntAutoBoxing.get(funcId));
+              .obtainMessage(what, instanceId, interval, 
antiIntAutoBoxing.get(funcId));
       handler.sendMessageDelayed(message, interval);
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/IWebView.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/view/IWebView.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/IWebView.java
index e38c3ca..b3bc8e7 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/view/IWebView.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/IWebView.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  *   http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/WXCircleViewPager.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXCircleViewPager.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXCircleViewPager.java
index 0cb5f4e..616c16d 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXCircleViewPager.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXCircleViewPager.java
@@ -112,11 +112,11 @@ public class WXCircleViewPager extends ViewPager 
implements WXGestureObservable
       Field scroller = ViewPager.class.getDeclaredField("mScroller");
       scroller.setAccessible(true);
       Field interpolator = ViewPager.class
-          .getDeclaredField("sInterpolator");
+              .getDeclaredField("sInterpolator");
       interpolator.setAccessible(true);
 
       mScroller = new WXSmoothScroller(getContext(),
-          (Interpolator) interpolator.get(null));
+              (Interpolator) interpolator.get(null));
       scroller.set(this, mScroller);
     } catch (Exception e) {
       WXLogUtils.e("[CircleViewPager] postInitViewPager: ", e);

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/WXImageView.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXImageView.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXImageView.java
index d8670c1..bd2d418 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXImageView.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXImageView.java
@@ -40,8 +40,8 @@ import java.lang.ref.WeakReference;
 import java.util.Arrays;
 
 public class WXImageView extends ImageView implements WXGestureObservable,
-                                                      IRenderStatus<WXImage>,
-                                                      IRenderResult<WXImage>, 
WXImage.Measurable {
+        IRenderStatus<WXImage>,
+        IRenderResult<WXImage>, WXImage.Measurable {
 
   private WeakReference<WXImage> mWeakReference;
   private WXGesture wxGesture;
@@ -66,10 +66,10 @@ public class WXImageView extends ImageView implements 
WXGestureObservable,
     ViewGroup.LayoutParams layoutParams;
     if ((layoutParams = getLayoutParams()) != null) {
       Drawable wrapDrawable = ImageDrawable.createImageDrawable(drawable,
-                                                                
getScaleType(), borderRadius,
-                                                                
layoutParams.width - getPaddingLeft() - getPaddingRight(),
-                                                                
layoutParams.height - getPaddingTop() - getPaddingBottom(),
-                                                                isGif);
+              getScaleType(), borderRadius,
+              layoutParams.width - getPaddingLeft() - getPaddingRight(),
+              layoutParams.height - getPaddingTop() - getPaddingBottom(),
+              isGif);
       if (wrapDrawable instanceof ImageDrawable) {
         ImageDrawable imageDrawable = (ImageDrawable) wrapDrawable;
         if (!Arrays.equals(imageDrawable.getCornerRadii(), borderRadius)) {
@@ -186,13 +186,13 @@ public class WXImageView extends ImageView implements 
WXGestureObservable,
     super.onWindowVisibilityChanged(visibility);
     if(mOutWindowVisibilityChangedReally){
       if(visibility == View.VISIBLE){
-         autoRecoverImage();
+        autoRecoverImage();
       }else{
-         autoReleaseImage();
+        autoReleaseImage();
       }
     }
   }
-  
+
 
   @Override
   protected void onAttachedToWindow() {
@@ -224,19 +224,19 @@ public class WXImageView extends ImageView implements 
WXGestureObservable,
 
 
   public void setEnableBitmapAutoManage(boolean enableBitmapAutoManage) {
-     this.enableBitmapAutoManage = enableBitmapAutoManage;
+    this.enableBitmapAutoManage = enableBitmapAutoManage;
   }
 
   public void autoReleaseImage(){
-      if(enableBitmapAutoManage) {
-        if (!isBitmapReleased) {
-          isBitmapReleased = true;
-          WXImage image = getComponent();
-          if (image != null) {
-            image.autoReleaseImage();
-          }
+    if(enableBitmapAutoManage) {
+      if (!isBitmapReleased) {
+        isBitmapReleased = true;
+        WXImage image = getComponent();
+        if (image != null) {
+          image.autoReleaseImage();
         }
       }
+    }
   }
 
   public void autoRecoverImage(){

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/WXScrollView.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXScrollView.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXScrollView.java
index 104ed26..5bb0977 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXScrollView.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXScrollView.java
@@ -52,7 +52,7 @@ import java.util.Map.Entry;
  * Custom-defined scrollView
  */
 public class WXScrollView extends ScrollView implements Callback, IWXScroller,
-                                                        
WXGestureObservable,NestedScrollingChild {
+        WXGestureObservable,NestedScrollingChild {
 
   private NestedScrollingChildHelper childHelper;
   private float ox;
@@ -147,8 +147,8 @@ public class WXScrollView extends ScrollView implements 
Callback, IWXScroller,
 
       if (mRedirectTouchToStickyView) {
         mRedirectTouchToStickyView = ev.getY() <= 
mCurrentStickyView.getHeight()
-                                     && ev.getX() >= 
mCurrentStickyView.getLeft()
-                                     && ev.getX() <= 
mCurrentStickyView.getRight();
+                && ev.getX() >= mCurrentStickyView.getLeft()
+                && ev.getX() <= mCurrentStickyView.getRight();
       }
     }
 
@@ -176,7 +176,7 @@ public class WXScrollView extends ScrollView implements 
Callback, IWXScroller,
       int realOffset = (mStickyOffset <= 0 ? mStickyOffset : 0);
       canvas.translate(mStickyP[0], getScrollY() + realOffset);
       canvas.clipRect(0, realOffset, mCurrentStickyView.getWidth(),
-                      mCurrentStickyView.getHeight());
+              mCurrentStickyView.getHeight());
       mCurrentStickyView.draw(canvas);
       canvas.restore();
     }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/WXSwitchView.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXSwitchView.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXSwitchView.java
index 9568b23..fc96a7d 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXSwitchView.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXSwitchView.java
@@ -19,32 +19,21 @@
 package com.taobao.weex.ui.view;
 
 import android.content.Context;
-import android.content.res.ColorStateList;
-import android.graphics.Color;
 import android.support.v7.widget.SwitchCompat;
 import android.view.Gravity;
 import android.view.MotionEvent;
 
 import com.taobao.weex.ui.view.gesture.WXGesture;
 import com.taobao.weex.ui.view.gesture.WXGestureObservable;
-import com.taobao.weex.utils.WXResourceUtils;
 
 public class WXSwitchView extends SwitchCompat implements WXGestureObservable {
 
-  static final String TRACK_TINT_COLOR_NORMAL = "#b9b8b8";
-  static final String TRACK_TINT_COLOR_ACTIVATED = "#fb97bd";
-  static final String TRACK_TINT_COLOR_DISABLED = "#42b9b8b8";
-  static final String THUMB_TINT_COLOR_NORMAL = "#f1f1f1";
-  static final String THUMB_TINT_COLOR_ACTIVATED = "#fc4482";
-  static final String THUMB_TINT_COLOR_DISABLED = "#42f1f1f1";
-
   private WXGesture wxGesture;
 
   public WXSwitchView(Context context) {
     super(context);
     setShowText(false);
     setGravity(Gravity.CENTER_VERTICAL);
-    setBackgroundColor(Color.TRANSPARENT);
   }
 
   @Override
@@ -60,28 +49,4 @@ public class WXSwitchView extends SwitchCompat implements 
WXGestureObservable {
     }
     return result;
   }
-
-  public void setThumbColor(String thumbTintColorNormal, String 
thumbTintColorActivated) {
-    setThumbTintList(new ColorStateList(new int[][]{
-        new int[]{-android.R.attr.state_enabled},
-        new int[]{-android.R.attr.state_checked},
-        new int[]{android.R.attr.state_checked}
-    }, new int[]{
-        WXResourceUtils.getColor(THUMB_TINT_COLOR_DISABLED, 
Color.parseColor(THUMB_TINT_COLOR_DISABLED)),
-        WXResourceUtils.getColor(thumbTintColorNormal, 
Color.parseColor(THUMB_TINT_COLOR_NORMAL)),
-        WXResourceUtils.getColor(thumbTintColorActivated, 
Color.parseColor(THUMB_TINT_COLOR_ACTIVATED))
-    }));
-  }
-
-  public void setTrackColor(String trackTintColorNormal, String 
trackTintColorActivated) {
-    setTrackTintList(new ColorStateList(new int[][]{
-        new int[]{-android.R.attr.state_enabled},
-        new int[]{-android.R.attr.state_checked},
-        new int[]{android.R.attr.state_checked}
-    }, new int[]{
-        WXResourceUtils.getColor(TRACK_TINT_COLOR_DISABLED, 
Color.parseColor(TRACK_TINT_COLOR_DISABLED)),
-        WXResourceUtils.getColor(trackTintColorNormal, 
Color.parseColor(TRACK_TINT_COLOR_NORMAL)),
-        WXResourceUtils.getColor(trackTintColorActivated, 
Color.parseColor(TRACK_TINT_COLOR_ACTIVATED))
-    }));
-  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/WXTextView.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXTextView.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXTextView.java
index e4a9808..f37670f 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXTextView.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXTextView.java
@@ -40,7 +40,7 @@ import java.lang.ref.WeakReference;
  * TextView wrapper
  */
 public class WXTextView extends View implements WXGestureObservable, 
IWXTextView,
-                                                IRenderStatus<WXText>, 
IRenderResult<WXText> {
+        IRenderStatus<WXText>, IRenderResult<WXText> {
 
   private WeakReference<WXText> mWeakReference;
   private WXGesture wxGesture;
@@ -120,7 +120,7 @@ public class WXTextView extends View implements 
WXGestureObservable, IWXTextView
   @Nullable
   @Override
   public WXText getComponent() {
-     return null != mWeakReference ? mWeakReference.get() : null;
+    return null != mWeakReference ? mWeakReference.get() : null;
   }
 
   public void enableCopy(boolean enable) {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/WXVideoView.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXVideoView.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXVideoView.java
index f679c38..75b4f16 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXVideoView.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXVideoView.java
@@ -122,8 +122,8 @@ public class WXVideoView extends VideoView implements 
WXGestureObservable {
       setBackgroundColor(WXResourceUtils.getColor("#ee000000"));
       mProgressBar = new ProgressBar(context);
       FrameLayout.LayoutParams pLayoutParams =
-          new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
-              FrameLayout.LayoutParams.WRAP_CONTENT);
+              new 
FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
+                      FrameLayout.LayoutParams.WRAP_CONTENT);
       mProgressBar.setLayoutParams(pLayoutParams);
       pLayoutParams.gravity = Gravity.CENTER;
       addView(mProgressBar);
@@ -228,8 +228,8 @@ public class WXVideoView extends VideoView implements 
WXGestureObservable {
       Context context = getContext();
       WXVideoView video = new WXVideoView(context);
       FrameLayout.LayoutParams videoLayoutParams =
-          new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
-              FrameLayout.LayoutParams.MATCH_PARENT);
+              new 
FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
+                      FrameLayout.LayoutParams.MATCH_PARENT);
       videoLayoutParams.gravity = Gravity.CENTER;
       video.setLayoutParams(videoLayoutParams);
       addView(video, 0);//first child

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderCorner.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderCorner.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderCorner.java
index 07ff38f..918d2f0 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderCorner.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderCorner.java
@@ -18,28 +18,148 @@
  */
 package com.taobao.weex.ui.view.border;
 
+import android.graphics.Canvas;
+import android.graphics.Paint;
 import android.graphics.PointF;
 import android.graphics.RectF;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
 import android.support.annotation.NonNull;
-
-import com.taobao.weex.dom.flex.FloatUtil;
+import com.taobao.weex.base.FloatUtil;
 
 abstract class BorderCorner {
 
   final static float SWEEP_ANGLE = 45;
-  private final float mCornerRadius;
-  private final float mPreBorderWidth;
-  private final float mPostBorderWidth;
-  private final RectF mBorderBox;
-  protected final float mAngleBisector;
+  private float mCornerRadius = 0.0f;
+  private float mPreBorderWidth = 0.0f;
+  private float mPostBorderWidth = 0.0f;
+  private RectF mBorderBox;
+  protected float mAngleBisector;
+
+  /**
+   * Tell whether this corner has a rounded inner corner.
+   * If a corner has a rounded inner corner, it has an outer corner as well.
+   */
+  private boolean hasInnerCorner = false;
+
+  /**
+   * Tell whether this corner has a rounded outer corner.
+   */
+  private boolean hasOuterCorner = false;
+
+  private float mOvalLeft, mOvalTop, mOvalRight, mOvalBottom;
+
+  private float mRoundCornerStartX, mRoundCornerStartY;
+  private float mRoundCornerEndX, mRoundCornerEndY;
+
+  BorderCorner() {
+  }
+
+  final void set(float cornerRadius, float preBorderWidth, float 
postBorderWidth,
+                 @NonNull RectF borderBox, float angleBisector) {
+    boolean dirty = !FloatUtil.floatsEqual(mCornerRadius, cornerRadius)
+        || !FloatUtil.floatsEqual(mPreBorderWidth, preBorderWidth)
+        || !FloatUtil.floatsEqual(mPostBorderWidth, postBorderWidth)
+        || !FloatUtil.floatsEqual(mAngleBisector, angleBisector)
+        || (null != mBorderBox && mBorderBox.equals(borderBox));
+
+    if (dirty) {
+      mCornerRadius = cornerRadius;
+      mPreBorderWidth = preBorderWidth;
+      mPostBorderWidth = postBorderWidth;
+      mBorderBox = borderBox;
+      mAngleBisector = angleBisector;
+
+      hasOuterCorner = mCornerRadius > 0 && !FloatUtil.floatsEqual(0, 
mCornerRadius);
+
+      hasInnerCorner = (hasOuterCorner
+          && (getPreBorderWidth() >= 0)
+          && (getPostBorderWidth() >= 0)
+          && (getOuterCornerRadius() > getPreBorderWidth())
+          && (getOuterCornerRadius() > getPostBorderWidth()));
+
+      if (hasOuterCorner) {
+        prepareOval();
+      }
+      prepareRoundCorner();
+    }
+  }
+
+  /** Build oval data */
+  abstract protected void prepareOval();
+
+  /** Build corner data */
+  abstract protected void prepareRoundCorner();
+
+  public final void drawRoundedCorner(@NonNull Canvas canvas, @NonNull Paint 
paint, float startAngle) {
+    if (this.hasOuterCorner()) {
+      /*Due to the problem of hardware-acceleration, border-radius in some 
case will not
+       be rendered if Path.addArc used instead and the following condition met.
+       1. hardware-acceleration enabled
+       2. System version is Android 4.1
+       3. Screen width is 720px.
+       http://dotwe.org/weex/421b9ad09fde51c0b49bb56b37fcf955
+      */
+      if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
+        canvas.drawArc(mOvalLeft, mOvalTop, mOvalRight, mOvalBottom, 
startAngle, BorderCorner.SWEEP_ANGLE, false,
+            paint);
+      } else {
+        canvas.drawArc(new RectF(mOvalLeft, mOvalTop, mOvalRight, 
mOvalBottom), startAngle, BorderCorner.SWEEP_ANGLE,
+            false, paint);
+      }
+    } else {
+      canvas.drawLine(getRoundCornerStartX(), getRoundCornerStartY(), 
getRoundCornerEndX(), getRoundCornerEndY(),
+          paint);
+    }
+  }
+
+
+  public final float getRoundCornerStartX() {
+    return mRoundCornerStartX;
+  }
+
+  final void setRoundCornerStartX(float roundCornerStartX) {
+    this.mRoundCornerStartX = roundCornerStartX;
+  }
+
+  public final float getRoundCornerStartY() {
+    return mRoundCornerStartY;
+  }
+
+  final void setRoundCornerStartY(float roundCornerStartY) {
+    this.mRoundCornerStartY = roundCornerStartY;
+  }
+
+  public final float getRoundCornerEndX() {
+    return mRoundCornerEndX;
+  }
 
-  BorderCorner(float cornerRadius, float preBorderWidth, float postBorderWidth,
-      @NonNull RectF borderBox, float angleBisector) {
-    mCornerRadius = cornerRadius;
-    mPreBorderWidth = preBorderWidth;
-    mPostBorderWidth = postBorderWidth;
-    mBorderBox = borderBox;
-    mAngleBisector = angleBisector;
+  final void setRoundCornerEndX(float mRoundCornerEndX) {
+    this.mRoundCornerEndX = mRoundCornerEndX;
+  }
+
+  public final float getRoundCornerEndY() {
+    return mRoundCornerEndY;
+  }
+
+  final void setRoundCornerEndY(float mRoundCornerEndY) {
+    this.mRoundCornerEndY = mRoundCornerEndY;
+  }
+
+  final void setOvalLeft(float mOvalLeft) {
+    this.mOvalLeft = mOvalLeft;
+  }
+
+  final void setOvalTop(float mOvalTop) {
+    this.mOvalTop = mOvalTop;
+  }
+
+  final void setOvalRight(float mOvalRight) {
+    this.mOvalRight = mOvalRight;
+  }
+
+  final void setOvalBottom(float mOvalBottom) {
+    this.mOvalBottom = mOvalBottom;
   }
 
   /**
@@ -48,11 +168,7 @@ abstract class BorderCorner {
    * @return true for a rounded inner corner, otherwise false.
    */
   boolean hasInnerCorner() {
-    return hasOuterCorner()
-           && (getPreBorderWidth() >= 0)
-           && (getPostBorderWidth() >= 0)
-           && (getOuterCornerRadius() > getPreBorderWidth())
-           && (getOuterCornerRadius() > getPostBorderWidth());
+    return hasInnerCorner;
   }
 
   /**
@@ -60,7 +176,7 @@ abstract class BorderCorner {
    * @return true for a rounded outer corner, otherwise false.
    */
   boolean hasOuterCorner() {
-    return getOuterCornerRadius() > 0 && !FloatUtil.floatsEqual(0, 
getOuterCornerRadius());
+    return hasOuterCorner;
   }
 
   protected final float getPreBorderWidth() {
@@ -83,55 +199,4 @@ abstract class BorderCorner {
     return mBorderBox;
   }
 
-  /**
-   * Get the staring point of the corner.
-   * @return the starting point of the corner.
-   */
-  @NonNull
-  PointF getCornerStart() {
-    PointF lineStart;
-    if (hasOuterCorner()) {
-      lineStart = getRoundCornerStart();
-    } else {
-      lineStart = getSharpCornerVertex();
-    }
-    return lineStart;
-  }
-
-  /**
-   * Get the ending point of the corner.
-   * @return the ending point of the corner.
-   */
-  @NonNull
-  PointF getCornerEnd() {
-    PointF lineEnd;
-    if (hasOuterCorner()) {
-      lineEnd = getRoundCornerEnd();
-    } else {
-      lineEnd = getSharpCornerVertex();
-    }
-    return lineEnd;
-  }
-
-  @NonNull
-  abstract protected PointF getRoundCornerStart();
-
-  @NonNull
-  abstract protected PointF getSharpCornerVertex();
-
-  @NonNull
-  abstract protected PointF getRoundCornerEnd();
-
-  @NonNull
-  abstract protected PointF getSharpCornerStart();
-
-  @NonNull
-  abstract protected PointF getSharpCornerEnd();
-
-  @NonNull
-  abstract protected RectF getOvalIfInnerCornerExist();
-
-  @NonNull
-  abstract protected RectF getOvalIfInnerCornerNotExist();
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/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 a05a964..d1ff5c2 100644
--- 
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
@@ -18,6 +18,11 @@
  */
 package com.taobao.weex.ui.view.border;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
@@ -33,18 +38,18 @@ import android.os.Build;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
-import android.util.SparseArray;
 import android.util.SparseIntArray;
-
-import com.taobao.weex.dom.flex.FloatUtil;
-import com.taobao.weex.dom.flex.Spacing;
+import com.taobao.weex.dom.CSSShorthand;
+import com.taobao.weex.dom.CSSShorthand.CORNER;
+import com.taobao.weex.dom.CSSShorthand.EDGE;
 import com.taobao.weex.utils.WXLogUtils;
 import com.taobao.weex.utils.WXViewUtils;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
+import static com.taobao.weex.dom.CSSShorthand.CORNER.ALL;
+import static com.taobao.weex.dom.CSSShorthand.CORNER.BORDER_BOTTOM_LEFT;
+import static com.taobao.weex.dom.CSSShorthand.CORNER.BORDER_BOTTOM_RIGHT;
+import static com.taobao.weex.dom.CSSShorthand.CORNER.BORDER_TOP_LEFT;
+import static com.taobao.weex.dom.CSSShorthand.CORNER.BORDER_TOP_RIGHT;
 
 /**
  * A subclass of
@@ -62,23 +67,23 @@ public class BorderDrawable extends Drawable {
   public static final int BORDER_TOP_RIGHT_RADIUS = 1;
   public static final int BORDER_BOTTOM_RIGHT_RADIUS = 2;
   public static final int BORDER_BOTTOM_LEFT_RADIUS = 3;
-  public static final int BORDER_RADIUS_ALL = 8;
+  public static final int BORDER_RADIUS_ALL = 5;
   static final int DEFAULT_BORDER_COLOR = Color.BLACK;
   static final float DEFAULT_BORDER_WIDTH = 0;
-  private static final float DEFAULT_BORDER_RADIUS = 0;
   private static final BorderStyle DEFAULT_BORDER_STYLE = BorderStyle.SOLID;
   private static final String TAG = "Border";
   private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+  private static BorderStyle[] sBorderStyle = BorderStyle.values();
 
   private
   @Nullable
-  SparseArray<Float> mBorderWidth;
+  CSSShorthand<EDGE> mBorderWidth;
   private
   @Nullable
-  SparseArray<Float> mBorderRadius;
+  CSSShorthand<CORNER> mBorderRadius;
   private
   @Nullable
-  SparseArray<Float> mOverlappingBorderRadius;
+  CSSShorthand<CORNER> mOverlappingBorderRadius;
   private
   @Nullable
   SparseIntArray mBorderColor;
@@ -94,9 +99,18 @@ public class BorderDrawable extends Drawable {
   /**
    * set background-image linear-gradient
    */
-  private Shader mShader=null;
+  private Shader mShader = null;
   private int mAlpha = 255;
 
+  private TopLeftCorner mTopLeftCorner;
+  private TopRightCorner mTopRightCorner;
+  private BottomRightCorner mBottomRightCorner;
+  private BottomLeftCorner mBottomLeftCorner;
+
+  private final BorderEdge mBorderEdge = new BorderEdge();
+
+  private RectF mRectBounds;
+
   public BorderDrawable() {
   }
 
@@ -156,8 +170,8 @@ public class BorderDrawable extends Drawable {
 
   @Override
   public int getOpacity() {
-    return mShader!=null?PixelFormat.OPAQUE:
-          
WXViewUtils.getOpacityFromColor(WXViewUtils.multiplyColorAlpha(mColor, mAlpha));
+    return mShader != null ? PixelFormat.OPAQUE :
+            
WXViewUtils.getOpacityFromColor(WXViewUtils.multiplyColorAlpha(mColor, mAlpha));
   }
 
   /* Android's elevation implementation requires this to be implemented to 
know where to draw the
@@ -173,78 +187,101 @@ public class BorderDrawable extends Drawable {
     }
   }
 
-  public void setBorderWidth(@BorderWidthStyleColorType int position, float 
width) {
+  public void setBorderWidth(CSSShorthand.EDGE edge, float width) {
     if (mBorderWidth == null) {
-      mBorderWidth = new SparseArray<>(5);
-      mBorderWidth.put(Spacing.ALL, DEFAULT_BORDER_WIDTH);
+      mBorderWidth = new CSSShorthand<>();
     }
-    if (!FloatUtil.floatsEqual(getBorderWidth(position), width)) {
-      BorderUtil.updateSparseArray(mBorderWidth, position, width);
-      mBorderWidth.put(position, width);
+    if (mBorderWidth.get(edge) != width) {
+      mBorderWidth.set(edge, width);
       mNeedUpdatePath = true;
       invalidateSelf();
     }
   }
 
-  float getBorderWidth(@BorderWidthStyleColorType int position) {
-    return BorderUtil.fetchFromSparseArray(mBorderWidth, position, 
DEFAULT_BORDER_WIDTH);
+  float getBorderWidth(CSSShorthand.EDGE edge) {
+    return mBorderWidth.get(edge);
   }
 
-  public void setBorderRadius(@BorderRadiusType int position, float radius) {
+  public void setBorderRadius(CORNER position, float radius) {
     if (mBorderRadius == null) {
-      mBorderRadius = new SparseArray<>(5);
-      mBorderRadius.put(Spacing.ALL, DEFAULT_BORDER_RADIUS);
+      mBorderRadius = new CSSShorthand<>();
     }
-    if (!FloatUtil.floatsEqual(getBorderRadius(mBorderRadius, position), 
radius)) {
-      BorderUtil.updateSparseArray(mBorderRadius, position, radius, true);
+    if (mBorderRadius.get(position) != radius ||
+        (position == ALL &&
+            (radius != mBorderRadius.get(BORDER_TOP_LEFT) ||
+            radius != mBorderRadius.get(BORDER_TOP_RIGHT) ||
+            radius != mBorderRadius.get(BORDER_BOTTOM_RIGHT) ||
+            radius != mBorderRadius.get(BORDER_BOTTOM_LEFT)))) {
+      mBorderRadius.set(position, radius);
       mNeedUpdatePath = true;
       invalidateSelf();
     }
   }
 
-  @VisibleForTesting
-  float getBorderRadius(@BorderRadiusType int position) {
-    return getBorderRadius(mOverlappingBorderRadius, position);
+  public
+  @NonNull
+  float[] getBorderRadius(RectF borderBox) {
+    prepareBorderRadius(borderBox);
+    if (mOverlappingBorderRadius == null) {
+      mOverlappingBorderRadius = new CSSShorthand<>();
+    }
+    float topLeftRadius = mOverlappingBorderRadius.get(BORDER_TOP_LEFT);
+    float topRightRadius = mOverlappingBorderRadius.get(BORDER_TOP_RIGHT);
+    float bottomRightRadius = 
mOverlappingBorderRadius.get(BORDER_BOTTOM_RIGHT);
+    float bottomLeftRadius = mOverlappingBorderRadius.get(BORDER_BOTTOM_LEFT);
+    return new float[]{topLeftRadius, topLeftRadius,
+            topRightRadius, topRightRadius,
+            bottomRightRadius, bottomRightRadius,
+            bottomLeftRadius, bottomLeftRadius};
   }
 
   public
   @NonNull
-  float[] getBorderRadius(RectF borderBox) {
+  float[] getBorderInnerRadius(RectF borderBox) {
     prepareBorderRadius(borderBox);
-    float topLeftRadius = getBorderRadius(mOverlappingBorderRadius, 
BORDER_TOP_LEFT_RADIUS);
-    float topRightRadius = getBorderRadius(mOverlappingBorderRadius, 
BORDER_TOP_RIGHT_RADIUS);
-    float bottomRightRadius = getBorderRadius(mOverlappingBorderRadius, 
BORDER_BOTTOM_RIGHT_RADIUS);
-    float bottomLeftRadius = getBorderRadius(mOverlappingBorderRadius, 
BORDER_BOTTOM_LEFT_RADIUS);
-    return new float[]{topLeftRadius,topLeftRadius,
-        topRightRadius,topRightRadius,
+    if (mOverlappingBorderRadius == null) {
+      mOverlappingBorderRadius = new CSSShorthand<>();
+    }
+    float topLeftRadius = mOverlappingBorderRadius.get(BORDER_TOP_LEFT);
+    float topRightRadius = mOverlappingBorderRadius.get(BORDER_TOP_RIGHT);
+    float bottomRightRadius = 
mOverlappingBorderRadius.get(BORDER_BOTTOM_RIGHT);
+    float bottomLeftRadius = mOverlappingBorderRadius.get(BORDER_BOTTOM_LEFT);
+    if (null != mBorderWidth) {
+      topLeftRadius = Math.max(topLeftRadius - mBorderWidth.get(EDGE.TOP), 0);
+      topRightRadius = Math.max(topRightRadius - mBorderWidth.get(EDGE.TOP), 
0);
+      bottomRightRadius = Math.max(bottomRightRadius - 
mBorderWidth.get(EDGE.BOTTOM), 0);
+      bottomLeftRadius = Math.max(bottomLeftRadius - 
mBorderWidth.get(EDGE.BOTTOM), 0);
+    }
+    return new float[] {topLeftRadius, topLeftRadius,
+        topRightRadius, topRightRadius,
         bottomRightRadius, bottomRightRadius,
-        bottomLeftRadius,bottomLeftRadius};
+        bottomLeftRadius, bottomLeftRadius};
   }
 
-  public void setBorderColor(@BorderWidthStyleColorType int position, int 
color) {
+  public void setBorderColor(CSSShorthand.EDGE edge, int color) {
     if (mBorderColor == null) {
       mBorderColor = new SparseIntArray(5);
-      mBorderColor.put(Spacing.ALL, DEFAULT_BORDER_COLOR);
+      mBorderColor.put(CSSShorthand.EDGE.ALL.ordinal(), DEFAULT_BORDER_COLOR);
     }
-    if (getBorderColor(position) != color) {
-      BorderUtil.updateSparseArray(mBorderColor, position, color);
+    if (getBorderColor(edge) != color) {
+      BorderUtil.updateSparseArray(mBorderColor, edge.ordinal(), color);
       invalidateSelf();
     }
   }
 
-  int getBorderColor(@BorderWidthStyleColorType int position) {
-    return BorderUtil.fetchFromSparseArray(mBorderColor, position, 
DEFAULT_BORDER_COLOR);
+  int getBorderColor(CSSShorthand.EDGE edge) {
+    return BorderUtil.fetchFromSparseArray(mBorderColor, edge.ordinal(), 
DEFAULT_BORDER_COLOR);
   }
 
-  public void setBorderStyle(@BorderWidthStyleColorType int position, @NonNull 
String style) {
+  public void setBorderStyle(CSSShorthand.EDGE edge, @NonNull String style) {
     if (mBorderStyle == null) {
       mBorderStyle = new SparseIntArray(5);
-      mBorderStyle.put(Spacing.ALL, DEFAULT_BORDER_STYLE.ordinal());
+      mBorderStyle.put(CSSShorthand.EDGE.ALL.ordinal(), 
DEFAULT_BORDER_STYLE.ordinal());
     }
     try {
       int borderStyle = 
BorderStyle.valueOf(style.toUpperCase(Locale.US)).ordinal();
-      if (getBorderStyle(position) != borderStyle) {
-        BorderUtil.updateSparseArray(mBorderStyle, position, borderStyle);
+      if (getBorderStyle(edge) != borderStyle) {
+        BorderUtil.updateSparseArray(mBorderStyle, edge.ordinal(), 
borderStyle);
         invalidateSelf();
       }
     } catch (IllegalArgumentException e) {
@@ -252,8 +289,8 @@ public class BorderDrawable extends Drawable {
     }
   }
 
-  int getBorderStyle(@BorderWidthStyleColorType int position) {
-    return BorderUtil.fetchFromSparseArray(mBorderStyle, position, 
BorderStyle.SOLID.ordinal());
+  int getBorderStyle(CSSShorthand.EDGE edge) {
+    return BorderUtil.fetchFromSparseArray(mBorderStyle, edge.ordinal(), 
BorderStyle.SOLID.ordinal());
   }
 
   public int getColor() {
@@ -270,16 +307,16 @@ public class BorderDrawable extends Drawable {
     invalidateSelf();
   }
 
-  public boolean hasImage(){
-    return mShader!=null;
+  public boolean hasImage() {
+    return mShader != null;
   }
 
   public boolean isRounded() {
     return mBorderRadius != null &&
-           (!FloatUtil.floatsEqual(getBorderRadius(mBorderRadius, 
BORDER_TOP_LEFT_RADIUS), 0) ||
-            !FloatUtil.floatsEqual(getBorderRadius(mBorderRadius, 
BORDER_TOP_RIGHT_RADIUS), 0) ||
-            !FloatUtil.floatsEqual(getBorderRadius(mBorderRadius, 
BORDER_BOTTOM_RIGHT_RADIUS), 0) ||
-            !FloatUtil.floatsEqual(getBorderRadius(mBorderRadius, 
BORDER_BOTTOM_LEFT_RADIUS), 0));
+            (mBorderRadius.get(BORDER_TOP_LEFT) != 0 ||
+                mBorderRadius.get(BORDER_TOP_RIGHT) != 0 ||
+                mBorderRadius.get(BORDER_BOTTOM_RIGHT) != 0 ||
+                mBorderRadius.get(BORDER_BOTTOM_LEFT) != 0);
   }
 
   public
@@ -290,10 +327,6 @@ public class BorderDrawable extends Drawable {
     return contentClip;
   }
 
-  private float getBorderRadius(@Nullable SparseArray<Float> borderRadius, 
@BorderRadiusType int position) {
-    return BorderUtil.fetchFromSparseArray(borderRadius, position, 
DEFAULT_BORDER_RADIUS);
-  }
-
   private void updateBorderOutline() {
     if (mNeedUpdatePath) {
       mNeedUpdatePath = false;
@@ -313,25 +346,26 @@ public class BorderDrawable extends Drawable {
                                  @NonNull Path path) {
     if (mBorderRadius != null) {
       prepareBorderRadius(rectF);
-      float topLeftRadius = getBorderRadius(mOverlappingBorderRadius, 
BORDER_TOP_LEFT_RADIUS);
-      float topRightRadius = getBorderRadius(mOverlappingBorderRadius, 
BORDER_TOP_RIGHT_RADIUS);
-      float bottomRightRadius = getBorderRadius(mOverlappingBorderRadius,
-                                                BORDER_BOTTOM_RIGHT_RADIUS);
-      float bottomLeftRadius = getBorderRadius(mOverlappingBorderRadius,
-                                               BORDER_BOTTOM_LEFT_RADIUS);
+      if (mOverlappingBorderRadius == null) {
+        mOverlappingBorderRadius = new CSSShorthand<>();
+      }
+      float topLeftRadius = mOverlappingBorderRadius.get(BORDER_TOP_LEFT);
+      float topRightRadius = mOverlappingBorderRadius.get(BORDER_TOP_RIGHT);
+      float bottomRightRadius = 
mOverlappingBorderRadius.get(BORDER_BOTTOM_RIGHT);
+      float bottomLeftRadius = 
mOverlappingBorderRadius.get(BORDER_BOTTOM_LEFT);
       path.addRoundRect(
-          rectF,
-          new float[]{
-              topLeftRadius - leftPadding,
-              topLeftRadius - topPadding,
-              topRightRadius - rightPadding,
-              topRightRadius - topPadding,
-              bottomRightRadius - rightPadding,
-              bottomRightRadius - bottomPadding,
-              bottomLeftRadius - leftPadding,
-              bottomLeftRadius - bottomPadding
-          },
-          Path.Direction.CW);
+              rectF,
+              new float[]{
+                      topLeftRadius - leftPadding,
+                      topLeftRadius - topPadding,
+                      topRightRadius - rightPadding,
+                      topRightRadius - topPadding,
+                      bottomRightRadius - rightPadding,
+                      bottomRightRadius - bottomPadding,
+                      bottomLeftRadius - leftPadding,
+                      bottomLeftRadius - bottomPadding
+              },
+              Path.Direction.CW);
     } else {
       path.addRect(rectF, Path.Direction.CW);
     }
@@ -344,44 +378,39 @@ public class BorderDrawable extends Drawable {
     if (mBorderRadius != null) {
       float factor = getScaleFactor(borderBox);
       if (mOverlappingBorderRadius == null) {
-        mOverlappingBorderRadius = new SparseArray<>(5);
-        mOverlappingBorderRadius.put(Spacing.ALL, 0f);
+        mOverlappingBorderRadius = new CSSShorthand<>();
       }
       if (!Float.isNaN(factor) && factor < 1) {
-        mOverlappingBorderRadius.put(BORDER_TOP_LEFT_RADIUS,
-                                     getBorderRadius(mBorderRadius, 
BORDER_TOP_LEFT_RADIUS) *
-                                     factor);
-        mOverlappingBorderRadius.put(BORDER_TOP_RIGHT_RADIUS,
-                                     getBorderRadius(mBorderRadius, 
BORDER_TOP_RIGHT_RADIUS) *
-                                     factor);
-        mOverlappingBorderRadius.put(BORDER_BOTTOM_RIGHT_RADIUS,
-                                     getBorderRadius(mBorderRadius, 
BORDER_BOTTOM_RIGHT_RADIUS) *
-                                     factor);
-        mOverlappingBorderRadius.put(BORDER_BOTTOM_LEFT_RADIUS,
-                                     getBorderRadius(mBorderRadius, 
BORDER_BOTTOM_LEFT_RADIUS) *
-                                     factor);
+        mOverlappingBorderRadius.set(BORDER_TOP_LEFT,
+            mBorderRadius.get(BORDER_TOP_LEFT) * factor);
+        mOverlappingBorderRadius.set(BORDER_TOP_RIGHT,
+            mBorderRadius.get(BORDER_TOP_RIGHT) * factor);
+        mOverlappingBorderRadius.set(BORDER_BOTTOM_RIGHT,
+            mBorderRadius.get(BORDER_BOTTOM_RIGHT) * factor);
+        mOverlappingBorderRadius.set(BORDER_BOTTOM_LEFT,
+            mBorderRadius.get(BORDER_BOTTOM_LEFT) * factor);
       } else {
-        mOverlappingBorderRadius.put(BORDER_TOP_LEFT_RADIUS,
-                                     getBorderRadius(mBorderRadius, 
BORDER_TOP_LEFT_RADIUS));
-        mOverlappingBorderRadius.put(BORDER_TOP_RIGHT_RADIUS,
-                                     getBorderRadius(mBorderRadius, 
BORDER_TOP_RIGHT_RADIUS));
-        mOverlappingBorderRadius.put(BORDER_BOTTOM_RIGHT_RADIUS,
-                                     getBorderRadius(mBorderRadius, 
BORDER_BOTTOM_RIGHT_RADIUS));
-        mOverlappingBorderRadius.put(BORDER_BOTTOM_LEFT_RADIUS,
-                                     getBorderRadius(mBorderRadius, 
BORDER_BOTTOM_LEFT_RADIUS));
+        mOverlappingBorderRadius.set(BORDER_TOP_LEFT,
+            mBorderRadius.get(BORDER_TOP_LEFT));
+        mOverlappingBorderRadius.set(BORDER_TOP_RIGHT,
+            mBorderRadius.get(BORDER_TOP_RIGHT));
+        mOverlappingBorderRadius.set(BORDER_BOTTOM_RIGHT,
+            mBorderRadius.get(BORDER_BOTTOM_RIGHT));
+        mOverlappingBorderRadius.set(BORDER_BOTTOM_LEFT,
+            mBorderRadius.get(BORDER_BOTTOM_LEFT));
       }
     }
   }
 
   private float getScaleFactor(@NonNull RectF borderBox) {
-    final float topRadius = getBorderRadius(mBorderRadius, 
BORDER_TOP_LEFT_RADIUS)
-                            + getBorderRadius(mBorderRadius, 
BORDER_TOP_RIGHT_RADIUS);
-    final float rightRadius = getBorderRadius(mBorderRadius, 
BORDER_TOP_RIGHT_RADIUS)
-                              + getBorderRadius(mBorderRadius, 
BORDER_BOTTOM_RIGHT_RADIUS);
-    final float bottomRadius = getBorderRadius(mBorderRadius, 
BORDER_BOTTOM_RIGHT_RADIUS)
-                               + getBorderRadius(mBorderRadius, 
BORDER_BOTTOM_LEFT_RADIUS);
-    final float leftRadius = getBorderRadius(mBorderRadius, 
BORDER_BOTTOM_LEFT_RADIUS)
-                             + getBorderRadius(mBorderRadius, 
BORDER_TOP_LEFT_RADIUS);
+    final float topRadius = mBorderRadius.get(BORDER_TOP_LEFT)
+            + mBorderRadius.get(BORDER_TOP_RIGHT);
+    final float rightRadius = mBorderRadius.get(BORDER_TOP_RIGHT)
+            + mBorderRadius.get(BORDER_BOTTOM_RIGHT);
+    final float bottomRadius = mBorderRadius.get(BORDER_BOTTOM_RIGHT)
+            + mBorderRadius.get(BORDER_BOTTOM_LEFT);
+    final float leftRadius = mBorderRadius.get(BORDER_BOTTOM_LEFT)
+            + mBorderRadius.get(BORDER_TOP_LEFT);
     List<Float> factors = new ArrayList<>(4);
     updateFactor(factors, borderBox.width(), topRadius);
     updateFactor(factors, borderBox.height(), rightRadius);
@@ -397,55 +426,66 @@ public class BorderDrawable extends Drawable {
   }
 
   private void updateFactor(@NonNull List<Float> list, float numerator, float 
denominator) {
-    if (!FloatUtil.floatsEqual(denominator, 0)) {
+    if (denominator != 0) {
       list.add(numerator / denominator);
     }
   }
 
   private void drawBorders(Canvas canvas) {
-    RectF rectBounds = new RectF(getBounds());
-    BorderCorner topLeft = new TopLeftCorner(
-        getBorderRadius(mOverlappingBorderRadius, BORDER_TOP_LEFT_RADIUS),
-        getBorderWidth(Spacing.LEFT),
-        getBorderWidth(Spacing.TOP),
-        rectBounds);
-    BorderCorner topRight = new TopRightCorner(
-        getBorderRadius(mOverlappingBorderRadius, BORDER_TOP_RIGHT_RADIUS),
-        getBorderWidth(Spacing.TOP),
-        getBorderWidth(Spacing.RIGHT),
-        rectBounds);
-    BorderCorner bottomRight = new BottomRightCorner(
-        getBorderRadius(mOverlappingBorderRadius, BORDER_BOTTOM_RIGHT_RADIUS),
-        getBorderWidth(Spacing.RIGHT),
-        getBorderWidth(Spacing.BOTTOM),
-        rectBounds);
-    BorderCorner bottomLeft = new BottomLeftCorner(
-        getBorderRadius(mOverlappingBorderRadius, BORDER_BOTTOM_LEFT_RADIUS),
-        getBorderWidth(Spacing.BOTTOM),
-        getBorderWidth(Spacing.LEFT),
-        rectBounds);
-    drawOneSide(canvas, new BorderEdge(topLeft, topRight, Spacing.TOP,
-                                       getBorderWidth(Spacing.TOP)));
-    drawOneSide(canvas, new BorderEdge(topRight, bottomRight, Spacing.RIGHT,
-                                       getBorderWidth(Spacing.RIGHT)));
-    drawOneSide(canvas, new BorderEdge(bottomRight, bottomLeft, Spacing.BOTTOM,
-                                       getBorderWidth(Spacing.BOTTOM)));
-    drawOneSide(canvas, new BorderEdge(bottomLeft, topLeft, Spacing.LEFT,
-                                       getBorderWidth(Spacing.LEFT)));
+    if (mRectBounds == null) {
+      mRectBounds = new RectF(getBounds());
+    } else {
+      mRectBounds.set(getBounds());
+    }
+
+    final float leftBorderWidth = mBorderWidth.get(EDGE.LEFT);
+    final float topBorderWidth = mBorderWidth.get(EDGE.TOP);
+    final float bottomBorderWidth = mBorderWidth.get(EDGE.BOTTOM);
+    final float rightBorderWidth = mBorderWidth.get(EDGE.RIGHT);
+
+    if (mTopLeftCorner == null) {
+      mTopLeftCorner = new TopLeftCorner();
+    }
+    mTopLeftCorner.set(getBorderRadius(BORDER_TOP_LEFT), leftBorderWidth, 
topBorderWidth, mRectBounds);
+    if (mTopRightCorner == null) {
+      mTopRightCorner = new TopRightCorner();
+    }
+    mTopRightCorner.set(getBorderRadius(BORDER_TOP_RIGHT), topBorderWidth, 
rightBorderWidth, mRectBounds);
+    if (mBottomRightCorner == null) {
+      mBottomRightCorner = new BottomRightCorner();
+    }
+    mBottomRightCorner.set(getBorderRadius(BORDER_BOTTOM_RIGHT), 
rightBorderWidth, bottomBorderWidth, mRectBounds);
+    if (mBottomLeftCorner == null) {
+      mBottomLeftCorner = new BottomLeftCorner();
+    }
+    mBottomLeftCorner.set(getBorderRadius(BORDER_BOTTOM_LEFT), 
bottomBorderWidth, leftBorderWidth, mRectBounds);
+
+    drawOneSide(canvas, mBorderEdge.set(mTopLeftCorner, mTopRightCorner, 
topBorderWidth, EDGE.TOP));
+    drawOneSide(canvas, mBorderEdge.set(mTopRightCorner, mBottomRightCorner, 
rightBorderWidth, EDGE.RIGHT));
+    drawOneSide(canvas, mBorderEdge.set(mBottomRightCorner, mBottomLeftCorner, 
bottomBorderWidth, EDGE.BOTTOM));
+    drawOneSide(canvas, mBorderEdge.set(mBottomLeftCorner, mTopLeftCorner, 
leftBorderWidth, EDGE.LEFT));
+  }
+
+  private float getBorderRadius(CORNER position) {
+    if (null != mOverlappingBorderRadius) {
+      return mOverlappingBorderRadius.get(position);
+    } else {
+      return 0.0f;
+    }
   }
 
   private void drawOneSide(Canvas canvas, @NonNull BorderEdge borderEdge) {
-    if (!FloatUtil.floatsEqual(0, getBorderWidth(borderEdge.getEdge()))) {
+    if (0 != borderEdge.getBorderWidth()) {
       preparePaint(borderEdge.getEdge());
       borderEdge.drawEdge(canvas, mPaint);
     }
   }
 
-  private void preparePaint(@BorderWidthStyleColorType int side) {
-    float borderWidth = getBorderWidth(side);
-    int color = WXViewUtils.multiplyColorAlpha(getBorderColor(side), mAlpha);
-    BorderStyle borderStyle = BorderStyle.values()[getBorderStyle(side)];
-    Shader shader = borderStyle.getLineShader(borderWidth, color, side);
+  private void preparePaint(CSSShorthand.EDGE edge) {
+    final float borderWidth = mBorderWidth.get(edge);
+    final int color = WXViewUtils.multiplyColorAlpha(getBorderColor(edge), 
mAlpha);
+    final BorderStyle borderStyle = sBorderStyle[getBorderStyle(edge)];
+    final Shader shader = borderStyle.getLineShader(borderWidth, color, edge);
     mPaint.setShader(shader);
     mPaint.setColor(color);
     mPaint.setStrokeCap(Paint.Cap.ROUND);

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderEdge.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderEdge.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderEdge.java
index 0da0354..76c4e95 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderEdge.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderEdge.java
@@ -21,10 +21,8 @@ package com.taobao.weex.ui.view.border;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.PointF;
-import android.graphics.RectF;
 import android.support.annotation.NonNull;
-
-import com.taobao.weex.dom.flex.Spacing;
+import com.taobao.weex.dom.CSSShorthand;
 
 /**
  * Edge for border. Every border has four edges, and each edge has a previous 
corner and a post
@@ -34,21 +32,24 @@ class BorderEdge {
 
   private
   @NonNull
-  final BorderCorner mPreCorner;
+  BorderCorner mPreCorner;
   private
   @NonNull
-  final BorderCorner mPostCorner;
+  BorderCorner mPostCorner;
+
+  private CSSShorthand.EDGE mEdge;
+  private float mBorderWidth;
 
-  private final int mEdge;
-  private final float mBorderWidth;
+  BorderEdge() {
+  }
 
-  BorderEdge(@NonNull BorderCorner preCorner, @NonNull BorderCorner postCorner,
-             @BorderWidthStyleColorType int edge, float
-      borderWidth) {
+  BorderEdge set(@NonNull BorderCorner preCorner, @NonNull BorderCorner 
postCorner,
+                 float borderWidth, CSSShorthand.EDGE edge) {
     mPreCorner = preCorner;
     mPostCorner = postCorner;
-    mEdge = edge;
     mBorderWidth = borderWidth;
+    mEdge = edge;
+    return this;
   }
 
   /**
@@ -57,63 +58,32 @@ class BorderEdge {
    * @param paint the paint which is used to draw.
    */
   void drawEdge(@NonNull Canvas canvas, @NonNull Paint paint) {
-    RectF oval;
-    PointF lineStart = mPreCorner.getCornerEnd();
     paint.setStrokeWidth(mBorderWidth);
 
-    drawRoundedCorner(canvas, paint, mPreCorner,
-                      mPreCorner.getAngleBisectorDegree(),
-                      mPreCorner.getSharpCornerStart(), lineStart);
+    mPreCorner.drawRoundedCorner(canvas, paint, 
mPreCorner.getAngleBisectorDegree());
 
     paint.setStrokeWidth(mBorderWidth);
-    PointF lineEnd = mPostCorner.getCornerStart();
-    canvas.drawLine(lineStart.x, lineStart.y, lineEnd.x, lineEnd.y, paint);
 
-    drawRoundedCorner(canvas, paint, mPostCorner,
-                      mPostCorner.getAngleBisectorDegree() - 
BorderCorner.SWEEP_ANGLE,
-                      lineEnd, mPostCorner.getSharpCornerEnd());
-  }
+    final float lineStartX = mPreCorner.getRoundCornerEndX();
+    final float lineStartY = mPreCorner.getRoundCornerEndY();
 
-  /**
-   * Draw the Rounded corner.
-   * @param canvas the canvas where the edge will be drawn
-   * @param paint the paint which is used to draw
-   * @param borderCorner the corner to be drawn
-   * @param startAngle the startAngle of the corner
-   * @param startPoint the startPoint of the line
-   * @param endPoint the endPoint of the line
-   */
-  private void drawRoundedCorner(@NonNull Canvas canvas, @NonNull Paint paint,
-                                 @NonNull BorderCorner borderCorner, float 
startAngle,
-                                 @NonNull PointF startPoint, @NonNull PointF 
endPoint) {
-    if (borderCorner.hasOuterCorner()) {
-      RectF oval;
-      if (borderCorner.hasInnerCorner()) {
-        oval = borderCorner.getOvalIfInnerCornerExist();
-      } else {
-        paint.setStrokeWidth(borderCorner.getOuterCornerRadius());
-        oval = borderCorner.getOvalIfInnerCornerNotExist();
-      }
-      /*Due to the problem of hardware-acceleration, border-radius in some 
case will not
-       be rendered if Path.addArc used instead and the following condition met.
-       1. hardware-acceleration enabled
-       2. System version is Android 4.1
-       3. Screen width is 720px.
-       http://dotwe.org/weex/421b9ad09fde51c0b49bb56b37fcf955
-      */
-      canvas.drawArc(oval, startAngle, BorderCorner.SWEEP_ANGLE, false, paint);
-    } else {
-      canvas.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, 
paint);
-    }
+    final float lineEndX = mPostCorner.getRoundCornerStartX();
+    final float lineEndY = mPostCorner.getRoundCornerStartY();
+
+    canvas.drawLine(lineStartX, lineStartY, lineEndX, lineEndY, paint);
+
+    mPostCorner.drawRoundedCorner(canvas, paint, 
mPostCorner.getAngleBisectorDegree() - BorderCorner.SWEEP_ANGLE);
   }
 
   /**
    * The index of the edge
    * @return index of edge. May be one of
-   * {@link Spacing#TOP},{@link Spacing#BOTTOM},{@link Spacing#RIGHT},{@link 
Spacing#LEFT}.
    */
-  public @BorderWidthStyleColorType
-  int getEdge() {
+  public CSSShorthand.EDGE getEdge() {
     return mEdge;
   }
+
+  public float getBorderWidth() {
+    return mBorderWidth;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderStyle.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderStyle.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderStyle.java
index aab38f7..91f4ad7 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderStyle.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderStyle.java
@@ -23,8 +23,7 @@ import android.graphics.LinearGradient;
 import android.graphics.PathEffect;
 import android.graphics.Shader;
 import android.support.annotation.Nullable;
-
-import com.taobao.weex.dom.flex.Spacing;
+import com.taobao.weex.dom.CSSShorthand;
 
 enum BorderStyle {
   SOLID,
@@ -36,28 +35,28 @@ enum BorderStyle {
    * for implementing {@link #DASHED} or {@link #DASHED}
    * @param borderWidth width of the edge
    * @param borderColor color of the edge
-   * @param edge the index of the ede. See {@link Spacing}
+   * @param edge the index of the ede. See {@link CSSShorthand}
    * @return An object of {@link LinearGradient} without color transitions for 
{@link #DOTTED}
    * or {@link #DASHED}, null otherwise
    */
   @Nullable
-  Shader getLineShader(float borderWidth, int borderColor, int edge) {
+  Shader getLineShader(float borderWidth, int borderColor, CSSShorthand.EDGE 
edge) {
     switch (this) {
       case DOTTED:
-        if (edge == Spacing.LEFT || edge == Spacing.RIGHT) {
+        if (edge == CSSShorthand.EDGE.LEFT || edge == CSSShorthand.EDGE.RIGHT) 
{
           return new LinearGradient(0, 0, 0, borderWidth * 2, new 
int[]{borderColor, Color
-              .TRANSPARENT}, new float[]{0.5f, 0.5f}, Shader.TileMode.REPEAT);
-        } else if (edge == Spacing.TOP || edge == Spacing.BOTTOM) {
+                  .TRANSPARENT}, new float[]{0.5f, 0.5f}, 
Shader.TileMode.REPEAT);
+        } else if (edge == CSSShorthand.EDGE.TOP || edge == 
CSSShorthand.EDGE.BOTTOM) {
           return new LinearGradient(0, 0, borderWidth * 2, 0, new 
int[]{borderColor, Color
-              .TRANSPARENT}, new float[]{0.5f, 0.5f}, Shader.TileMode.REPEAT);
+                  .TRANSPARENT}, new float[]{0.5f, 0.5f}, 
Shader.TileMode.REPEAT);
         }
       case DASHED:
-        if (edge == Spacing.LEFT || edge == Spacing.RIGHT) {
+        if (edge == CSSShorthand.EDGE.LEFT || edge == CSSShorthand.EDGE.RIGHT) 
{
           return new LinearGradient(0, 0, 0, borderWidth * 6, new 
int[]{borderColor, Color
-              .TRANSPARENT}, new float[]{0.5f, 0.5f}, Shader.TileMode.REPEAT);
-        } else if (edge == Spacing.TOP || edge == Spacing.BOTTOM) {
+                  .TRANSPARENT}, new float[]{0.5f, 0.5f}, 
Shader.TileMode.REPEAT);
+        } else if (edge == CSSShorthand.EDGE.TOP || edge == 
CSSShorthand.EDGE.BOTTOM) {
           return new LinearGradient(0, 0, borderWidth * 6, 0, new 
int[]{borderColor, Color
-              .TRANSPARENT}, new float[]{0.5f, 0.5f}, Shader.TileMode.REPEAT);
+                  .TRANSPARENT}, new float[]{0.5f, 0.5f}, 
Shader.TileMode.REPEAT);
         }
       default:
         return null;

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderUtil.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderUtil.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderUtil.java
index b768eb5..9779dbe 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderUtil.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderUtil.java
@@ -23,59 +23,24 @@ import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
-
-import com.taobao.weex.dom.flex.Spacing;
+import com.taobao.weex.dom.CSSShorthand;
 
 class BorderUtil {
 
-  static <T> T fetchFromSparseArray(@Nullable SparseArray<T> array, int 
position, T fallback) {
-    return array == null ? fallback :
-           array.get(position, array.get(Spacing.ALL));
-  }
-
   static int fetchFromSparseArray(@Nullable SparseIntArray array, int 
position, int fallback) {
     return array == null ? fallback :
-           array.get(position, array.get(Spacing.ALL));
-  }
-
-  static <T> void updateSparseArray(@NonNull SparseArray<T> array, int 
position, T value) {
-    updateSparseArray(array, position, value, false);
+            array.get(position, array.get(CSSShorthand.EDGE.ALL.ordinal()));
   }
 
   static void updateSparseArray(@NonNull SparseIntArray array, int position, 
int value) {
-      if (position == Spacing.ALL) {
-        array.put(Spacing.ALL, value);
-        array.put(Spacing.TOP, value);
-        array.put(Spacing.LEFT, value);
-        array.put(Spacing.RIGHT, value);
-        array.put(Spacing.BOTTOM, value);
-      } else {
-        array.put(position, value);
-      }
-    }
-
-  static <T> void updateSparseArray(@NonNull SparseArray<T> array, int 
position, T value,
-                             boolean borderRadius) {
-    if (borderRadius) {
-      if (position == BorderDrawable.BORDER_RADIUS_ALL) {
-        array.put(BorderDrawable.BORDER_RADIUS_ALL, value);
-        array.put(BorderDrawable.BORDER_TOP_LEFT_RADIUS, value);
-        array.put(BorderDrawable.BORDER_TOP_RIGHT_RADIUS, value);
-        array.put(BorderDrawable.BORDER_BOTTOM_LEFT_RADIUS, value);
-        array.put(BorderDrawable.BORDER_BOTTOM_RIGHT_RADIUS, value);
-      } else {
-        array.put(position, value);
-      }
+    if (position == CSSShorthand.EDGE.ALL.ordinal()) {
+      array.put(CSSShorthand.EDGE.ALL.ordinal(), value);
+      array.put(CSSShorthand.EDGE.TOP.ordinal(), value);
+      array.put(CSSShorthand.EDGE.LEFT.ordinal(), value);
+      array.put(CSSShorthand.EDGE.RIGHT.ordinal(), value);
+      array.put(CSSShorthand.EDGE.BOTTOM.ordinal(), value);
     } else {
-      if (position == Spacing.ALL) {
-        array.put(Spacing.ALL, value);
-        array.put(Spacing.TOP, value);
-        array.put(Spacing.LEFT, value);
-        array.put(Spacing.RIGHT, value);
-        array.put(Spacing.BOTTOM, value);
-      } else {
-        array.put(position, value);
-      }
+      array.put(position, value);
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderWidthStyleColorType.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderWidthStyleColorType.java
 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderWidthStyleColorType.java
deleted file mode 100644
index 44ec8f8..0000000
--- 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderWidthStyleColorType.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.taobao.weex.ui.view.border;
-
-import android.support.annotation.IntDef;
-
-import com.taobao.weex.dom.flex.Spacing;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-@Retention(RetentionPolicy.SOURCE)
-@IntDef({
-    Spacing.ALL,
-    Spacing.TOP,
-    Spacing.RIGHT,
-    Spacing.BOTTOM,
-    Spacing.LEFT})
-public @interface BorderWidthStyleColorType {
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomLeftCorner.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomLeftCorner.java
 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomLeftCorner.java
index 3c01a76..40c3d14 100644
--- 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomLeftCorner.java
+++ 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomLeftCorner.java
@@ -18,68 +18,47 @@
  */
 package com.taobao.weex.ui.view.border;
 
-import android.graphics.PointF;
 import android.graphics.RectF;
 import android.support.annotation.NonNull;
 
 class BottomLeftCorner extends BorderCorner {
 
-  BottomLeftCorner(float cornerRadius, float preBorderWidth, float 
postBorderWidth, @NonNull RectF borderBox) {
-    super(cornerRadius, preBorderWidth, postBorderWidth, borderBox, 135);
+  void set(float cornerRadius, float preBorderWidth, float postBorderWidth, 
@NonNull RectF borderBox) {
+    set(cornerRadius, preBorderWidth, postBorderWidth, borderBox, 135);
   }
 
-  @NonNull
   @Override
-  protected RectF getOvalIfInnerCornerExist() {
-    return new RectF(getPostBorderWidth() / 2,
-                     getBorderBox().height() - (2 * getOuterCornerRadius() - 
getPreBorderWidth() / 2),
-                     2 * getOuterCornerRadius() - getPostBorderWidth() / 2,
-                     getBorderBox().height() - getPreBorderWidth() / 2);
+  protected void prepareOval() {
+    if (hasInnerCorner()) {
+      setOvalLeft(getPostBorderWidth() / 2);
+      setOvalTop(getBorderBox().height() - (2 * getOuterCornerRadius() - 
getPreBorderWidth() / 2));
+      setOvalRight(2 * getOuterCornerRadius() - getPostBorderWidth() / 2);
+      setOvalBottom(getBorderBox().height() - getPreBorderWidth() / 2);
+    } else {
+      setOvalLeft(getOuterCornerRadius() / 2);
+      setOvalTop(getBorderBox().height() - 1.5f * getOuterCornerRadius());
+      setOvalRight(1.5f * getOuterCornerRadius());
+      setOvalBottom(getBorderBox().height() - getOuterCornerRadius() / 2);
+    }
   }
 
-  @NonNull
   @Override
-  protected RectF getOvalIfInnerCornerNotExist() {
-    return new RectF(getOuterCornerRadius()/2,
-                     getBorderBox().height()-1.5f*getOuterCornerRadius(),
-                     1.5f*getOuterCornerRadius(),
-                     getBorderBox().height()-getOuterCornerRadius()/2);
-  }
-
-  @NonNull
-  @Override
-  protected PointF getRoundCornerStart() {
-    return new PointF(getOuterCornerRadius(),
-                      getBorderBox().height() - getPreBorderWidth() / 2);
-  }
-
-  @NonNull
-  @Override
-  protected PointF getSharpCornerVertex() {
-    return new PointF(getPostBorderWidth() / 2,
-                      getBorderBox().height() - getPreBorderWidth() / 2);
-  }
+  protected void prepareRoundCorner() {
+    if (hasOuterCorner()) {
+      setRoundCornerStartX(getOuterCornerRadius());
+      setRoundCornerStartY(getBorderBox().height() - getPreBorderWidth() / 2);
 
-  @NonNull
-  @Override
-  protected PointF getSharpCornerStart() {
-    PointF pointF=getSharpCornerVertex();
-    pointF.y=getBorderBox().height();
-    return pointF;
-  }
+      setRoundCornerEndX(getPostBorderWidth() / 2);
+      setRoundCornerEndY(getBorderBox().height() - getOuterCornerRadius());
+    } else {
+      final float x = getPostBorderWidth() / 2;
+      final float y = getBorderBox().height() - getPreBorderWidth() / 2;
 
-  @NonNull
-  @Override
-  protected PointF getSharpCornerEnd() {
-    PointF pointF=getSharpCornerVertex();
-    pointF.x=0;
-    return pointF;
-  }
+      setRoundCornerStartX(x);
+      setRoundCornerStartY(y);
 
-  @NonNull
-  @Override
-  protected PointF getRoundCornerEnd() {
-    return new PointF(getPostBorderWidth() / 2,
-                      getBorderBox().height() - getOuterCornerRadius());
+      setRoundCornerEndX(x);
+      setRoundCornerEndY(y);
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomRightCorner.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomRightCorner.java
 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomRightCorner.java
index 2ed50a4..82ef548 100644
--- 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomRightCorner.java
+++ 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomRightCorner.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  *   http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -18,68 +18,47 @@
  */
 package com.taobao.weex.ui.view.border;
 
-import android.graphics.PointF;
 import android.graphics.RectF;
 import android.support.annotation.NonNull;
 
 class BottomRightCorner extends BorderCorner {
 
-  BottomRightCorner(float cornerRadius, float preBorderWidth, float 
postBorderWidth, @NonNull RectF borderBox) {
-    super(cornerRadius, preBorderWidth, postBorderWidth, borderBox, 45);
+  void set(float cornerRadius, float preBorderWidth, float postBorderWidth, 
@NonNull RectF borderBox) {
+    set(cornerRadius, preBorderWidth, postBorderWidth, borderBox, 45);
   }
 
-  @NonNull
   @Override
-  protected RectF getOvalIfInnerCornerExist() {
-    return new RectF(getBorderBox().width() - (2 * getOuterCornerRadius() - 
getPreBorderWidth() / 2),
-                     getBorderBox().height() - (2 * getOuterCornerRadius() - 
getPostBorderWidth() / 2),
-                     getBorderBox().width() - (getPreBorderWidth() / 2),
-                     getBorderBox().height() - (getPostBorderWidth() / 2));
+  protected void prepareOval() {
+    if (hasInnerCorner()) {
+      setOvalLeft(getBorderBox().width() - (2 * getOuterCornerRadius() - 
getPreBorderWidth() / 2));
+      setOvalTop(getBorderBox().height() - (2 * getOuterCornerRadius() - 
getPostBorderWidth() / 2));
+      setOvalRight(getBorderBox().width() - (getPreBorderWidth() / 2));
+      setOvalBottom(getBorderBox().height() - (getPostBorderWidth() / 2));
+    } else {
+      setOvalLeft(getBorderBox().width() - 1.5f * getOuterCornerRadius());
+      setOvalTop(getBorderBox().height() - 1.5f * getOuterCornerRadius());
+      setOvalRight(getBorderBox().width() - getOuterCornerRadius() / 2);
+      setOvalBottom(getBorderBox().height() - getOuterCornerRadius() / 2);
+    }
   }
 
-  @NonNull
   @Override
-  protected RectF getOvalIfInnerCornerNotExist() {
-    return new RectF(getBorderBox().width() - 1.5f * getOuterCornerRadius(),
-                     getBorderBox().height() - 1.5f * getOuterCornerRadius(),
-                     getBorderBox().width()-getOuterCornerRadius()/2,
-                     getBorderBox().height()-getOuterCornerRadius()/2);
-  }
-
-  @NonNull
-  @Override
-  protected PointF getRoundCornerStart() {
-    return new PointF(getBorderBox().width() - getPreBorderWidth() / 2,
-                      getBorderBox().height() - getOuterCornerRadius());
-  }
-
-  @NonNull
-  @Override
-  protected PointF getSharpCornerVertex() {
-    return new PointF(getBorderBox().width() - getPreBorderWidth() / 2,
-                      getBorderBox().height() - getPostBorderWidth() / 2);
-  }
+  protected void prepareRoundCorner() {
+    if (hasOuterCorner()) {
+      setRoundCornerStartX(getBorderBox().width() - getPreBorderWidth() / 2);
+      setRoundCornerStartY(getBorderBox().height() - getOuterCornerRadius());
 
-  @NonNull
-  @Override
-  protected PointF getSharpCornerStart() {
-    PointF pointF=getSharpCornerVertex();
-    pointF.x=getBorderBox().right;
-    return pointF;
-  }
+      setRoundCornerEndX(getBorderBox().width() - getOuterCornerRadius());
+      setRoundCornerEndY(getBorderBox().height() - getPostBorderWidth() / 2);
+    } else {
+      final float x = getBorderBox().width() - getPreBorderWidth() / 2;
+      final float y = getBorderBox().height() - getPostBorderWidth() / 2;
 
-  @NonNull
-  @Override
-  protected PointF getSharpCornerEnd() {
-    PointF pointF=getSharpCornerVertex();
-    pointF.y=getBorderBox().height();
-    return pointF;
-  }
+      setRoundCornerStartX(x);
+      setRoundCornerStartY(y);
 
-  @NonNull
-  @Override
-  protected PointF getRoundCornerEnd() {
-    return new PointF(getBorderBox().width() - getOuterCornerRadius(),
-                      getBorderBox().height() - getPostBorderWidth() / 2);
+      setRoundCornerEndX(x);
+      setRoundCornerEndY(y);
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopLeftCorner.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopLeftCorner.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopLeftCorner.java
index e83706f..42c9cb2 100644
--- 
a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopLeftCorner.java
+++ 
b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopLeftCorner.java
@@ -18,65 +18,47 @@
  */
 package com.taobao.weex.ui.view.border;
 
-import android.graphics.PointF;
 import android.graphics.RectF;
 import android.support.annotation.NonNull;
 
 class TopLeftCorner extends BorderCorner {
 
-  TopLeftCorner(float cornerRadius, float preBorderWidth, float 
postBorderWidth, @NonNull RectF borderBox) {
-    super(cornerRadius, preBorderWidth, postBorderWidth, borderBox, 225);
+  void set(float cornerRadius, float preBorderWidth, float postBorderWidth, 
@NonNull RectF borderBox) {
+    set(cornerRadius, preBorderWidth, postBorderWidth, borderBox, 225);
   }
 
-  @NonNull
   @Override
-  protected RectF getOvalIfInnerCornerExist() {
-    return new RectF(getPreBorderWidth() / 2,
-                     getPostBorderWidth() / 2,
-                     2 * getOuterCornerRadius() - getPreBorderWidth() / 2,
-                     2 * getOuterCornerRadius() - getPostBorderWidth() / 2);
+  protected void prepareOval() {
+    if (hasInnerCorner()) {
+      setOvalLeft(getPreBorderWidth() / 2);
+      setOvalTop(getPostBorderWidth() / 2);
+      setOvalRight(2 * getOuterCornerRadius() - getPreBorderWidth() / 2);
+      setOvalBottom(2 * getOuterCornerRadius() - getPostBorderWidth() / 2);
+    } else {
+      setOvalLeft(getOuterCornerRadius() / 2);
+      setOvalTop(getOuterCornerRadius() / 2);
+      setOvalRight(getOuterCornerRadius() * 1.5f);
+      setOvalBottom(getOuterCornerRadius() * 1.5f);
+    }
   }
 
-  @NonNull
   @Override
-  protected RectF getOvalIfInnerCornerNotExist() {
-    return new RectF(getOuterCornerRadius()/2,
-                     getOuterCornerRadius()/2,
-                     getOuterCornerRadius() * 1.5f,
-                     getOuterCornerRadius() * 1.5f);
-  }
-
-  @NonNull
-  @Override
-  protected PointF getRoundCornerStart() {
-    return new PointF(getPreBorderWidth() / 2, getOuterCornerRadius());
-  }
-
-  @NonNull
-  @Override
-  protected PointF getSharpCornerVertex() {
-    return new PointF(getPreBorderWidth() / 2, getPostBorderWidth() / 2);
-  }
+  protected void prepareRoundCorner() {
+    if (hasOuterCorner()) {
+      setRoundCornerStartX(getPreBorderWidth() / 2);
+      setRoundCornerStartY(getOuterCornerRadius());
 
-  @NonNull
-  @Override
-  protected PointF getSharpCornerStart() {
-    PointF pointF=getSharpCornerVertex();
-    pointF.x=0;
-    return pointF;
-  }
+      setRoundCornerEndX(getOuterCornerRadius());
+      setRoundCornerEndY(getPostBorderWidth() / 2);
+    } else {
+      final float x = getPreBorderWidth() / 2;
+      final float y = getPostBorderWidth() / 2;
 
-  @NonNull
-  @Override
-  protected PointF getSharpCornerEnd() {
-    PointF pointF=getSharpCornerVertex();
-    pointF.y=0;
-    return pointF;
-  }
+      setRoundCornerStartX(x);
+      setRoundCornerStartY(y);
 
-  @NonNull
-  @Override
-  protected PointF getRoundCornerEnd() {
-    return new PointF(getOuterCornerRadius(), getPostBorderWidth() / 2);
+      setRoundCornerEndX(x);
+      setRoundCornerEndY(y);
+    }
   }
 }


Reply via email to