+ [android] support the box-shadow attribute on android 4.3 or higher

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

Branch: refs/heads/0.16-dev
Commit: b0e072a4211d2b39cc3618c753a50efc3647cf23
Parents: 4490223
Author: misakuo <misa...@apache.org>
Authored: Fri Sep 22 10:46:12 2017 +0800
Committer: misakuo <misa...@apache.org>
Committed: Fri Sep 22 10:46:12 2017 +0800

----------------------------------------------------------------------
 .travis.yml                                     |   47 +-
 POSSIBLE-NOTICES-FOR-BIN-DIST                   |    5 +-
 WeexSDK.podspec                                 |    2 -
 android/build.gradle                            |   13 +-
 .../gradle/wrapper/gradle-wrapper.properties    |    2 +-
 .../alibaba/weex/benchmark/BenchmarkTest.java   |    6 +-
 android/sdk/libs/armeabi/libweexjsc.so          |  Bin 325660 -> 325660 bytes
 android/sdk/libs/armeabi/libweexjss.so          |  Bin 6754012 -> 6754016 bytes
 .../java/com/taobao/weex/WXSDKInstance.java     |  102 +-
 .../appfram/websocket/WebSocketCloseCodes.java  |    2 +-
 .../com/taobao/weex/bridge/WXBridgeManager.java |   27 +-
 .../java/com/taobao/weex/common/Constants.java  |    2 +
 .../com/taobao/weex/dom/ImmutableDomObject.java |   21 +-
 .../main/java/com/taobao/weex/dom/WXStyle.java  |   17 -
 .../com/taobao/weex/dom/WXTextDomObject.java    |   11 +-
 .../com/taobao/weex/dom/action/Actions.java     |    4 +-
 .../weex/dom/action/CreateBodyAction.java       |   12 +-
 .../weex/dom/action/ReloadPageAction.java       |    6 +-
 .../taobao/weex/ui/component/WXComponent.java   |  143 +-
 .../com/taobao/weex/ui/component/WXDiv.java     |   74 +-
 .../com/taobao/weex/ui/component/WXSlider.java  |    4 +-
 .../com/taobao/weex/ui/component/WXText.java    |   65 +-
 .../taobao/weex/ui/component/WXVContainer.java  |   44 +-
 .../taobao/weex/ui/component/list/WXCell.java   |   61 +-
 .../weex/ui/component/list/WXListComponent.java |   53 +-
 .../com/taobao/weex/ui/flat/FlatComponent.java  |   33 +
 .../com/taobao/weex/ui/flat/FlatGUIContext.java |  146 ++
 .../taobao/weex/ui/flat/WidgetContainer.java    |   93 +
 .../weex/ui/flat/widget/AndroidViewWidget.java  |   76 +
 .../taobao/weex/ui/flat/widget/BaseWidget.java  |  130 ++
 .../taobao/weex/ui/flat/widget/TextWidget.java  |   49 +
 .../com/taobao/weex/ui/flat/widget/Widget.java  |   51 +
 .../taobao/weex/ui/flat/widget/WidgetGroup.java |   54 +
 .../taobao/weex/ui/module/WXTimerModule.java    |    9 +-
 .../weex/ui/view/WXBaseCircleIndicator.java     |  131 +-
 .../com/taobao/weex/ui/view/WXFrameLayout.java  |   53 +-
 .../weex/ui/view/border/BorderCorner.java       |   37 +-
 .../taobao/weex/ui/view/border/BorderUtil.java  |   26 -
 .../weex/ui/view/border/BottomLeftCorner.java   |    7 +-
 .../weex/ui/view/border/BottomRightCorner.java  |    7 +-
 .../weex/ui/view/border/TopLeftCorner.java      |    7 +-
 .../weex/ui/view/border/TopRightCorner.java     |    7 +-
 .../com/taobao/weex/utils/FunctionParser.java   |    6 -
 .../java/com/taobao/weex/utils/LogLevel.java    |    4 +-
 .../java/com/taobao/weex/utils/OsVersion.java   |    2 +-
 .../main/java/com/taobao/weex/utils/Trace.java  |    4 +-
 .../java/com/taobao/weex/utils/WXLogUtils.java  |   14 +
 .../java/com/taobao/weex/utils/WXViewUtils.java |   31 +
 .../com/taobao/weex/ui/component/WXDivTest.java |   12 +-
 .../taobao/weex/ui/component/WXTextTest.java    |   18 +-
 .../weex/ui/module/WXTimerModuleTest.java       |   45 +-
 dangerfile-android.js                           |  108 ++
 dangerfile-ios.js                               |  107 ++
 dangerfile-jsfm.js                              |  105 +
 ios/sdk/WeexSDK.xcodeproj/project.pbxproj       |   42 -
 .../Sources/Bridge/WXDebugLoggerBridge.h        |   26 -
 .../Sources/Bridge/WXDebugLoggerBridge.m        |  213 ---
 ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.m |   89 +-
 .../Component/Recycler/WXMultiColumnLayout.m    |   32 +-
 .../Sources/Component/WXComponent_internal.h    |    2 +-
 .../Sources/Component/WXImageComponent.m        |   34 +-
 .../WeexSDK/Sources/Component/WXTextComponent.m |    6 +-
 .../Sources/Display/WXComponent+Display.m       |    2 +-
 ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m    |    4 -
 .../WeexSDK/Sources/Events/WXComponent+Events.m |   35 +-
 .../Sources/Manager/WXComponentManager.m        |    9 +-
 ios/sdk/WeexSDK/Sources/Model/WXComponent.m     |   30 +-
 .../WeexSDK/Sources/Module/WXAnimationModule.m  |   26 +-
 .../WeexSDK/Sources/Module/WXModalUIModule.m    |    4 +-
 .../WeexSDK/Sources/Module/WXWebSocketModule.m  |    1 -
 ios/sdk/WeexSDK/Sources/Utility/WXConvert.m     |   24 +-
 ios/sdk/WeexSDK/Sources/Utility/WXUtility.m     |    4 +
 .../Sources/WebSocket/SRWebSocket+Weex.h        |   29 -
 .../Sources/WebSocket/SRWebSocket+Weex.m        |   47 -
 .../Sources/WebSocket/WXWebSocketDefaultImpl.h  |   25 -
 .../Sources/WebSocket/WXWebSocketDefaultImpl.m  |  121 --
 ios/sdk/WeexSDK/dependency/SRWebSocket.h        |  135 --
 ios/sdk/WeexSDK/dependency/SRWebSocket.m        | 1806 ------------------
 package.json                                    |    5 +-
 scripts/build_from_source.sh                    |    2 +-
 scripts/generate_apache_release.sh              |    2 +-
 test/pages/components/iconfont.vue              |    6 +-
 test/pages/modules/vue_timer.vue                |   14 +-
 test/pages/modules/we_timer.we                  |   14 +-
 test/scripts/components/scroll-event.test.js    |    2 +-
 85 files changed, 1864 insertions(+), 3022 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index a62ef95..dd3f139 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,11 +5,9 @@ language: node_js
 node_js: 7.6
 rvm: 2.0.0
 env:
-  - TEST_SUITE=ios
   - TEST_SUITE=danger
   - TEST_SUITE=jsfm
   - TEST_SUITE=android
-  - TEST_SUITE=release
 matrix:
     fast_finish: true
     exclude:
@@ -25,16 +23,8 @@ matrix:
         env: TEST_SUITE=ios
       - os: linux
         env: TEST_SUITE=android
-      - os: osx
-        env: TEST_SUITE=release
-      - os: linux
-        env: TEST_SUITE=release
     include:
       - os: osx
-        env: TEST_SUITE=release
-        osx_image: xcode8.1
-        language: objective-c
-      - os: osx
         env: TEST_SUITE=ios
         osx_image: xcode8.1
         language: objective-c
@@ -63,50 +53,19 @@ before_script:
       nvm install 7.0
       npm install
     fi
-  - |
-    if [[ $TEST_SUITE = "ios" ]]; then
-      brew update
-    fi
-  - |
-    if [[ $TEST_SUITE = "release" ]]; then
-      brew update
-      #manual install android sdk
-      brew cask install android-sdk
-      brew install gradle
-      export ANDROID_HOME=/usr/local/share/android-sdk
-      export 
PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools
-      echo yes | sdkmanager platform-tools
-      echo yes | sdkmanager tools #tools
-      echo yes | sdkmanager "build-tools;25.0.3" #build-tool
-      echo yes | sdkmanager "platforms;android-25" #compile target
-      echo yes | sdkmanager "extras;android;m2repository" #support
-    fi
 script:
   - |
     if [[ $TEST_SUITE = "android" ]]; then
-      cd android
-      ./gradlew clean assembleDebug :weex_sdk:testDebugUnitTest --info 
-PdisableCov=true -Dorg.gradle.daemon=true -Dorg.gradle.parallel=true 
-Dorg.gradle.jvmargs="-Xmx512m -XX:+HeapDumpOnOutOfMemoryError" 
-Dfile.encoding=UTF-8 &&
+      npm run danger -- run --dangerfile ./dangerfile-android.js
       cd $TRAVIS_BUILD_DIR
     fi
   - |
-    if [[ $TEST_SUITE = "ios" ]]; then
-      xcodebuild -project ios/sdk/WeexSDK.xcodeproj test -scheme WeexSDKTests 
CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -destination 'platform=iOS 
Simulator,name=iPhone 6'
-    fi
-  - |
     if [[ $TEST_SUITE = "jsfm" ]]; then
-      npm run build &&
-      npm run test
+      npm run danger -- run --dangerfile ./dangerfile-jsfm.js
     fi
   - |
     if [[ $TEST_SUITE = "danger" ]]; then
-      npm run danger
-    fi
-  - |
-    if [[ $TEST_SUITE = "release" ]]; then
-      bash scripts/generate_apache_release.sh &&
-      cd apache_release_temp &&
-      bash scripts/build_from_source.sh &&
-      cd $TRAVIS_BUILD_DIR
+      npm run danger -- run --dangerfile ./dangerfile.js
     fi
 notifications:
   webhooks:

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/POSSIBLE-NOTICES-FOR-BIN-DIST
----------------------------------------------------------------------
diff --git a/POSSIBLE-NOTICES-FOR-BIN-DIST b/POSSIBLE-NOTICES-FOR-BIN-DIST
index 350a00b..6efd6ee 100644
--- a/POSSIBLE-NOTICES-FOR-BIN-DIST
+++ b/POSSIBLE-NOTICES-FOR-BIN-DIST
@@ -99,4 +99,7 @@ This product contains software 
SDWebImage(https://github.com/rs/SDWebImage) deve
 by Olivier Poitrey  , licensed under the MIT License.
 
 This product contains software Guava(https://github.com/google/guava) developed
-by google  , licensed under the Apache License.
\ No newline at end of file
+by google  , licensed under the Apache License.
+
+This product contains shelljs Guava(https://github.com/shelljs/shelljs) 
developed
+by shelljs  , licensed under BSD 3-clause "New" or "Revised" License.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/WeexSDK.podspec
----------------------------------------------------------------------
diff --git a/WeexSDK.podspec b/WeexSDK.podspec
index fbf8139..5cb6864 100644
--- a/WeexSDK.podspec
+++ b/WeexSDK.podspec
@@ -39,8 +39,6 @@ Pod::Spec.new do |s|
   s.xcconfig = { "OTHER_LINK_FLAG" => '$(inherited) -ObjC'}
 
   s.frameworks = 
'CoreMedia','MediaPlayer','AVFoundation','AVKit','JavaScriptCore', 'GLKit', 
'OpenGLES', 'CoreText', 'QuartzCore', 'CoreGraphics'
-
-  s.dependency 'SocketRocket'
   s.libraries = "stdc++"
 
 end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/build.gradle
----------------------------------------------------------------------
diff --git a/android/build.gradle b/android/build.gradle
index 28cf76e..9c0e2d5 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -5,12 +5,13 @@ buildscript {
         jcenter()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:2.1.3'
+        classpath 'com.android.tools.build:gradle:2.3.3'
     }
 }
 
 plugins {
     id "de.undercouch.download" version "3.2.0"
+//    id "com.github.dcendents.android-maven" version "1.5"
 }
 
 repositories {
@@ -29,7 +30,9 @@ subprojects {
             jcenter()
         }
         dependencies {
-            classpath 'com.android.tools.build:gradle:2.1.3'
+            classpath 'com.android.tools.build:gradle:2.3.3'
+            classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0'
+            classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
         }
     }
     ext {
@@ -43,6 +46,6 @@ subprojects {
     }
 }
 
-task clean(type: Delete) {
-    delete rootProject.buildDir
-}
+//task clean(type: Delete) {
+//    delete rootProject.buildDir
+//}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/gradle/wrapper/gradle-wrapper.properties
----------------------------------------------------------------------
diff --git a/android/gradle/wrapper/gradle-wrapper.properties 
b/android/gradle/wrapper/gradle-wrapper.properties
index d795868..73990aa 100644
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/playground/app/src/androidTest/java/com/alibaba/weex/benchmark/BenchmarkTest.java
----------------------------------------------------------------------
diff --git 
a/android/playground/app/src/androidTest/java/com/alibaba/weex/benchmark/BenchmarkTest.java
 
b/android/playground/app/src/androidTest/java/com/alibaba/weex/benchmark/BenchmarkTest.java
index dddada7..5a5f74b 100644
--- 
a/android/playground/app/src/androidTest/java/com/alibaba/weex/benchmark/BenchmarkTest.java
+++ 
b/android/playground/app/src/androidTest/java/com/alibaba/weex/benchmark/BenchmarkTest.java
@@ -68,9 +68,7 @@ public class BenchmarkTest {
   private static List<Long> firstScreenRenderTime = new LinkedList<>();
   private static List<Long> flingFrameSeconds = new LinkedList<>();
   private static List<Long> scrollFrameSeconds = new LinkedList<>();
-  private static final String DUMP_START = 
"Flags,IntendedVsync,Vsync,OldestInputEvent,NewestInputEvent,"
-                                           + 
"HandleInputStart,AnimationStart,PerformTraversalsStart,DrawStart,"
-                                           + 
"SyncQueued,SyncStart,IssueDrawCommandsStart,SwapBuffers,FrameCompleted,\n";
+  private static final String DUMP_START = "QueueBufferDuration,\n";
   private static final String DUMP_END = "---PROFILEDATA---";
   private static final String DUMP_COMMAND = "dumpsys gfxinfo com.alibaba.weex 
framestats reset";
 
@@ -195,7 +193,7 @@ public class BenchmarkTest {
 
   private long calcTime() {
     BenchmarkActivity benchmarkActivity = mActivityRule.getActivity();
-    benchmarkActivity.loadWeexPage();
+    benchmarkActivity.loadWeexPage("http://30.8.53.163:8080/complicated.js";);
     onView(withClassName(Matchers.is(WXRecyclerView.class.getName()))).perform
         (RecyclerViewActions.scrollToPosition(0));
     return 
benchmarkActivity.getWXInstance().getWXPerformance().screenRenderTime;

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/libs/armeabi/libweexjsc.so
----------------------------------------------------------------------
diff --git a/android/sdk/libs/armeabi/libweexjsc.so 
b/android/sdk/libs/armeabi/libweexjsc.so
index d3fb7e7..b08a455 100755
Binary files a/android/sdk/libs/armeabi/libweexjsc.so and 
b/android/sdk/libs/armeabi/libweexjsc.so differ

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/libs/armeabi/libweexjss.so
----------------------------------------------------------------------
diff --git a/android/sdk/libs/armeabi/libweexjss.so 
b/android/sdk/libs/armeabi/libweexjss.so
index c0236b6..13e5bc6 100755
Binary files a/android/sdk/libs/armeabi/libweexjss.so and 
b/android/sdk/libs/armeabi/libweexjss.so differ

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java 
b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
index 7e0da86..fcdcd0d 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
@@ -18,6 +18,8 @@
  */
 package com.taobao.weex;
 
+import static com.taobao.weex.http.WXHttpUtil.KEY_USER_AGENT;
+
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.Intent;
@@ -28,13 +30,14 @@ import android.net.Uri;
 import android.os.Message;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+import android.support.annotation.RestrictTo.Scope;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Menu;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ScrollView;
-
 import com.alibaba.fastjson.JSONObject;
 import com.taobao.weex.adapter.IDrawableLoader;
 import com.taobao.weex.adapter.IWXHttpAdapter;
@@ -68,6 +71,7 @@ import com.taobao.weex.ui.component.NestedContainer;
 import com.taobao.weex.ui.component.WXBasicComponentType;
 import com.taobao.weex.ui.component.WXComponent;
 import com.taobao.weex.ui.component.WXComponentFactory;
+import com.taobao.weex.ui.flat.FlatGUIContext;
 import com.taobao.weex.ui.view.WXScrollView;
 import com.taobao.weex.ui.view.WXScrollView.WXScrollViewListener;
 import com.taobao.weex.utils.Trace;
@@ -76,8 +80,6 @@ import com.taobao.weex.utils.WXJsonUtils;
 import com.taobao.weex.utils.WXLogUtils;
 import com.taobao.weex.utils.WXReflectionUtils;
 import com.taobao.weex.utils.WXViewUtils;
-import com.taobao.weex.WXSDKEngine;
-
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -86,9 +88,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
-import static com.taobao.weex.http.WXHttpUtil.KEY_USER_AGENT;
-
-
 /**
  * Each instance of WXSDKInstance represents an running weex instance.
  * It can be a pure weex view, or mixed with native view
@@ -120,6 +119,8 @@ public class WXSDKInstance implements 
IWXActivityStateListener,DomContext, View.
   private boolean mNeedReLoad = false;
   private static volatile int mViewPortWidth = 750;
   private int mInstanceViewPortWidth = 750;
+  private @NonNull
+  FlatGUIContext mFlatGUIContext =new FlatGUIContext();
 
   public long mRenderStartNanos;
   public int mExecJSTraceId = WXTracing.nextId();
@@ -200,6 +201,12 @@ public class WXSDKInstance implements 
IWXActivityStateListener,DomContext, View.
     enableLayerType = enable;
   }
 
+  @RestrictTo(Scope.LIBRARY)
+  public @NonNull
+  FlatGUIContext getFlatUIContext(){
+    return mFlatGUIContext;
+  }
+
   public boolean isNeedValidate() {
     return mNeedValidate;
   }
@@ -251,6 +258,7 @@ public class WXSDKInstance implements 
IWXActivityStateListener,DomContext, View.
   /**
    * For unittest only.
    */
+  @RestrictTo(Scope.TESTS)
   WXSDKInstance(Context context,String id) {
     mInstanceId = id;
     init(context);
@@ -606,21 +614,23 @@ public class WXSDKInstance implements 
IWXActivityStateListener,DomContext, View.
     return "";
   }
 
-  public void reloadPage() {
+  public void reloadPage(boolean reloadThis) {
+
     WXSDKEngine.reload();
 
-    // 可以发送广播吗?
-    if (mContext != null) {
-      Intent intent = new Intent();
-      intent.setAction(IWXDebugProxy.ACTION_INSTANCE_RELOAD);
-      intent.putExtra("url", mBundleUrl);
-      mContext.sendBroadcast(intent);
+    if (reloadThis) {
+      // 可以发送广播吗?
+      if (mContext != null)  {
+        Intent intent = new Intent();
+        intent.setAction(IWXDebugProxy.ACTION_INSTANCE_RELOAD);
+        intent.putExtra("url", mBundleUrl);
+        mContext.sendBroadcast(intent);
+      }
+      // mRendered = false;
+      //    destroy();
+      // renderInternal(mPackage, mTemplate, mOptions, mJsonInitData, mFlag);
+      // refreshInstance("{}");
     }
-    // mRendered = false;
-    //    destroy();
-    // renderInternal(mPackage, mTemplate, mOptions, mJsonInitData, mFlag);
-    // refreshInstance("{}");
-
   }
   /**
    * Refresh instance asynchronously.
@@ -1249,35 +1259,41 @@ public class WXSDKInstance implements 
IWXActivityStateListener,DomContext, View.
   }
 
   public synchronized void destroy() {
-    WXSDKManager.getInstance().destroyInstance(mInstanceId);
-    WXComponentFactory.removeComponentTypesByInstanceId(getInstanceId());
+    if(!isDestroy()) {
+      WXSDKManager.getInstance().destroyInstance(mInstanceId);
+      WXComponentFactory.removeComponentTypesByInstanceId(getInstanceId());
 
-    if(mGlobalEventReceiver!=null){
-      getContext().unregisterReceiver(mGlobalEventReceiver);
-      mGlobalEventReceiver=null;
-    }
-    if(mRootComp != null ) {
-      mRootComp.destroy();
-      destroyView(mRenderContainer);
-      mRenderContainer = null;
-      mRootComp = null;
-    }
+      if (mGlobalEventReceiver != null) {
+        getContext().unregisterReceiver(mGlobalEventReceiver);
+        mGlobalEventReceiver = null;
+      }
+      if (mRootComp != null) {
+        mRootComp.destroy();
+        destroyView(mRenderContainer);
+        mRootComp = null;
+      }
 
-    if(mGlobalEvents!=null){
-      mGlobalEvents.clear();
-    }
+      if (mGlobalEvents != null) {
+        mGlobalEvents.clear();
+      }
 
-    if(mComponentObserver != null){
+      if (mComponentObserver != null) {
         mComponentObserver = null;
-    }
+      }
 
-    mNestedInstanceInterceptor = null;
-    mUserTrackAdapter = null;
-    mScrollView = null;
-    mContext = null;
-    mRenderListener = null;
-    isDestroy = true;
-    mStatisticsListener = null;
+      getFlatUIContext().destroy();
+      mFlatGUIContext = null;
+
+      mWXScrollListeners = null;
+      mRenderContainer = null;
+      mNestedInstanceInterceptor = null;
+      mUserTrackAdapter = null;
+      mScrollView = null;
+      mContext = null;
+      mRenderListener = null;
+      isDestroy = true;
+      mStatisticsListener = null;
+    }
   }
 
   public boolean isDestroy(){
@@ -1484,7 +1500,7 @@ public class WXSDKInstance implements 
IWXActivityStateListener,DomContext, View.
    * Check whether the current module registered the event
    * @param eventName EventName register in weex
    * @param module Events occur in this Module
-   * @return  register->true
+   * @return  boolean true
    */
   public boolean checkModuleEventRegistered(String eventName,WXModule module) {
     if (module != null) {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/appfram/websocket/WebSocketCloseCodes.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/appfram/websocket/WebSocketCloseCodes.java
 
b/android/sdk/src/main/java/com/taobao/weex/appfram/websocket/WebSocketCloseCodes.java
index 6251399..0f742ae 100644
--- 
a/android/sdk/src/main/java/com/taobao/weex/appfram/websocket/WebSocketCloseCodes.java
+++ 
b/android/sdk/src/main/java/com/taobao/weex/appfram/websocket/WebSocketCloseCodes.java
@@ -20,7 +20,7 @@ package com.taobao.weex.appfram.websocket;
 
 /**
  * Created by moxun on 17/1/3.
- * @link {https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent}
+ * @see <a 
href="https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent";>CloseEvent</a>
  */
 
 public enum WebSocketCloseCodes {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java 
b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
index 89b2d3b..3b11387 100644
--- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
+++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
@@ -135,6 +135,9 @@ public class WXBridgeManager implements 
Callback,BactchExecutor {
   private static final int CRASHREINIT = 50;
   private static int reInitCount = 1;
 
+  private static String crashUrl = null;
+  private static long lastCrashTime = 0;
+
 
   /**
    * next tick tasks, can set priority
@@ -962,12 +965,15 @@ public class WXBridgeManager implements 
Callback,BactchExecutor {
         WXLogUtils.e("[WXBridgeManager] callReportCrashReloadPage exception: 
", e);
       }
       try {
+
           if (WXSDKManager.getInstance().getSDKInstance(instanceId) != null) {
-              // JSONObject domObject = JSON.parseObject(tasks);
+              boolean reloadThisInstance = shouReloadCurrentInstance(
+                      
WXSDKManager.getInstance().getSDKInstance(instanceId).getBundleUrl());
               WXDomModule domModule = getDomModule(instanceId);
-              Action action = Actions.getReloadPage(instanceId);
-              domModule.postAction((DOMAction)action, true);
+              Action action = Actions.getReloadPage(instanceId, 
reloadThisInstance);
+              domModule.postAction((DOMAction) action, true);
           }
+
       } catch (Exception e) {
           WXLogUtils.e("[WXBridgeManager] callReloadPage exception: ", e);
           commitJSBridgeAlarmMonitor(instanceId, 
WXErrorCode.WX_ERR_RELOAD_PAGE,"[WXBridgeManager] callReloadPage exception 
"+e.getCause());
@@ -975,6 +981,19 @@ public class WXBridgeManager implements 
Callback,BactchExecutor {
       return IWXBridge.INSTANCE_RENDERING_ERROR;
   }
 
+  public boolean shouReloadCurrentInstance(String aUrl) {
+    long time = System.currentTimeMillis();
+    if (crashUrl == null ||
+            (crashUrl != null && !crashUrl.equals(aUrl)) ||
+            ((time - lastCrashTime) > 10000)) {
+      crashUrl = aUrl;
+      lastCrashTime = time;
+      return true;
+    }
+    lastCrashTime = time;
+    return false;
+  }
+
   public void callReportCrash(String crashFile, final String instanceId, final 
String url) {
       // statistic weexjsc process crash
       Date date = new Date();
@@ -1809,7 +1828,7 @@ public class WXBridgeManager implements 
Callback,BactchExecutor {
           if (reInitCount > 1 && !instance.isNeedReLoad()) {
             // JSONObject domObject = JSON.parseObject(tasks);
             WXDomModule domModule = getDomModule(instanceId);
-            Action action = Actions.getReloadPage(instanceId);
+            Action action = Actions.getReloadPage(instanceId, true);
             domModule.postAction((DOMAction)action, true);
             instance.setNeedLoad(true);
             return;

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/common/Constants.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/common/Constants.java 
b/android/sdk/src/main/java/com/taobao/weex/common/Constants.java
index 8c87662..917fbcd 100644
--- a/android/sdk/src/main/java/com/taobao/weex/common/Constants.java
+++ b/android/sdk/src/main/java/com/taobao/weex/common/Constants.java
@@ -182,6 +182,8 @@ public class Constants {
     String ARIA_LABEL = "ariaLabel";
     String ARIA_HIDDEN = "ariaHidden";
     String UNDEFINED = "undefined";
+
+    String FLAT = "flat";
   }
 
   public interface Value {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/dom/ImmutableDomObject.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/dom/ImmutableDomObject.java 
b/android/sdk/src/main/java/com/taobao/weex/dom/ImmutableDomObject.java
index 55439c3..c19ca59 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/ImmutableDomObject.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/ImmutableDomObject.java
@@ -19,11 +19,8 @@
 package com.taobao.weex.dom;
 
 import android.support.annotation.NonNull;
-
 import com.taobao.weex.dom.flex.Spacing;
 
-import static com.taobao.weex.dom.WXDomObject.DESTROYED;
-
 /**
  * Created by sospartan on 25/10/2016.
  */
@@ -33,8 +30,26 @@ public interface ImmutableDomObject {
   @NonNull Spacing getMargin();
   float getLayoutWidth();
   float getLayoutHeight();
+
+  /**
+   * Use {@link #getCSSLayoutLeft()} ()} instead
+   */
+  @Deprecated
   float getLayoutX();
+
+  /**
+   * Use {@link #getCSSLayoutTop()} instead
+   */
+  @Deprecated
   float getLayoutY();
+
+  public float getCSSLayoutTop();
+
+  public float getCSSLayoutBottom();
+
+  public float getCSSLayoutLeft();
+
+  public float getCSSLayoutRight();
   boolean isFixed();
   @NonNull WXStyle getStyles();
   @NonNull WXEvent getEvents();

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java 
b/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java
index 01c25d2..6dc444a 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java
@@ -346,23 +346,6 @@ public class WXStyle implements Map<String, 
Object>,Cloneable {
     return WXUtils.getFloatByViewport(get(Constants.Name.BORDER_WIDTH), 
viewport);
   }
 
-  public float getBorderRightWidth() {
-    return getBorderWidth(Constants.Name.BORDER_RIGHT_WIDTH);
-  }
-
-  public float getBorderTopWidth() {
-    return getBorderWidth(Constants.Name.BORDER_TOP_WIDTH);
-  }
-
-  public float getBorderBottomWidth() {
-    return getBorderWidth(Constants.Name.BORDER_BOTTOM_WIDTH);
-  }
-
-  public float getBorderLeftWidth() {
-    return getBorderWidth(Constants.Name.BORDER_LEFT_WIDTH);
-  }
-
-
   public float getBorderRightWidth(int viewport) {
     return getBorderWidth(Constants.Name.BORDER_RIGHT_WIDTH, viewport);
   }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java 
b/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java
index 06084a9..8adb991 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java
@@ -337,12 +337,19 @@ public class WXTextDomObject extends WXDomObject {
       int desired, @Nullable TextUtils.TruncateAt truncateAt) {
     Spanned ret = new SpannedString("");
     if (!TextUtils.isEmpty(source) && source.length() > 0) {
-      StaticLayout layout;
       if (truncateAt != null) {
         source.append(ELLIPSIS);
       }
+
+      StaticLayout layout;
+      int startOffset;
+
       while (source.length() > 1) {
-        source.delete(source.length() - 2, source.length() - 1);
+        startOffset = source.length() -1;
+        if (truncateAt != null) {
+          startOffset -= 1;
+        }
+        source.delete(startOffset, startOffset+1);
         layout = new StaticLayout(source, paint, desired, 
Layout.Alignment.ALIGN_NORMAL, 1, 0, true);
         if (layout.getLineCount() <= 1) {
           ret = source;

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java 
b/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java
index 6e87c68..779b4d6 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java
@@ -225,7 +225,7 @@ public class Actions {
     return new ExecutableRenderAction(runnable);
   }
 
-  public static DOMAction getReloadPage(String instanceId) {
-    return new ReloadPageAction(instanceId);
+  public static DOMAction getReloadPage(String instanceId, boolean relaod) {
+    return new ReloadPageAction(instanceId, relaod);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java 
b/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java
index 8c4df7d..cd51668 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java
@@ -50,11 +50,13 @@ class CreateBodyAction extends AbstractAddElementAction {
 
   @Override
   public void executeDom(DOMActionContext context) {
-    if (WXEnvironment.isApkDebugable()) {
-      WXTracing.TraceEvent execJsEndEvent = 
WXTracing.newEvent("executeBundleJS", context.getInstanceId(), -1);
-      execJsEndEvent.traceId = context.getInstance().mExecJSTraceId;
-      execJsEndEvent.ph = "E";
-      execJsEndEvent.submit();
+    if (WXTracing.isAvailable()) {
+      if (context != null && context.getInstance() != null) {
+        WXTracing.TraceEvent execJsEndEvent = 
WXTracing.newEvent("executeBundleJS", context.getInstanceId(), -1);
+        execJsEndEvent.traceId = context.getInstance().mExecJSTraceId;
+        execJsEndEvent.ph = "E";
+        execJsEndEvent.submit();
+      }
     }
     addDomInternal(context, mData);
   }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/dom/action/ReloadPageAction.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/dom/action/ReloadPageAction.java 
b/android/sdk/src/main/java/com/taobao/weex/dom/action/ReloadPageAction.java
index aaf67e7..791a5f2 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/ReloadPageAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/ReloadPageAction.java
@@ -36,9 +36,11 @@ import com.taobao.weex.dom.RenderActionContext;
 final class ReloadPageAction implements DOMAction, RenderAction {
   private final String TAG = "ReloadPageAction";
   private String mInstanceId;
+  private boolean mReloadThis;
 
-  ReloadPageAction(String instanceId) {
+  ReloadPageAction(String instanceId, boolean reloadThis) {
     mInstanceId = instanceId;
+    mReloadThis = reloadThis;
   }
 
   @Override
@@ -51,7 +53,7 @@ final class ReloadPageAction implements DOMAction, 
RenderAction {
     WXSDKInstance instance = context.getInstance();
     if (instance != null) {
          // instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, 
WXErrorCode.WX_SUCCESS);
-         instance.reloadPage();
+         instance.reloadPage(mReloadThis);
     } else {
       Log.e(TAG, "ReloadPageAction executeDom reloadPage instance is null");
     }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
index 88ffece..fd01aa5 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
@@ -22,6 +22,7 @@ import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Color;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.Shader;
@@ -34,13 +35,15 @@ import android.support.annotation.CheckResult;
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+import android.support.annotation.RestrictTo.Scope;
 import android.support.v4.view.ViewCompat;
 import android.text.TextUtils;
 import android.view.Menu;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewGroup.MarginLayoutParams;
 import android.widget.FrameLayout;
-
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.taobao.weex.ComponentObserver;
@@ -66,6 +69,11 @@ import com.taobao.weex.ui.animation.WXAnimationModule;
 import com.taobao.weex.ui.component.pesudo.OnActivePseudoListner;
 import com.taobao.weex.ui.component.pesudo.PesudoStatus;
 import com.taobao.weex.ui.component.pesudo.TouchActivePseudoListener;
+import com.taobao.weex.ui.flat.FlatComponent;
+import com.taobao.weex.ui.flat.FlatGUIContext;
+import com.taobao.weex.ui.flat.WidgetContainer;
+import com.taobao.weex.ui.flat.widget.AndroidViewWidget;
+import com.taobao.weex.ui.flat.widget.Widget;
 import com.taobao.weex.ui.view.border.BorderDrawable;
 import com.taobao.weex.ui.view.gesture.WXGesture;
 import com.taobao.weex.ui.view.gesture.WXGestureObservable;
@@ -77,7 +85,6 @@ import com.taobao.weex.utils.WXReflectionUtils;
 import com.taobao.weex.utils.WXResourceUtils;
 import com.taobao.weex.utils.WXUtils;
 import com.taobao.weex.utils.WXViewUtils;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -143,6 +150,12 @@ public abstract class  WXComponent<T extends View> 
implements IWXObject, IWXActi
     this.mAnimationHolder = holder;
   }
 
+  //This method will be removed once flatGUI is completed.
+  @RestrictTo(Scope.LIBRARY)
+  public boolean isFlatUIEnabled(){
+    return mParent != null && mParent.isFlatUIEnabled();
+  }
+
   private OnClickListener mClickEventListener = new OnClickListener() {
     @Override
     public void onHostViewClick() {
@@ -394,15 +407,17 @@ public abstract class  WXComponent<T extends View> 
implements IWXObject, IWXActi
 
   protected BorderDrawable getOrCreateBorder() {
     if (mBackgroundDrawable == null) {
-      Drawable backgroundDrawable = mHost.getBackground();
-      WXViewUtils.setBackGround(mHost,null);
       mBackgroundDrawable = new BorderDrawable();
-      if (backgroundDrawable == null) {
-        WXViewUtils.setBackGround(mHost,mBackgroundDrawable);
-      } else {
-        //TODO Not strictly clip according to background-clip:border-box
-        WXViewUtils.setBackGround(mHost,new LayerDrawable(new Drawable[]{
-            mBackgroundDrawable,backgroundDrawable}));
+      if (mHost != null) {
+        Drawable backgroundDrawable = mHost.getBackground();
+        WXViewUtils.setBackGround(mHost, null);
+        if (backgroundDrawable == null) {
+          WXViewUtils.setBackGround(mHost, mBackgroundDrawable);
+        } else {
+          //TODO Not strictly clip according to background-clip:border-box
+          WXViewUtils.setBackGround(mHost, new LayerDrawable(new Drawable[]{
+              mBackgroundDrawable, backgroundDrawable}));
+        }
       }
     }
     return mBackgroundDrawable;
@@ -433,6 +448,9 @@ public abstract class  WXComponent<T extends View> 
implements IWXObject, IWXActi
                          parentBorder.get(Spacing.TOP)) + siblingOffset;
     int realRight = (int) margin.get(Spacing.RIGHT);
     int realBottom = (int) margin.get(Spacing.BOTTOM);
+    Point rawOffset = new Point(
+        (int) mDomObj.getCSSLayoutLeft(),
+        (int) mDomObj.getCSSLayoutTop());
 
     if (mPreRealWidth == realWidth && mPreRealHeight == realHeight && 
mPreRealLeft == realLeft && mPreRealTop == realTop) {
       return;
@@ -446,32 +464,79 @@ public abstract class  WXComponent<T extends View> 
implements IWXObject, IWXActi
       mInstance.firstScreenRenderFinished();
     }
 
-    if (mHost == null) {
-      return;
-    }
 
     MeasureOutput measureOutput = measure(realWidth, realHeight);
     realWidth = measureOutput.width;
     realHeight = measureOutput.height;
 
-    //fixed style
-    if (mDomObj.isFixed()) {
-      
setFixedHostLayoutParams(mHost,realWidth,realHeight,realLeft,realRight,realTop,realBottom);
-    }else {
-      setHostLayoutParams(mHost, realWidth, realHeight, realLeft, realRight, 
realTop, realBottom);
-    }
-
-    mPreRealWidth = realWidth;
-    mPreRealHeight = realHeight;
-    mPreRealLeft = realLeft;
-    mPreRealTop = realTop;
-
-    onFinishLayout();
+    setComponentLayoutParams(realWidth, realHeight, realLeft, realTop, 
realRight, realBottom, rawOffset);
   }
 
+  private void setComponentLayoutParams(int realWidth, int realHeight, int 
realLeft, int realTop,
+      int realRight, int realBottom, Point rawOffset) {
+    FlatGUIContext UIImp = getInstance().getFlatUIContext();
+    WidgetContainer ancestor;
+    Widget widget;
+    if ((ancestor = UIImp.getFlatComponentAncestor(this)) != null) {
+      if (this instanceof FlatComponent && !((FlatComponent) 
this).promoteToView(true)) {
+        widget = ((FlatComponent) this).getOrCreateFlatWidget();
+      } else {
+        widget = UIImp.getAndroidViewWidget(this);
+      }
+      setWidgetParams(widget, UIImp, rawOffset, realWidth, realHeight, 
realLeft, realRight, realTop,
+          realBottom);
+    } else if (mHost != null) {
+      if (mDomObj.isFixed()) {
+        setFixedHostLayoutParams(mHost, realWidth, realHeight, realLeft, 
realRight, realTop,
+            realBottom);
+      } else {
+        setHostLayoutParams(mHost, realWidth, realHeight, realLeft, realRight, 
realTop, realBottom);
+      }
+      mPreRealWidth = realWidth;
+      mPreRealHeight = realHeight;
+      mPreRealLeft = realLeft;
+      mPreRealTop = realTop;
+      onFinishLayout();
+    }
+  }
+
+  private void setWidgetParams(Widget widget, FlatGUIContext UIImp, Point 
rawoffset,
+      int width, int height, int left, int right, int top, int bottom) {
+    Point childOffset = new Point();
+    if (mParent != null) {
+      if (mParent instanceof FlatComponent &&
+          UIImp.getFlatComponentAncestor(mParent) != null &&
+          UIImp.getAndroidViewWidget(mParent) == null) {
+        childOffset.set(rawoffset.x, rawoffset.y);
+      }
+      else{
+        childOffset.set(left, top);
+      }
 
-  public int getLayoutTopOffsetForSibling(){
-    return 0;
+      if (mParent instanceof FlatComponent &&
+          UIImp.getFlatComponentAncestor(mParent) != null &&
+          UIImp.getAndroidViewWidget(mParent) == null) {
+        Point parentLayoutOffset = ((FlatComponent) 
mParent).getOrCreateFlatWidget().getLocInFlatContainer();
+        childOffset.offset(parentLayoutOffset.x, parentLayoutOffset.y);
+      }
+      ViewGroup.LayoutParams lp = mParent
+          .getChildLayoutParams(this, mHost, width, height, left, right, top, 
bottom);
+      if (lp instanceof MarginLayoutParams) {
+        width = lp.width;
+        height = lp.height;
+        left = ((MarginLayoutParams) lp).leftMargin;
+        right = ((MarginLayoutParams) lp).rightMargin;
+        top = ((MarginLayoutParams) lp).topMargin;
+        bottom = ((MarginLayoutParams) lp).bottomMargin;
+      }
+    }
+    widget.setLayout(width, height, left, right, top, bottom, childOffset);
+
+    if (widget instanceof AndroidViewWidget && ((AndroidViewWidget) 
widget).getView()!=null) {
+      //TODO generic method if ever possible
+      setHostLayoutParams((T) ((AndroidViewWidget) widget).getView(),
+          width, height, childOffset.x, right, childOffset.y, bottom);
+    }
   }
 
   protected void setHostLayoutParams(T host, int width, int height, int left, 
int right, int top, int bottom){
@@ -514,6 +579,10 @@ public abstract class  WXComponent<T extends View> 
implements IWXObject, IWXActi
     }
   }
 
+  public int getLayoutTopOffsetForSibling(){
+    return 0;
+  }
+
   public float getLayoutWidth(){
     float w = 0f;
     if (mDomObj != null) {
@@ -538,10 +607,11 @@ public abstract class  WXComponent<T extends View> 
implements IWXObject, IWXActi
     int right = (int) (padding.get(Spacing.RIGHT) + border.get(Spacing.RIGHT));
     int bottom = (int) (padding.get(Spacing.BOTTOM) + 
border.get(Spacing.BOTTOM));
 
-    if (mHost == null) {
-      return;
+    if (this instanceof FlatComponent && !((FlatComponent) 
this).promoteToView(true)) {
+      ((FlatComponent) this).getOrCreateFlatWidget().setContentBox(left, top, 
right, bottom);
+    } else if (mHost != null) {
+      mHost.setPadding(left, top, right, bottom);
     }
-    mHost.setPadding(left, top, right, bottom);
   }
 
   private void addEvents() {
@@ -611,6 +681,13 @@ public abstract class  WXComponent<T extends View> 
implements IWXObject, IWXActi
       }
     }
     readyToRender();
+    if (this instanceof FlatComponent && mBackgroundDrawable != null) {
+      FlatComponent flatComponent = (FlatComponent) this;
+      if (!flatComponent.promoteToView(true) && !(flatComponent
+          .getOrCreateFlatWidget() instanceof AndroidViewWidget)) {
+        
flatComponent.getOrCreateFlatWidget().setBackgroundAndBorder(mBackgroundDrawable);
+      }
+    }
   }
 
   /**
@@ -645,7 +722,7 @@ public abstract class  WXComponent<T extends View> 
implements IWXObject, IWXActi
         return true;
       case Constants.Name.BACKGROUND_IMAGE:
         String bgImage = WXUtils.getString(param, null);
-        if (bgImage != null && mHost != null) {
+        if (bgImage != null) {
           setBackgroundImage(bgImage);
         }
         return true;
@@ -1155,7 +1232,7 @@ public abstract class  WXComponent<T extends View> 
implements IWXObject, IWXActi
   }
 
   public void setBackgroundColor(String color) {
-    if (!TextUtils.isEmpty(color)&& mHost!=null) {
+    if (!TextUtils.isEmpty(color)) {
       int colorInt = WXResourceUtils.getColor(color);
       if (!(colorInt == Color.TRANSPARENT && mBackgroundDrawable == null)){
           getOrCreateBorder().setColor(colorInt);

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/WXDiv.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXDiv.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXDiv.java
index 2772cc6..b9b97e1 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXDiv.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXDiv.java
@@ -20,41 +20,99 @@ package com.taobao.weex.ui.component;
 
 import android.content.Context;
 import android.support.annotation.NonNull;
-
 import com.taobao.weex.WXSDKInstance;
 import com.taobao.weex.annotation.Component;
 import com.taobao.weex.dom.WXDomObject;
 import com.taobao.weex.ui.ComponentCreator;
+import com.taobao.weex.ui.flat.FlatComponent;
+import com.taobao.weex.ui.flat.WidgetContainer;
+import com.taobao.weex.ui.flat.widget.WidgetGroup;
 import com.taobao.weex.ui.view.WXFrameLayout;
-
 import java.lang.reflect.InvocationTargetException;
 
 /**
  * div component
  */
 @Component(lazyload = false)
-public class WXDiv extends WXVContainer<WXFrameLayout> {
+public class WXDiv extends WidgetContainer<WXFrameLayout> implements 
FlatComponent<WidgetGroup> {
+
+  private WidgetGroup mWidgetGroup;
 
   public static class Ceator implements ComponentCreator {
-    public WXComponent createInstance(WXSDKInstance instance, WXDomObject 
node, WXVContainer parent) throws IllegalAccessException, 
InvocationTargetException, InstantiationException {
-      return new WXDiv(instance,node,parent);
+
+    public WXComponent createInstance(WXSDKInstance instance, WXDomObject 
node, WXVContainer parent)
+        throws IllegalAccessException, InvocationTargetException, 
InstantiationException {
+      return new WXDiv(instance, node, parent);
     }
   }
 
   @Deprecated
-  public WXDiv(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, 
String instanceId, boolean isLazy) {
-    this(instance,dom,parent);
+  public WXDiv(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, 
String instanceId,
+      boolean isLazy) {
+    this(instance, dom, parent);
   }
 
   public WXDiv(WXSDKInstance instance, WXDomObject node, WXVContainer parent) {
     super(instance, node, parent);
   }
 
+
   @Override
   protected WXFrameLayout initComponentHostView(@NonNull Context context) {
-    WXFrameLayout frameLayout =new WXFrameLayout(context);
+    WXFrameLayout frameLayout = new WXFrameLayout(context);
     frameLayout.holdComponent(this);
     return frameLayout;
   }
 
+  @Override
+  public boolean promoteToView(boolean checkAncestor) {
+    return !intendToBeFlatContainer() ||
+        getInstance().getFlatUIContext().promoteToView(this, checkAncestor, 
WXDiv.class);
+  }
+
+  /**
+   * Create View tree there. Either this method or {@link #createViewImpl()} 
get called.
+   * If this object will be promoted to view, then getOrCreateFlatWidget() 
should never be called.
+   */
+  @Override
+  @NonNull
+  public WidgetGroup getOrCreateFlatWidget() {
+    if (mWidgetGroup == null) {
+      mWidgetGroup = new WidgetGroup(getInstance().getFlatUIContext());
+      for (int i = 0; i < getChildCount(); i++) {
+        createChildViewAt(i);
+      }
+      mountFlatGUI();
+    }
+    return mWidgetGroup;
+  }
+
+  @Override
+  protected void mountFlatGUI() {
+    if (promoteToView(true)) {
+      if(getHostView()!=null) {
+        getHostView().mountFlatGUI(widgets);
+      }
+    } else {
+      mWidgetGroup.replaceAll(widgets);
+    }
+  }
+
+  @Override
+  public void unmountFlatGUI() {
+    if (getHostView() != null) {
+      getHostView().unmountFlatGUI();
+    }
+  }
+
+  @Override
+  public boolean intendToBeFlatContainer() {
+    return getInstance().getFlatUIContext().isFlatUIEnabled(this) && 
WXDiv.class.equals(getClass());
+  }
+
+  @Override
+  public boolean isVirtualComponent() {
+    return !promoteToView(true);
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/WXSlider.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXSlider.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXSlider.java
index 4ef51f3..1023e3e 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXSlider.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXSlider.java
@@ -29,7 +29,6 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.widget.FrameLayout;
-
 import com.taobao.weex.WXEnvironment;
 import com.taobao.weex.WXSDKInstance;
 import com.taobao.weex.WXSDKManager;
@@ -45,7 +44,6 @@ import com.taobao.weex.ui.view.gesture.WXGestureType;
 import com.taobao.weex.utils.WXLogUtils;
 import com.taobao.weex.utils.WXUtils;
 import com.taobao.weex.utils.WXViewUtils;
-
 import java.lang.ref.WeakReference;
 import java.lang.reflect.InvocationTargetException;
 import java.util.HashMap;
@@ -132,7 +130,7 @@ public class WXSlider extends WXVContainer<FrameLayout> {
    */
   @Override
   public LayoutParams getChildLayoutParams(WXComponent child,View childView, 
int width, int height, int left, int right, int top, int bottom) {
-    ViewGroup.LayoutParams lp = childView.getLayoutParams();
+    ViewGroup.LayoutParams lp = childView == null ? null : 
childView.getLayoutParams();
     if (lp == null) {
       lp = new FrameLayout.LayoutParams(width, height);
     } else {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/WXText.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXText.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXText.java
index aad2bf4..ea7b9ea 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXText.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXText.java
@@ -33,6 +33,8 @@ import com.taobao.weex.annotation.Component;
 import com.taobao.weex.common.Constants;
 import com.taobao.weex.dom.WXDomObject;
 import com.taobao.weex.ui.ComponentCreator;
+import com.taobao.weex.ui.flat.FlatComponent;
+import com.taobao.weex.ui.flat.widget.TextWidget;
 import com.taobao.weex.ui.view.WXTextView;
 import com.taobao.weex.utils.FontDO;
 import com.taobao.weex.utils.TypefaceUtil;
@@ -44,7 +46,9 @@ import java.lang.reflect.InvocationTargetException;
  * Text component
  */
 @Component(lazyload = false)
-public class WXText extends WXComponent<WXTextView> {
+public class WXText extends WXComponent<WXTextView> implements 
FlatComponent<TextWidget> {
+
+  private TextWidget mTextWidget;
 
   /**
    * The default text size
@@ -53,6 +57,25 @@ public class WXText extends WXComponent<WXTextView> {
   private BroadcastReceiver mTypefaceObserver;
   private String mFontFamily;
 
+  @Override
+  public boolean promoteToView(boolean checkAncestor) {
+    return getInstance().getFlatUIContext().promoteToView(this, checkAncestor, 
WXText.class);
+  }
+
+  @Override
+  @NonNull
+  public TextWidget getOrCreateFlatWidget() {
+    if (mTextWidget == null) {
+      mTextWidget = new TextWidget(getInstance().getFlatUIContext());
+    }
+    return mTextWidget;
+  }
+
+  @Override
+  public boolean isVirtualComponent() {
+    return !promoteToView(true);
+  }
+
   public static class Creator implements ComponentCreator {
 
     public WXComponent createInstance(WXSDKInstance instance, WXDomObject 
node, WXVContainer parent) throws IllegalAccessException, 
InvocationTargetException, InstantiationException {
@@ -79,11 +102,14 @@ public class WXText extends WXComponent<WXTextView> {
 
   @Override
   public void updateExtra(Object extra) {
-    if (extra instanceof Layout &&
-        getHostView() != null && !extra.equals(getHostView().getTextLayout())) 
{
+    if(extra instanceof Layout) {
       final Layout layout = (Layout) extra;
-      getHostView().setTextLayout(layout);
-      getHostView().invalidate();
+      if (!promoteToView(true)) {
+        getOrCreateFlatWidget().updateTextDrawable(layout);
+      } else if (getHostView() != null && 
!extra.equals(getHostView().getTextLayout())) {
+        getHostView().setTextLayout(layout);
+        getHostView().invalidate();
+      }
     }
   }
 
@@ -127,28 +153,6 @@ public class WXText extends WXComponent<WXTextView> {
     }
   }
 
-  /**
-   * Flush view no matter what height and width the {@link WXDomObject} 
specifies.
-   * @param extra must be a {@link Layout} object, otherwise, nothing will 
happen.
-   */
-  private void flushView(Object extra) {
-    if (extra instanceof Layout &&
-        getHostView() != null && !extra.equals(getHostView().getTextLayout())) 
{
-      final Layout layout = (Layout) extra;
-      /**The following if block change the height of the width of the textView.
-       * other part of the code is the same to updateExtra
-       */
-      ViewGroup.LayoutParams layoutParams = getHostView().getLayoutParams();
-      if (layoutParams != null) {
-        layoutParams.height = layout.getHeight();
-        layoutParams.width = layout.getWidth();
-        getHostView().setLayoutParams(layoutParams);
-      }
-      getHostView().setTextLayout(layout);
-      getHostView().invalidate();
-    }
-  }
-
   @Override
   protected Object convertEmptyProperty(String propName, Object originalValue) 
{
     switch (propName) {
@@ -161,6 +165,13 @@ public class WXText extends WXComponent<WXTextView> {
   }
 
   @Override
+  protected void createViewImpl() {
+    if(promoteToView(true)) {
+      super.createViewImpl();
+    }
+  }
+
+  @Override
   public void destroy() {
     super.destroy();
     if (WXEnvironment.getApplication() != null && mTypefaceObserver != null) {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java
index f769c2a..43b45a7 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java
@@ -19,15 +19,14 @@
 package com.taobao.weex.ui.component;
 
 import android.content.Intent;
+import android.util.Pair;
 import android.support.annotation.Nullable;
 import android.view.Menu;
 import android.view.View;
 import android.view.ViewGroup;
-
 import com.taobao.weex.WXSDKInstance;
 import com.taobao.weex.common.Constants;
 import com.taobao.weex.dom.WXDomObject;
-
 import java.util.ArrayList;
 
 /**
@@ -115,7 +114,11 @@ public abstract class WXVContainer<T extends ViewGroup> 
extends WXComponent<T> {
    *
    */
   public ViewGroup.LayoutParams getChildLayoutParams(WXComponent child,View 
childView, int width, int height, int left, int right, int top, int bottom){
-    ViewGroup.LayoutParams lp = childView.getLayoutParams();
+    ViewGroup.LayoutParams lp = null;
+    if (childView != null) {
+      lp = childView.getLayoutParams();
+    }
+
     if(lp == null) {
       lp = new ViewGroup.LayoutParams(width,height);
     }else{
@@ -228,6 +231,11 @@ public abstract class WXVContainer<T extends ViewGroup> 
extends WXComponent<T> {
     return original;
   }
 
+  /**
+   * Use {@link #getChildCount()} instead
+   * @return
+   */
+  @Deprecated
   public int childCount() {
     return mChildren == null ? 0 : mChildren.size();
   }
@@ -242,7 +250,7 @@ public abstract class WXVContainer<T extends ViewGroup> 
extends WXComponent<T> {
   }
 
   public int getChildCount() {
-    return mChildren.size();
+    return childCount();
   }
 
   public void addChild(WXComponent child) {
@@ -268,21 +276,31 @@ public abstract class WXVContainer<T extends ViewGroup> 
extends WXComponent<T> {
     return mChildren.indexOf(comp);
   }
 
-  public void createChildViewAt(int index){
+  public void createChildViewAt(int index) {
     long startNanos = System.nanoTime();
+    Pair<WXComponent, Integer> ret = rearrangeIndexAndGetChild(index);
+    if (ret.first != null) {
+      WXComponent child = ret.first;
+      child.createView();
+      if (!child.isVirtualComponent()) {
+        addSubView(child.getHostView(), ret.second);
+      }
+    }
+    mTraceInfo.uiThreadNanos += (System.nanoTime() - startNanos);
+  }
+
+  protected Pair<WXComponent, Integer> rearrangeIndexAndGetChild(int index){
     int indexToCreate = index;
     if(indexToCreate < 0){
       indexToCreate = childCount()-1;
-      if(indexToCreate < 0 ){
-        return;
-      }
     }
-    WXComponent child = getChild(indexToCreate);
-    child.createView();
-    if(!child.isVirtualComponent()){
-      addSubView(child.getHostView(),indexToCreate);
+
+    if (indexToCreate<0){
+      return new Pair<>(null, indexToCreate);
+    }
+    else {
+      return new Pair<>(getChild(indexToCreate), indexToCreate);
     }
-    mTraceInfo.uiThreadNanos += (System.nanoTime() - startNanos);
   }
 
   protected void addSubView(View child, int index) {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java
index 3095c04..6ba985f 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java
@@ -19,23 +19,31 @@
 package com.taobao.weex.ui.component.list;
 
 import android.content.Context;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
+import android.support.annotation.RestrictTo.Scope;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
-
 import com.taobao.weex.WXSDKInstance;
 import com.taobao.weex.annotation.Component;
+import com.taobao.weex.common.Constants.Name;
+import com.taobao.weex.dom.WXAttr;
 import com.taobao.weex.dom.WXDomObject;
 import com.taobao.weex.ui.component.WXVContainer;
+import com.taobao.weex.ui.flat.WidgetContainer;
 import com.taobao.weex.ui.view.WXFrameLayout;
+import com.taobao.weex.utils.WXLogUtils;
+import com.taobao.weex.utils.WXUtils;
 
 /**
  * Root component for components in {@link WXListComponent}
  */
 @Component(lazyload = false)
 
-public class WXCell extends WXVContainer<WXFrameLayout> {
+public class WXCell extends WidgetContainer<WXFrameLayout> {
 
     private int mLastLocationY = 0;
     private ViewGroup mRealView;
@@ -45,15 +53,26 @@ public class WXCell extends WXVContainer<WXFrameLayout> {
 
     /** used in list sticky detect **/
     private int mScrollPositon = -1;
-
+    private boolean mFlatUIEnabled = false;
 
     @Deprecated
     public WXCell(WXSDKInstance instance, WXDomObject dom, WXVContainer 
parent, String instanceId, boolean isLazy) {
-        this(instance,dom,parent,isLazy);
+        super(instance, dom, parent);
     }
 
     public WXCell(WXSDKInstance instance, WXDomObject dom, WXVContainer 
parent, boolean isLazy) {
-        super(instance, dom, parent,true );
+        super(instance, dom, parent);
+        if(Build.VERSION.SDK_INT< VERSION_CODES.LOLLIPOP) {
+            try {
+                //TODO a WTF is necessary if anyone try to change the flat 
flag during update attrs.
+                WXAttr attr = getDomObject().getAttrs();
+                if (attr.containsKey(Name.FLAT)) {
+                    mFlatUIEnabled = WXUtils.getBoolean(attr.get(Name.FLAT), 
false);
+                }
+            } catch (NullPointerException e) {
+                WXLogUtils.e("Cell", WXLogUtils.getStackTrace(e));
+            }
+        }
     }
 
     @Override
@@ -65,6 +84,12 @@ public class WXCell extends WXVContainer<WXFrameLayout> {
         mLazy = lazy;
     }
 
+    @Override
+    @RestrictTo(Scope.LIBRARY)
+    public boolean isFlatUIEnabled() {
+        return mFlatUIEnabled;
+    }
+
     /**
      * If Cell is Sticky, need wraped FrameLayout
      */
@@ -74,10 +99,17 @@ public class WXCell extends WXVContainer<WXFrameLayout> {
             WXFrameLayout view = new WXFrameLayout(context);
             mRealView = new WXFrameLayout(context);
             view.addView(mRealView);
+            //TODO Maybe there is a better solution for hardware-acceleration 
view's display list.
+            if (isFlatUIEnabled()) {
+                view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+            }
             return view;
         } else {
             WXFrameLayout view = new WXFrameLayout(context);
             mRealView = view;
+            if (isFlatUIEnabled()) {
+                view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+            }
             return view;
         }
     }
@@ -127,4 +159,23 @@ public class WXCell extends WXVContainer<WXFrameLayout> {
         mHeadView.setTranslationX(0);
         mHeadView.setTranslationY(0);
     }
+
+    @Override
+    protected void mountFlatGUI() {
+      if(getHostView()!=null) {
+        getHostView().mountFlatGUI(widgets);
+      }
+    }
+
+    @Override
+    public void unmountFlatGUI() {
+        if (getHostView() != null) {
+            getHostView().unmountFlatGUI();
+        }
+    }
+
+    @Override
+    public boolean intendToBeFlatContainer() {
+        return getInstance().getFlatUIContext().isFlatUIEnabled(this) && 
WXCell.class.equals(getClass()) && !isSticky();
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXListComponent.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXListComponent.java
 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXListComponent.java
index ab53f78..c5ef8b5 100644
--- 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXListComponent.java
+++ 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXListComponent.java
@@ -19,6 +19,7 @@
 package com.taobao.weex.ui.component.list;
 
 import android.content.Context;
+import android.util.Pair;
 
 import com.taobao.weex.WXSDKInstance;
 import com.taobao.weex.annotation.Component;
@@ -187,35 +188,31 @@ public class WXListComponent extends 
BasicListComponent<BounceRecyclerView> {
 
   @Override
   public void createChildViewAt(int index) {
-    int indexToCreate = index;
-    if (indexToCreate < 0) {
-      indexToCreate = childCount() - 1;
-      if (indexToCreate < 0) {
-        return;
-      }
-    }
-    final WXComponent child = getChild(indexToCreate);
-    if (child instanceof WXBaseRefresh) {
-      child.createView();
-      if (child instanceof WXRefresh) {
-        getHostView().setOnRefreshListener((WXRefresh) child);
-        getHostView().postDelayed(new Runnable() {
-          @Override
-          public void run() {
-            getHostView().setHeaderView(child);
-          }
-        }, 100);
-      } else if (child instanceof WXLoading) {
-        getHostView().setOnLoadingListener((WXLoading) child);
-        getHostView().postDelayed(new Runnable() {
-          @Override
-          public void run() {
-            getHostView().setFooterView(child);
-          }
-        }, 100);
+    Pair<WXComponent, Integer> ret = rearrangeIndexAndGetChild(index);
+    if(ret.first != null) {
+      final WXComponent child = getChild(ret.second);
+      if (child instanceof WXBaseRefresh) {
+        child.createView();
+        if (child instanceof WXRefresh) {
+          getHostView().setOnRefreshListener((WXRefresh) child);
+          getHostView().postDelayed(new Runnable() {
+            @Override
+            public void run() {
+              getHostView().setHeaderView(child);
+            }
+          }, 100);
+        } else if (child instanceof WXLoading) {
+          getHostView().setOnLoadingListener((WXLoading) child);
+          getHostView().postDelayed(new Runnable() {
+            @Override
+            public void run() {
+              getHostView().setFooterView(child);
+            }
+          }, 100);
+        }
+      } else {
+        super.createChildViewAt(ret.second);
       }
-    } else {
-      super.createChildViewAt(indexToCreate);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatComponent.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatComponent.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatComponent.java
new file mode 100644
index 0000000..2c0cc46
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatComponent.java
@@ -0,0 +1,33 @@
+/**
+ * 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.flat;
+
+
+import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
+import android.support.annotation.RestrictTo.Scope;
+import com.taobao.weex.ui.flat.widget.Widget;
+
+@RestrictTo(Scope.LIBRARY)
+public interface FlatComponent<T extends Widget> {
+
+  boolean promoteToView(boolean checkAncestor);
+
+  @NonNull T getOrCreateFlatWidget();
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatGUIContext.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatGUIContext.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatGUIContext.java
new file mode 100644
index 0000000..4004bc8
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatGUIContext.java
@@ -0,0 +1,146 @@
+/**
+ * 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.flat;
+
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+import android.support.annotation.RestrictTo.Scope;
+import android.support.v4.util.ArrayMap;
+import android.text.TextUtils;
+import android.view.View;
+import com.taobao.weex.common.Constants.Name;
+import com.taobao.weex.common.Destroyable;
+import com.taobao.weex.dom.ImmutableDomObject;
+import com.taobao.weex.dom.WXAttr;
+import com.taobao.weex.dom.WXDomObject;
+import com.taobao.weex.dom.WXStyle;
+import com.taobao.weex.ui.component.WXComponent;
+import com.taobao.weex.ui.flat.widget.AndroidViewWidget;
+import com.taobao.weex.ui.flat.widget.Widget;
+import java.util.Map;
+import java.util.Map.Entry;
+
+//TODO The constructor of FlatGUIContext should have a flag decide whether to 
enable flagGUI.
+
+@RestrictTo(Scope.LIBRARY)
+public class FlatGUIContext implements Destroyable{
+
+  private Map<WXComponent, WidgetContainer> mWidgetRegistry = new ArrayMap<>();
+  private Map<WXComponent, AndroidViewWidget> mViewWidgetRegistry = new 
ArrayMap<>();
+  private Map<Widget, WXComponent> widgetToComponent = new ArrayMap<>();
+
+  public boolean isFlatUIEnabled(WXComponent component) {
+    return component.isFlatUIEnabled();
+  }
+
+  public void register(@NonNull WXComponent descendant, @NonNull 
WidgetContainer ancestor) {
+    if (!(ancestor instanceof FlatComponent) ||
+        ((FlatComponent) ancestor).promoteToView(true)) {
+      mWidgetRegistry.put(descendant, ancestor);
+    }
+  }
+
+  public void register(@NonNull WXComponent component, @NonNull 
AndroidViewWidget viewWidget){
+    mViewWidgetRegistry.put(component, viewWidget);
+  }
+
+  public void register(@NonNull Widget widget, @NonNull WXComponent component){
+    widgetToComponent.put(widget, component);
+  }
+
+  public
+  @Nullable
+  WidgetContainer getFlatComponentAncestor(@NonNull WXComponent flatWidget) {
+    return mWidgetRegistry.get(flatWidget);
+  }
+
+  public
+  @Nullable
+  AndroidViewWidget getAndroidViewWidget(@NonNull WXComponent component) {
+    return mViewWidgetRegistry.get(component);
+  }
+
+  public boolean promoteToView(@NonNull WXComponent component, boolean 
checkAncestor,
+      @NonNull Class<? extends WXComponent<?>> expectedClass) {
+    return !isFlatUIEnabled(component) ||
+        !expectedClass.equals(component.getClass()) ||
+        TextUtils.equals(component.getRef(), WXDomObject.ROOT) ||
+        (checkAncestor && getFlatComponentAncestor(component) == null) ||
+        checkComponent(component);
+  }
+
+  public
+  @Nullable
+  View getWidgetContainerView(Widget widget) {
+    WXComponent component, ancestor;
+    View ret = null;
+    if ((component = getComponent(widget)) != null) {
+      if ((ancestor = getFlatComponentAncestor(component)) != null) {
+        ret = ancestor.getHostView();
+      }
+    }
+    return ret;
+  }
+
+  @Override
+  @RestrictTo(Scope.LIBRARY)
+  public void destroy(){
+    widgetToComponent.clear();
+
+    for(Entry<WXComponent, AndroidViewWidget> entry: 
mViewWidgetRegistry.entrySet()){
+      entry.getValue().destroy();
+    }
+    mViewWidgetRegistry.clear();
+
+    for(Entry<WXComponent, WidgetContainer> entry:mWidgetRegistry.entrySet()){
+      entry.getValue().unmountFlatGUI();
+    }
+    mWidgetRegistry.clear();
+  }
+
+  private @Nullable WXComponent getComponent(@NonNull Widget widget){
+    return widgetToComponent.get(widget);
+  }
+
+  private boolean checkComponent(@NonNull WXComponent component) {
+    boolean ret = false;
+    ImmutableDomObject domObject = component.getDomObject();
+    if (domObject != null) {
+      WXStyle style = domObject.getStyles();
+      WXAttr attr = domObject.getAttrs();
+      if (style.containsKey(Name.OPACITY) ||
+          style.containsKey(Name.TRANSFORM) ||
+          style.containsKey(Name.VISIBILITY) ||
+          attr.containsKey(Name.ELEVATION) ||
+          attr.containsKey(Name.ARIA_HIDDEN) ||
+          attr.containsKey(Name.ARIA_LABEL) ||
+          attr.containsKey(WXComponent.PROP_FIXED_SIZE) ||
+          attr.containsKey(Name.DISABLED) ||
+          style.isFixed() ||
+          style.isSticky() ||
+          !style.getPesudoStyles().isEmpty() ||
+          domObject.getEvents().size() > 0) {
+        ret = true;
+      }
+    }
+    return ret;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/flat/WidgetContainer.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/flat/WidgetContainer.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/flat/WidgetContainer.java
new file mode 100644
index 0000000..f68aaeb
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/WidgetContainer.java
@@ -0,0 +1,93 @@
+/**
+ * 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.flat;
+
+
+import android.support.annotation.RestrictTo;
+import android.support.annotation.RestrictTo.Scope;
+import android.util.Pair;
+import android.view.ViewGroup;
+import com.taobao.weex.WXSDKInstance;
+import com.taobao.weex.dom.WXDomObject;
+import com.taobao.weex.ui.component.WXComponent;
+import com.taobao.weex.ui.component.WXVContainer;
+import com.taobao.weex.ui.flat.widget.AndroidViewWidget;
+import com.taobao.weex.ui.flat.widget.Widget;
+import java.util.LinkedList;
+import java.util.List;
+
+@RestrictTo(Scope.LIBRARY)
+public abstract class WidgetContainer<T extends ViewGroup> extends 
WXVContainer<T> {
+
+  protected List<Widget> widgets = new LinkedList<>();
+
+  public WidgetContainer(WXSDKInstance instance, WXDomObject node, 
WXVContainer parent) {
+    super(instance, node, parent);
+  }
+
+  protected abstract void mountFlatGUI();
+
+  protected abstract void unmountFlatGUI();
+
+  public boolean intendToBeFlatContainer() {
+    return false;
+  }
+
+  @Override
+  public void createChildViewAt(int index) {
+    if (intendToBeFlatContainer()) {
+      Pair<WXComponent, Integer> ret = rearrangeIndexAndGetChild(index);
+      if (ret.first != null) {
+        WXComponent child = ret.first;
+        Widget flatChild;
+        FlatGUIContext uiImp = getInstance().getFlatUIContext();
+        WidgetContainer parent = uiImp.getFlatComponentAncestor(this);
+        if (parent == null || uiImp.getAndroidViewWidget(this) != null) {
+          parent = this;
+        }
+        uiImp.register(child, parent);
+
+        if (child instanceof FlatComponent && !((FlatComponent) 
child).promoteToView(false)) {
+          flatChild = ((FlatComponent) child).getOrCreateFlatWidget();
+        } else {
+          flatChild = new AndroidViewWidget(uiImp);
+          uiImp.register(child, (AndroidViewWidget) flatChild);
+          child.createView();
+          ((AndroidViewWidget) flatChild).setContentView(child.getHostView());
+          //TODO Use a sort algorithm to decide the childIndex of 
AndroidViewWidget
+          parent.addSubView(child.getHostView(), -1);
+        }
+        uiImp.register(flatChild, child);
+        addFlatChild(flatChild, ret.second);
+      }
+    } else {
+      super.createChildViewAt(index);
+    }
+  }
+
+  private void addFlatChild(Widget widget, int index) {
+    if (index >= widgets.size()) {
+      widgets.add(widget);
+    } else {
+      widgets.add(index, widget);
+    }
+    //TODO do a partial update, not mount the whole flatContainer.
+    mountFlatGUI();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/AndroidViewWidget.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/AndroidViewWidget.java
 
b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/AndroidViewWidget.java
new file mode 100644
index 0000000..0610a8e
--- /dev/null
+++ 
b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/AndroidViewWidget.java
@@ -0,0 +1,76 @@
+/**
+ * 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.flat.widget;
+
+
+import android.graphics.Canvas;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+import android.support.annotation.RestrictTo.Scope;
+import android.view.View;
+import com.taobao.weex.common.Destroyable;
+import com.taobao.weex.ui.flat.FlatGUIContext;
+
+@RestrictTo(Scope.LIBRARY)
+public class AndroidViewWidget extends BaseWidget implements Destroyable {
+
+  private @Nullable View mView;
+  public AndroidViewWidget(@NonNull FlatGUIContext context) {
+    super(context);
+  }
+
+  public void setContentView(@Nullable View view){
+    this.mView = view;
+  }
+
+  @Override
+  public void setContentBox(int leftOffset, int topOffset, int rightOffset, 
int bottomOffset) {
+    if(mView!=null) {
+      mView.setPadding(leftOffset, topOffset, rightOffset, bottomOffset);
+      invalidate();
+    }
+  }
+
+  @Override
+  public void onDraw(@NonNull Canvas canvas) {
+    if(mView!=null) {
+      mView.draw(canvas);
+    }
+  }
+
+  @Override
+  public void invalidate() {
+    super.invalidate();
+    if (mView != null) {
+      mView.invalidate();
+    }
+  }
+
+  public @Nullable View getView() {
+    return mView;
+  }
+
+  @Override
+  public void destroy() {
+    if (mView != null) {
+      mView = null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/BaseWidget.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/BaseWidget.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/BaseWidget.java
new file mode 100644
index 0000000..02432dc
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/BaseWidget.java
@@ -0,0 +1,130 @@
+/**
+ * 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.flat.widget;
+
+
+import android.graphics.Canvas;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+import android.support.annotation.RestrictTo.Scope;
+import android.view.View;
+import com.taobao.weex.ui.flat.FlatGUIContext;
+import com.taobao.weex.ui.view.border.BorderDrawable;
+import com.taobao.weex.utils.WXViewUtils;
+
+@RestrictTo(Scope.LIBRARY)
+abstract class BaseWidget implements Widget {
+
+  //TODO Reconsider the field parameter in this class and the operation during 
draw(); Make a CPU/Memory balance.
+  //TODO use float to avoid 1px problem
+  private BorderDrawable backgroundBorder;
+  private int leftOffset, topOffset, rightOffset, bottomOffset;
+  private Rect borderBox = new Rect();
+  private Point offsetOfContainer = new Point();
+  private final @NonNull
+  FlatGUIContext context;
+
+  BaseWidget(@NonNull FlatGUIContext context){
+    this.context = context;
+  }
+
+  @Override
+  public void setLayout(int width, int height, int left, int right, int top, 
int bottom, Point offset) {
+    this.offsetOfContainer = offset;
+    borderBox.set(left, top, left + width, top + height);
+    if (backgroundBorder != null) {
+      setBackgroundAndBorder(backgroundBorder);
+    }
+    invalidate();
+  }
+
+  @Override
+  public void setContentBox(int leftOffset, int topOffset, int rightOffset, 
int bottomOffset) {
+    this.leftOffset = leftOffset;
+    this.topOffset = topOffset;
+    this.rightOffset = rightOffset;
+    this.bottomOffset = bottomOffset;
+    invalidate();
+  }
+
+  @Override
+  public void setBackgroundAndBorder(@NonNull BorderDrawable backgroundBorder) 
{
+    //TODO Change the code of BorderDrawable is more appropriate as it draws 
the borderLine from (0,0) not from getBounds
+    //TODO If the above is finished, no more traslate in draw in needed, only 
clip is enough.
+    this.backgroundBorder = backgroundBorder;
+    Rect backgroundBox = new Rect(borderBox);
+    backgroundBox.offset(-borderBox.left, -borderBox.top);
+    backgroundBorder.setBounds(backgroundBox);
+    setCallback(backgroundBorder);
+    invalidate();
+  }
+
+  @NonNull
+  @Override
+  public final Point getLocInFlatContainer() {
+    return offsetOfContainer;
+  }
+
+  @Nullable
+  @Override
+  public final BorderDrawable getBackgroundAndBorder() {
+    return backgroundBorder;
+  }
+
+  @NonNull
+  @Override
+  public final Rect getBorderBox() {
+    return borderBox;
+  }
+
+  @Override
+  public final void draw(@NonNull Canvas canvas) {
+    canvas.save();
+    WXViewUtils.clipCanvasWithinBorderBox(this, canvas);
+    canvas.translate(borderBox.left, borderBox.top);
+    if (backgroundBorder != null) {
+      backgroundBorder.draw(canvas);
+    }
+    canvas.clipRect(leftOffset, topOffset, borderBox.width()-rightOffset, 
borderBox.height() - bottomOffset);
+    canvas.translate(leftOffset, topOffset);
+    onDraw(canvas);
+    canvas.restore();
+  }
+
+  protected void invalidate() {
+    Rect dirtyRegion = new Rect(borderBox);
+    dirtyRegion.offset(offsetOfContainer.x, offsetOfContainer.y);
+    View widgetContainer;
+    if ((widgetContainer = context.getWidgetContainerView(this)) != null) {
+      widgetContainer.invalidate(dirtyRegion);
+    }
+  }
+
+  protected void setCallback(@NonNull Drawable drawable) {
+    View widgetContainer;
+    if ((widgetContainer = context.getWidgetContainerView(this)) != null) {
+      drawable.setCallback(widgetContainer);
+    }
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/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
new file mode 100644
index 0000000..2a69b46
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/TextWidget.java
@@ -0,0 +1,49 @@
+/**
+ * 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.flat.widget;
+
+
+import android.graphics.Canvas;
+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)
+public class TextWidget extends BaseWidget {
+
+  private Layout mLayout;
+
+  public TextWidget(@NonNull FlatGUIContext context) {
+    super(context);
+  }
+
+  @Override
+  public void onDraw(@NonNull Canvas canvas) {
+    if (mLayout != null) {
+      mLayout.draw(canvas);
+    }
+  }
+
+  public void updateTextDrawable(Layout layout) {
+    this.mLayout = layout;
+    invalidate();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/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
new file mode 100644
index 0000000..761d3b0
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/Widget.java
@@ -0,0 +1,51 @@
+/**
+ * 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.flat.widget;
+
+
+import android.graphics.Canvas;
+import android.graphics.Point;
+import android.graphics.Rect;
+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)
+public interface Widget {
+
+  public static final String TAG = "Widget";
+
+  void draw(@NonNull Canvas canvas);
+
+  void onDraw(@NonNull Canvas canvas);
+
+  void setBackgroundAndBorder(@NonNull BorderDrawable backgroundBorder);
+
+  void setLayout(int width, int height, int left, int right, int top, int 
bottom, Point offset);
+
+  void setContentBox(int leftOffset, int topOffset, int rightOffset, int 
bottomOffset);
+
+  @NonNull Point getLocInFlatContainer();
+
+  @Nullable BorderDrawable getBackgroundAndBorder();
+
+  @NonNull Rect getBorderBox();
+}


Reply via email to