http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
index 2ed3fae..b0b383e 100644
--- 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
+++ 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
@@ -21,19 +21,19 @@ package com.taobao.weex.ui.component.binding;
 import android.os.Looper;
 import android.support.v4.util.ArrayMap;
 import android.text.TextUtils;
-import android.util.Log;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.taobao.weex.WXEnvironment;
-import com.taobao.weex.annotation.Component;
+import com.taobao.weex.bridge.EventResult;
+import com.taobao.weex.bridge.WXBridgeManager;
 import com.taobao.weex.common.Constants;
 import com.taobao.weex.dom.WXAttr;
 import com.taobao.weex.dom.WXDomObject;
 import com.taobao.weex.dom.WXEvent;
+import com.taobao.weex.dom.WXStyle;
 import com.taobao.weex.dom.binding.ELUtils;
 import com.taobao.weex.dom.binding.WXStatement;
-import com.taobao.weex.dom.flex.CSSLayoutContext;
 import com.taobao.weex.el.parse.ArrayStack;
 import com.taobao.weex.el.parse.Operators;
 import com.taobao.weex.el.parse.Token;
@@ -42,6 +42,9 @@ import com.taobao.weex.ui.component.WXComponentFactory;
 import com.taobao.weex.ui.component.WXImage;
 import com.taobao.weex.ui.component.WXVContainer;
 import com.taobao.weex.ui.component.list.WXCell;
+import com.taobao.weex.ui.component.list.template.CellRenderContext;
+import com.taobao.weex.ui.component.list.template.CellDataManager;
+import com.taobao.weex.ui.component.list.template.VirtualComponentLifecycle;
 import com.taobao.weex.ui.component.list.template.WXRecyclerTemplateList;
 import com.taobao.weex.utils.WXLogUtils;
 import com.taobao.weex.utils.WXUtils;
@@ -63,11 +66,7 @@ public class Statements {
      * recursive copy component, none parent connect
      * */
     public static WXComponent copyComponentTree(WXComponent component){
-        long start = System.currentTimeMillis();
         WXComponent copy =  copyComponentTree(component, 
component.getParent());
-        if(WXEnvironment.isApkDebugable()){
-            WXLogUtils.d(WXRecyclerTemplateList.TAG, Thread.currentThread() + 
component.getRef() + "copyComponentTree " + "used " + 
(System.currentTimeMillis() - start));
-        }
         return copy;
     }
 
@@ -91,6 +90,10 @@ public class Statements {
                 }
             }
         }
+        //copy info need be sync
+        if(source.isWaste()){
+            component.setWaste(true);
+        }
         return  component;
     }
 
@@ -104,7 +107,7 @@ public class Statements {
      *  may be next render it can be used.
      *  after statement has executed, render component's binding attrs in 
context and bind it to component.
      * */
-    public static final List<WXComponent> doRender(WXComponent component, 
ArrayStack stack){
+    public static final List<WXComponent> doRender(WXComponent component, 
CellRenderContext stack){
         List<WXComponent> updates = new ArrayList<>(4);
         try{
             doRenderComponent(component, stack, updates);
@@ -143,7 +146,7 @@ public class Statements {
          *  may be next render it can be used.
          *  after statement has executed, render component's binding attrs in 
context and bind it to component.
          * */
-    private static final int doRenderComponent(WXComponent component, 
ArrayStack context,
+    private static final int doRenderComponent(WXComponent component, 
CellRenderContext context,
                                        List<WXComponent> updates){
         WXVContainer parent = component.getParent();
         WXDomObject domObject = (WXDomObject) component.getDomObject();
@@ -168,7 +171,7 @@ public class Statements {
                     String itemKey = vfor.getString(WXStatement.WX_FOR_ITEM);
                     Object data = null;
                     if(listBlock != null) {
-                        data = listBlock.execute(context);
+                        data = listBlock.execute(context.stack);
                     }
                     if((data instanceof List || data instanceof  Map)){
 
@@ -199,15 +202,15 @@ public class Statements {
                             if(itemKey != null){
                                 loop.put(itemKey, value);
                             }else{
-                                context.push(value);
+                                context.stack.push(value);
                             }
                             if(loop.size() > 0){
-                                context.push(loop);
+                                context.stack.push(loop);
                             }
 
 
                             if(vif != null){
-                                if(!Operators.isTrue(vif.execute(context))){
+                                
if(!Operators.isTrue(vif.execute(context.stack))){
                                     continue;
                                 }
                             }
@@ -229,8 +232,10 @@ public class Statements {
                             if(renderNode == null){
                                 long start = System.currentTimeMillis();
                                 renderNode = copyComponentTree(component, 
parent);
+                                renderNode.setWaste(false);
                                 WXDomObject renderNodeDomObject = 
(WXDomObject) renderNode.getDomObject();
-                                
renderNodeDomObject.getAttrs().setStatement(null); // clear node's statement
+                                
renderNodeDomObject.getAttrs().getStatement().remove(WXStatement.WX_FOR);
+                                
renderNodeDomObject.getAttrs().getStatement().remove(WXStatement.WX_IF); 
//FIXME  clear node's statement
                                 parentDomObject.add(renderNodeDomObject, 
renderIndex);
                                 parent.addChild(renderNode, renderIndex);
                                 updates.add(renderNode);
@@ -238,13 +243,13 @@ public class Statements {
                                     WXLogUtils.d(WXRecyclerTemplateList.TAG, 
Thread.currentThread().getName() +  renderNode.getRef() + 
renderNode.getDomObject().getType() + "statements copy component tree used " + 
(System.currentTimeMillis() - start));
                                 }
                             }
-                            doBindingAttrsEventAndRenderChildNode(renderNode, 
domObject, context, updates);
+                            doBindingAttrsEventAndRenderChildNode(renderNode, 
(WXDomObject) renderNode.getDomObject(), context, updates);
                             renderIndex++;
                             if(loop.size() > 0){
-                                context.push(loop);
+                                context.stack.push(loop);
                             }
                             if(itemKey == null) {
-                                context.pop();
+                                context.stack.pop();
                             }
                         }
                     }
@@ -264,45 +269,112 @@ public class Statements {
 
             //execute v-if context
             if(vif != null){
-                if(!Operators.isTrue(vif.execute(context))){
+                if(!Operators.isTrue(vif.execute(context.stack))){
                     component.setWaste(true);
-                    if(Thread.currentThread() == 
Looper.getMainLooper().getThread()) {
-                        return 1;
-                    }
+                    return 1;
                 }else{
                     component.setWaste(false);
                 }
+
             }
         }
         doBindingAttrsEventAndRenderChildNode(component, domObject, context, 
updates);
         return  1;
     }
 
+
     /**
      * bind attrs and doRender component child
      * */
-    private static void doBindingAttrsEventAndRenderChildNode(WXComponent 
component, WXDomObject domObject, ArrayStack context,
+    private static void doBindingAttrsEventAndRenderChildNode(WXComponent 
component, WXDomObject domObject, CellRenderContext context,
                                                               
List<WXComponent> updates){
-       WXAttr attr = component.getDomObject().getAttrs();
+        WXAttr attr = component.getDomObject().getAttrs();
+
         /**
          * sub component supported, sub component new stack
          * */
+        ArrayStack stack = context.stack;
+
+
+
         if(attr.get(ELUtils.IS_COMPONENT_ROOT) != null
                 && WXUtils.getBoolean(attr.get(ELUtils.IS_COMPONENT_ROOT), 
false)){
             if(attr.get(ELUtils.COMPONENT_PROPS) != null
                     && attr.get(ELUtils.COMPONENT_PROPS) instanceof  
JSONObject){
-                Map<String, Object>  props  = renderProps((JSONObject) 
attr.get(ELUtils.COMPONENT_PROPS), context);
-                context = new ArrayStack();
-                context.push(props);
+                 String compoentId = (String) 
attr.get(CellDataManager.SUB_COMPONENT_TEMPLATE_ID);
+                Object compoentData = null;
+                if(!TextUtils.isEmpty(compoentId)){
+                    String virtualComponentId =  
context.getRenderState().getVirtualComponentIds().get(component.getViewTreeKey());
+                   if(virtualComponentId == null){ //none virtualComponentId, 
create and do attach
+                        virtualComponentId =  
CellDataManager.createVirtualComponentId(context.templateList.getRef(),
+                                component.getViewTreeKey(), 
context.templateList.getItemId(context.position));
+                        Map<String, Object>  props  = renderProps((JSONObject) 
attr.get(ELUtils.COMPONENT_PROPS), context.stack);
+                        EventResult result = 
WXBridgeManager.getInstance().syncCallJSEventWithResult(WXBridgeManager.METHD_COMPONENT_HOOK_SYNC,
 component.getInstanceId(), null, compoentId, 
VirtualComponentLifecycle.LIFECYCLE, VirtualComponentLifecycle.CREATE,  new 
Object[]{
+                                virtualComponentId,
+                                props
+                        }, null);
+                        if(result != null
+                                && result.getResult() != null
+                                && result.getResult() instanceof Map){
+                            props.putAll((Map<? extends String, ?>) 
result.getResult());
+                        }
+                        compoentData  =  props;
+                        
context.getRenderState().getVirtualComponentIds().put(component.getViewTreeKey(),
 virtualComponentId);
+                        
context.templateList.getCellDataManager().createVirtualComponentData(context.position,
 virtualComponentId, compoentData);
+                        //create virtual componentId
+                        
WXBridgeManager.getInstance().asyncCallJSEventVoidResult(WXBridgeManager.METHD_COMPONENT_HOOK_SYNC,
 component.getInstanceId(), null, virtualComponentId, 
VirtualComponentLifecycle.LIFECYCLE, VirtualComponentLifecycle.ATTACH, null);
+                     }else{ // get virtual component data check has dirty's 
update
+                       compoentData = 
context.getRenderState().getVirtualComponentDatas().get(virtualComponentId);
+                       if(context.getRenderState().isHasDataUpdate()){
+                           Map<String, Object>  props  = 
renderProps((JSONObject) attr.get(ELUtils.COMPONENT_PROPS), context.stack);
+                           EventResult result = 
WXBridgeManager.getInstance().syncCallJSEventWithResult(WXBridgeManager.METHD_COMPONENT_HOOK_SYNC,
 component.getInstanceId(), null, virtualComponentId, 
VirtualComponentLifecycle.LIFECYCLE, VirtualComponentLifecycle.SYNSTATE,  new 
Object[]{
+                                   virtualComponentId,
+                                   props
+                           }, null);
+
+                           if(result != null
+                                   && result.getResult() != null
+                                   && result.getResult() instanceof Map){
+                               props.putAll((Map<? extends String, ?>) 
result.getResult());
+                               
context.templateList.getCellDataManager().updateVirtualComponentData(virtualComponentId,
 props);
+                               compoentData = props;
+                           }
+                       }
+                    }
+                    
component.getDomObject().getAttrs().put(CellDataManager.VIRTUAL_COMPONENT_ID, 
virtualComponentId);
+                }else{ //stateless component
+                    Map<String, Object>  props  = renderProps((JSONObject) 
attr.get(ELUtils.COMPONENT_PROPS), context.stack);
+                    compoentData = props;
+                }
+                //virtual component is new context
+                context.stack = new ArrayStack();
+                if(compoentData != null){
+                    context.stack.push(compoentData);
+                }
             }
         }
+
+        /**
+         * check node is render only once, if render once, and has rendered, 
just return
+         * */
+        Object vonce = null;
+        if(attr.getStatement() != null){
+            vonce = attr.getStatement().get(WXStatement.WX_ONCE);
+        }
+        if(vonce != null){
+            ArrayStack onceStack = 
context.getRenderState().getOnceComponentStates().get(component.getViewTreeKey());
+            if(onceStack == null){
+                onceStack = context.templateList.copyStack(context, stack);
+                
context.getRenderState().getOnceComponentStates().put(component.getViewTreeKey(),
 onceStack);
+            }
+            context.stack = onceStack;
+        }
+
         doRenderBindingAttrsAndEvent(component, domObject, context);
         if(component instanceof WXVContainer){
             if(!domObject.isShow()){
                 if(!(component instanceof WXCell)){
-                    if(Thread.currentThread() == 
Looper.getMainLooper().getThread()){
-                        return;
-                    }
+                    return;
                 }
             }
             WXVContainer container = (WXVContainer) component;
@@ -311,6 +383,9 @@ public class Statements {
                 k += doRenderComponent(next, context, updates);
             }
         }
+        if(stack != context.stack){
+            context.stack = stack;
+        }
     }
 
 
@@ -325,14 +400,15 @@ public class Statements {
     /**
      * render dynamic binding attrs and bind them to component node.
      * */
-    private static void doRenderBindingAttrsAndEvent(WXComponent component, 
WXDomObject domObject, ArrayStack context){
+    private static void doRenderBindingAttrsAndEvent(WXComponent component, 
WXDomObject domObject, CellRenderContext context){
+        ArrayStack stack  = context.stack;
         component.setWaste(false);
         WXAttr attr = domObject.getAttrs();
         if(attr != null
                 && attr.getBindingAttrs() != null
                 && attr.getBindingAttrs().size() > 0){
             ArrayMap<String, Object> bindAttrs = 
domObject.getAttrs().getBindingAttrs();
-            Map<String, Object> dynamic =  renderBindingAttrs(bindAttrs, 
context);
+            Map<String, Object> dynamic =  renderBindingAttrs(bindAttrs, 
stack);
             Set<Map.Entry<String, Object>> entries = dynamic.entrySet();
             /**
              * diff attrs, see attrs has update, remove none update attrs
@@ -364,23 +440,60 @@ public class Statements {
                 }else {
                     domObject.updateAttr(dynamic); //dirty layout
                 }
-                if(Thread.currentThread() == 
Looper.getMainLooper().getThread()) {
+                if(isMainThread()) {
                     component.updateProperties(dynamic);
                 }
                 dynamic.clear();
             }
         }
+
+
+        WXStyle style = domObject.getStyles();
+        if(style != null && style.getBindingStyle() != null){
+            ArrayMap<String, Object> bindStyle = style.getBindingStyle();
+            Map<String, Object> dynamic =  renderBindingAttrs(bindStyle, 
stack);
+            Set<Map.Entry<String, Object>> entries = dynamic.entrySet();
+            /**
+             * diff attrs, see attrs has update, remove none update attrs
+             * */
+            Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
+            while (iterator.hasNext()){
+                Map.Entry<String, Object> entry = iterator.next();
+                String key = entry.getKey();
+                Object value = entry.getValue();
+                Object oldValue = style.get(key);
+                if(value == null){
+                    if(oldValue == null){
+                        iterator.remove();
+                        continue;
+                    }
+                }else{
+                    if(value.equals(oldValue)){
+                        iterator.remove();
+                    }
+                }
+            }
+            if(dynamic.size() > 0) {
+                 domObject.updateStyle(dynamic, false);
+                 domObject.applyStyle(dynamic);
+                 if(isMainThread()) {
+                    component.updateProperties(dynamic);
+                 }
+            }
+        }
+
         WXEvent event = domObject.getEvents();
         if(event == null || event.getEventBindingArgs() == null){
             return;
         }
         Set<Map.Entry<String, Object>> eventBindArgsEntrySet = 
event.getEventBindingArgs().entrySet();
         for(Map.Entry<String, Object> eventBindArgsEntry : 
eventBindArgsEntrySet){
-             List<Object> values = getBindingEventArgs(context, 
eventBindArgsEntry.getValue());
+             List<Object> values = getBindingEventArgs(stack, 
eventBindArgsEntry.getValue());
              if(values != null){
                  event.putEventBindingArgsValue(eventBindArgsEntry.getKey(), 
values);
              }
         }
+
     }
 
 
@@ -390,7 +503,7 @@ public class Statements {
      * return binding attrs rended value in context
      * */
     private static final  ThreadLocal<Map<String, Object>> dynamicLocal = new 
ThreadLocal<>();
-    public static Map<String, Object> renderBindingAttrs(ArrayMap bindAttrs, 
ArrayStack context){
+    public static Map<String, Object> renderBindingAttrs(ArrayMap bindAttrs, 
ArrayStack stack){
         Set<Map.Entry<String, Object>> entrySet = bindAttrs.entrySet();
         Map<String, Object> dynamic = dynamicLocal.get();
         if(dynamic == null) {
@@ -407,7 +520,7 @@ public class Statements {
                     && (((JSONObject) value).get(ELUtils.BINDING)  instanceof 
Token)){
                 JSONObject binding = (JSONObject) value;
                 Token block = (Token) (binding.get(ELUtils.BINDING));
-                Object blockValue = block.execute(context);
+                Object blockValue = block.execute(stack);
                 dynamic.put(key, blockValue);
             }else if(value instanceof JSONArray){
                 JSONArray array = (JSONArray) value;
@@ -422,7 +535,7 @@ public class Statements {
                             && (((JSONObject) element).get(ELUtils.BINDING) 
instanceof Token)){
                         JSONObject binding = (JSONObject) element;
                         Token block = (Token) (binding.get(ELUtils.BINDING));
-                        Object blockValue = block.execute(context);
+                        Object blockValue = block.execute(stack);
                         if(blockValue == null){
                             blockValue = "";
                         }
@@ -442,7 +555,7 @@ public class Statements {
     }
 
 
-    public static Map<String, Object> renderProps(JSONObject props, ArrayStack 
context){
+    public static Map<String, Object> renderProps(JSONObject props, ArrayStack 
stack){
         Set<Map.Entry<String, Object>> entrySet = props.entrySet();
         Map<String, Object> renderProps = new ArrayMap<>(4);
         for(Map.Entry<String, Object> entry : entrySet){
@@ -452,7 +565,7 @@ public class Statements {
                     && (((JSONObject) value).get(ELUtils.BINDING)  instanceof  
Token)){
                 JSONObject binding = (JSONObject) value;
                 Token block = (Token) (binding.get(ELUtils.BINDING));
-                Object blockValue = block.execute(context);
+                Object blockValue = block.execute(stack);
                 renderProps.put(key, blockValue);
             }else{
                 renderProps.put(key, value);
@@ -461,7 +574,7 @@ public class Statements {
         return  renderProps;
     }
 
-    public static List<Object> getBindingEventArgs(ArrayStack context, Object 
bindings){
+    public static List<Object> getBindingEventArgs(ArrayStack stack, Object 
bindings){
           List<Object>  params = new ArrayList<>(4);
           if(bindings instanceof  JSONArray){
               JSONArray array = (JSONArray) bindings;
@@ -470,7 +583,7 @@ public class Statements {
                   if(value instanceof  JSONObject
                           && (((JSONObject) value).get(ELUtils.BINDING) 
instanceof  Token)){
                       Token block = (Token)(((JSONObject) 
value).get(ELUtils.BINDING));
-                      Object blockValue = block.execute(context);
+                      Object blockValue = block.execute(stack);
                       params.add(blockValue);
                   }else{
                       params.add(value);
@@ -480,7 +593,7 @@ public class Statements {
               JSONObject binding = (JSONObject) bindings;
                if(binding.get(ELUtils.BINDING) instanceof  Token){
                    Token block = (Token) binding.get(ELUtils.BINDING);
-                   Object blockValue = block.execute(context);
+                   Object blockValue = block.execute(stack);
                    params.add(blockValue);
                }else{
                    params.add(bindings.toString());
@@ -490,4 +603,33 @@ public class Statements {
           }
           return  params;
     }
+
+    private static volatile int componentIdNext = 0;
+
+
+    private static boolean isMainThread(){
+        return  Thread.currentThread() == Looper.getMainLooper().getThread();
+    }
+
+
+
+    public static String getComponentId(WXComponent component){
+        if(component instanceof  WXCell || component == null){
+            return  null;
+        }
+        WXDomObject domObject = (WXDomObject) component.getDomObject();
+        WXAttr attr = domObject.getAttrs();
+        if(attr.get(ELUtils.IS_COMPONENT_ROOT) != null
+                && WXUtils.getBoolean(attr.get(ELUtils.IS_COMPONENT_ROOT), 
false)){
+            if(attr.get(ELUtils.COMPONENT_PROPS) != null
+                    && attr.get(ELUtils.COMPONENT_PROPS) instanceof  
JSONObject){
+                Object componentId = 
attr.get(CellDataManager.VIRTUAL_COMPONENT_ID);
+                if(componentId == null){
+                    return null;
+                }
+                return componentId.toString();
+            }
+        }
+        return getComponentId(component.getParent());
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/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 36909fa..935f7e6 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
@@ -52,7 +52,6 @@ public class WXCell extends WidgetContainer<WXFrameLayout> {
     private ViewGroup mRealView;
     private View mTempStickyView;
     private View mHeadView;
-    private boolean mLazy = true;
 
     /** used in list sticky detect **/
     private int mScrollPositon = -1;
@@ -63,16 +62,16 @@ public class WXCell extends WidgetContainer<WXFrameLayout> {
 
     private boolean isSourceUsed = false;
 
-    private boolean hasLayout = false;
-
 
     @Deprecated
     public WXCell(WXSDKInstance instance, WXDomObject dom, WXVContainer 
parent, String instanceId, boolean isLazy) {
         super(instance, dom, parent);
+        lazy(true);
     }
 
     public WXCell(WXSDKInstance instance, WXDomObject dom, WXVContainer 
parent, boolean isLazy) {
         super(instance, dom, parent);
+        lazy(true);
         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.
@@ -88,12 +87,10 @@ public class WXCell extends WidgetContainer<WXFrameLayout> {
 
     @Override
     public boolean isLazy() {
-        return mLazy && !isFixed();
+        return super.isLazy() && !isFixed();
     }
 
-    public void lazy(boolean lazy) {
-        mLazy = lazy;
-    }
+
 
     @Override
     @RestrictTo(Scope.LIBRARY)
@@ -236,11 +233,4 @@ public class WXCell extends WidgetContainer<WXFrameLayout> 
{
         isSourceUsed = sourceUsed;
     }
 
-    public boolean isHasLayout() {
-        return hasLayout;
-    }
-
-    public void setHasLayout(boolean hasLayout) {
-        this.hasLayout = hasLayout;
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/AsyncCellLoadTask.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/AsyncCellLoadTask.java
 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/AsyncCellLoadTask.java
new file mode 100644
index 0000000..eb864bf
--- /dev/null
+++ 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/AsyncCellLoadTask.java
@@ -0,0 +1,128 @@
+/**
+ * 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.component.list.template;
+
+import android.os.AsyncTask;
+import android.os.Looper;
+import android.os.MessageQueue;
+
+import com.taobao.weex.WXEnvironment;
+import com.taobao.weex.ui.component.list.WXCell;
+import com.taobao.weex.utils.WXLogUtils;
+
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ * Created by furture on 2018/1/25.
+ * async template cell component copy in background and init component when 
idle
+ */
+class AsyncCellLoadTask extends AsyncTask<Void,Void, Void> {
+
+    private String template;
+    private WXCell source;
+    private WXRecyclerTemplateList templateList;
+
+    public AsyncCellLoadTask(String template, WXCell source, 
WXRecyclerTemplateList templateList) {
+        this.template = template;
+        this.source = source;
+        this.templateList = templateList;
+    }
+
+    /**
+     * async template cell component copy in background
+     * */
+    @Override
+    protected Void doInBackground(Void... params) {
+        TemplateCache cellCache = 
templateList.getTemplatesCache().get(template);
+        if(cellCache == null || cellCache.cells == null){
+            return null;
+        }
+        while (cellCache.cells.size() < templateList.getTemplateCacheSize()){
+            long start = System.currentTimeMillis();
+            WXCell component = (WXCell) 
templateList.copyComponentFromSourceCell(source);
+            if(WXEnvironment.isOpenDebugLog() && 
WXRecyclerTemplateList.ENABLE_TRACE_LOG){
+                WXLogUtils.d(WXRecyclerTemplateList.TAG, " AsyncCellLoadTask 
load " + template
+                + " used " + (System.currentTimeMillis() - start));
+            }
+            if(component == null){
+                return null;
+            }
+            if(isDestory()){
+                return null;
+            }
+            cellCache.cells.add(component);
+        }
+        return null;
+    }
+
+    /**
+     * init component view when main thread idle
+     * */
+    @Override
+    protected void onPostExecute(Void aVoid) {
+        if(isDestory()){
+            return;
+        }
+        final TemplateCache cellCache = 
templateList.getTemplatesCache().get(template);
+        if(cellCache == null){
+            return;
+        }
+        if(cellCache.cells == null
+                || cellCache.cells.size() == 0){
+            cellCache.isLoadIng = false;
+            return;
+        }
+        Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
+            @Override
+            public boolean queueIdle() {
+                if(isDestory()){
+                    return false;
+                }
+                ConcurrentLinkedQueue<WXCell> queue =  cellCache.cells;
+                Iterator<WXCell> iterator =  queue.iterator();
+                while (iterator.hasNext()){
+                    WXCell  component =  iterator.next();
+                    if(component.isLazy()){
+                        templateList.doCreateCellViewBindData(component, 
template, true);
+                        return iterator.hasNext();
+                    }
+                }
+                return false;
+            }
+        });
+        cellCache.isLoadIng = false;
+    }
+
+    private boolean isDestory(){
+        if(source.getInstance() == null
+                || source.getInstance().isDestroy()){
+            return true;
+        }
+        return templateList.isDestoryed();
+    }
+
+    /**
+     * start cell load task on THREAD_POOL_EXECUTOR
+     * */
+    public void startTask(){
+        executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellDataManager.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellDataManager.java
 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellDataManager.java
new file mode 100644
index 0000000..3982117
--- /dev/null
+++ 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellDataManager.java
@@ -0,0 +1,272 @@
+/**
+ * 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.component.list.template;
+
+
+import android.support.v4.util.ArrayMap;
+import android.text.TextUtils;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.taobao.weex.WXEnvironment;
+import com.taobao.weex.bridge.WXBridgeManager;
+import com.taobao.weex.utils.WXUtils;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by furture on 2018/1/23.
+ * template data manager, manage data and render state
+ */
+public class CellDataManager {
+
+    private static final String VIRTUAL_COMPONENT_SEPRATOR = "@";
+
+    public static final String SUB_COMPONENT_TEMPLATE_ID = "@templateId";
+
+    public static final String VIRTUAL_COMPONENT_ID = "@virtualComponentId";
+
+    /**
+     * template list data, update should vis data manager interface, this 
field is read only
+     * */
+    JSONArray listData;
+
+    /**
+     * current template list
+     * */
+    public final WXRecyclerTemplateList templateList;
+
+    /**
+     * data render state for position, itemId、dirty、and other info
+     * */
+    private Map<Integer, CellRenderState> renderStates = new ArrayMap<>();
+
+
+    /**
+     * list virtual component data, rendet state
+     * key virtual component id, value is cell render state.
+     * */
+    private Map<String, CellRenderState> virtualComponentRenderStates;
+
+
+
+    /**
+     * template list data manager
+     * */
+    public CellDataManager(WXRecyclerTemplateList templateList) {
+        this.templateList = templateList;
+    }
+
+    /**
+     * get current render state for current position, never return null.
+     * */
+    public CellRenderState getRenderState(int position){
+        CellRenderState renderState = renderStates.get(position);
+        if(renderState == null){
+            renderState = new CellRenderState();
+            renderState.position = position;
+            renderStates.put(position, renderState);
+        }
+        if(position != renderState.position) {
+            renderState.position = position;
+            renderState.hasPositionChange = true;
+        }
+        return renderState;
+    }
+
+    /**
+     * @param  virutalComponentId virutalComponentId
+     * @param  data   update    virutalComponent's data
+     * update virtual component data
+     * */
+    public void updateVirtualComponentData(String virutalComponentId, Object 
data){
+        if(virtualComponentRenderStates != null){
+            CellRenderState cellRenderState = 
virtualComponentRenderStates.get(virutalComponentId);
+            if(cellRenderState != null){
+                
cellRenderState.getVirtualComponentDatas().put(virutalComponentId, data);
+                cellRenderState.hasVirtualCompoentUpdate = true;
+            }else{
+                if(WXEnvironment.isApkDebugable()) {
+                    throw new IllegalArgumentException("virtualComponentDatas 
illegal state empty render state" + virutalComponentId);
+                }
+            }
+        }else{
+            if(WXEnvironment.isApkDebugable()){
+                throw  new IllegalArgumentException("virtualComponentDatas 
illegal state " + virutalComponentId);
+            }
+        }
+    }
+
+    /**
+     * @param  position  current position virtual component
+     * @param  virutalComponentId virutalComponentId
+     * @param  data   update    virutalComponent's data
+     * create virtual component data
+     * */
+    public void createVirtualComponentData(int position, String 
virutalComponentId, Object data){
+        if(virtualComponentRenderStates == null){
+            virtualComponentRenderStates = new HashMap<>(8);
+        }
+        CellRenderState renderState = renderStates.get(position);
+        renderState.getVirtualComponentDatas().put(virutalComponentId, data);
+        virtualComponentRenderStates.put(virutalComponentId, renderState);
+
+    }
+
+
+
+
+    /**
+     * @param  listData setList data
+     * clear render state for current cell, and virtual component data
+     * */
+    public void setListData(JSONArray listData) {
+        if(this.listData != listData) {
+            if(this.listData != null){
+                
if(WXUtils.getBoolean(templateList.getDomObject().getAttrs().get("exitDetach"), 
true)){
+                    for(int i=0; i<this.listData.size(); i++){
+                        cleanRenderState(renderStates.remove(i));
+                    }
+                }
+            }
+            this.listData = listData;
+            renderStates.clear();
+            if (virtualComponentRenderStates != null) {
+                virtualComponentRenderStates.clear();
+            }
+        }
+    }
+
+    /**
+     * @param index insert index
+     * @param  data  data object
+     * insert data at current index
+     * */
+    public boolean insertData(int index, Object data){
+        listData.add(index, data);
+        boolean renderStateChange = false;
+        for(int i=listData.size(); i>= index; i--){
+            CellRenderState state = renderStates.remove(i);
+            if(state != null){
+                renderStates.put(i + 1, state);
+                renderStateChange = true;
+            }
+        }
+        return renderStateChange;
+    }
+
+    /**
+     *
+     * @param index insert index
+     * @param  data  data object
+     * insert data at current index
+     * */
+    public boolean insertRange(int index, JSONArray data){
+        listData.addAll(index, data);
+        boolean renderStateChange = false;
+        for(int i = listData.size()-1; i >= index; i--){
+            CellRenderState state = renderStates.remove(i);
+            if(state != null){
+                renderStates.put(i + 1, state);
+                renderStateChange = true;
+            }
+        }
+        return renderStateChange;
+    }
+
+    /**
+     * @param  data  data object
+     * @param index insert index
+     * update data, reset new render state,
+     * return true if only data changed, false if viewType changed
+     * */
+    public boolean  updateData(Object data, int index){
+        boolean onlyDataChange = 
TextUtils.equals(templateList.getTemplateKey(index), 
templateList.getTemplateKey(data));
+        listData.set(index, data);
+        if(!onlyDataChange){
+            //structure changed, reset render state
+            cleanRenderState(renderStates.remove(index));
+        }else{
+            CellRenderState renderState = renderStates.get(index);
+            if(renderState != null){
+                renderState.hasDataUpdate = true;
+            }
+        }
+        return onlyDataChange;
+    }
+
+    /**
+     * @param index
+     * remove data, and its render state  and  virtual's data
+     * */
+    public void  removeData(Integer index){
+        listData.remove((int)index); //remove by index
+        cleanRenderState(renderStates.remove(index));
+        int count = listData.size() + 1;
+        for(int i=index + 1; i < count; i++){
+            CellRenderState state = renderStates.remove(i);
+            if(state != null){
+                renderStates.put(i-1, state);
+            }
+        }
+    }
+
+    /**
+     *  clean render state, if has virtual component, call virtual component 
detach lifecycle
+     * */
+    private void  cleanRenderState(CellRenderState renderState){
+        if(renderState == null){
+            return;
+        }
+        if(renderState.hasVirtualComponents()){
+            Collection<String> virtualComponentIds =  
renderState.getVirtualComponentIds().values();
+            for(String virtualComponentId : virtualComponentIds){
+                if(virtualComponentRenderStates != null){
+                    virtualComponentRenderStates.remove(virtualComponentId);
+                }
+                
WXBridgeManager.getInstance().asyncCallJSEventVoidResult(WXBridgeManager.METHD_COMPONENT_HOOK_SYNC,
+                        templateList.getInstanceId(),
+                        null,
+                        virtualComponentId, 
VirtualComponentLifecycle.LIFECYCLE, VirtualComponentLifecycle.DETACH, null);
+
+            }
+        }
+    }
+
+
+    /**
+     * create virtualComponentId
+     * */
+    public static String createVirtualComponentId(String listRef, String 
viewTreeKey, long itemId){
+        return  listRef + VIRTUAL_COMPONENT_SEPRATOR  + viewTreeKey + 
VIRTUAL_COMPONENT_SEPRATOR + itemId;
+    }
+
+    /**
+     * get list ref from virtualComponentId
+     * */
+    public static String getListRef(String virtualComponentId){
+        if(virtualComponentId == null){
+            return null;
+        }
+        return virtualComponentId.split(VIRTUAL_COMPONENT_SEPRATOR)[0];
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderContext.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderContext.java
 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderContext.java
new file mode 100644
index 0000000..7d59848
--- /dev/null
+++ 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderContext.java
@@ -0,0 +1,79 @@
+/**
+ * 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.component.list.template;
+
+import com.taobao.weex.el.parse.ArrayStack;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by furture on 2018/1/23.
+ * render context for cell template
+ */
+public class CellRenderContext {
+    /**
+     * code execute stack
+     * */
+    public ArrayStack stack = new ArrayStack();
+    /**
+     * init context data
+     * */
+    public Map map = new HashMap(8);
+
+
+    /**
+     * component data context
+     * */
+    public CellRenderState renderState;
+
+    /**
+     * current position
+     * */
+    public int position;
+
+    /**
+     * current list component
+     * */
+    public WXRecyclerTemplateList templateList;
+
+
+    /**
+     * get current render state
+     * */
+    public CellRenderState getRenderState() {
+        if(renderState != null){
+            renderState =  
templateList.getCellDataManager().getRenderState(position);
+        }
+        return renderState;
+    }
+
+
+    public void clear(){
+        if(stack.getList().size() > 0) {
+            stack.getList().clear();
+        }
+        if(map.size() > 0) {
+            map.clear();
+        }
+        renderState  = null;
+        position = 0;
+        templateList = null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderState.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderState.java
 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderState.java
new file mode 100644
index 0000000..2f71a81
--- /dev/null
+++ 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderState.java
@@ -0,0 +1,122 @@
+/**
+ * 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.component.list.template;
+
+import android.support.v7.widget.RecyclerView;
+
+import com.taobao.weex.el.parse.ArrayStack;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by furture on 2018/1/24.
+ * render state for one cell, manage it's render state
+ */
+public class CellRenderState {
+
+    /**
+     * dirty for current position, for example virtual component has update
+     * */
+    boolean hasVirtualCompoentUpdate = false;
+
+    /**
+     * has date update
+     * */
+    boolean hasDataUpdate = false;
+
+    /**
+     * position changed
+     * */
+    boolean hasPositionChange = false;
+
+    /**
+     *  may use position, when position changed should be rendered
+     * */
+    int  position;
+
+    /**
+     * unique itemId for current position, generate via key core
+     * */
+    long itemId = RecyclerView.NO_ID;
+
+
+
+    /**
+     * virtualCompoentId for cell, key is viewTreeKey, value is 
virutalComponentId.
+     * lazy init,
+     * */
+    private Map<String, String> virtualComponentIds;
+    private Map<String, Object> virtualComponentDatas;
+
+
+    /**
+     * mark once statements has rendered
+     * */
+    private Map<String,ArrayStack> onceComponentStates;
+
+
+    public Map<String, String> getVirtualComponentIds() {
+        if(virtualComponentIds == null){
+            virtualComponentIds = new HashMap<>(8);
+        }
+        return virtualComponentIds;
+    }
+
+    /**
+     * return current cell has virtual component
+     * */
+    public boolean hasVirtualComponents(){
+        return virtualComponentIds != null && virtualComponentIds.size() > 0;
+    }
+
+    public Map<String, Object> getVirtualComponentDatas() {
+        if(virtualComponentDatas == null){
+            virtualComponentDatas = new HashMap<>(4);
+        }
+        return virtualComponentDatas;
+    }
+
+    public Map<String, ArrayStack> getOnceComponentStates() {
+        if(onceComponentStates == null){
+            onceComponentStates = new HashMap<>();
+        }
+        return onceComponentStates;
+    }
+
+    public boolean isDirty() {
+        return hasDataUpdate
+                || hasVirtualCompoentUpdate
+                || hasPositionChange;
+    }
+
+    public boolean isHasDataUpdate() {
+        return hasDataUpdate;
+    }
+
+
+
+    public void  resetDirty(){
+        hasDataUpdate = false;
+        hasVirtualCompoentUpdate = false;
+        hasPositionChange = false;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/DomTreeBuilder.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/DomTreeBuilder.java
 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/DomTreeBuilder.java
deleted file mode 100644
index 0aa6cde..0000000
--- 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/DomTreeBuilder.java
+++ /dev/null
@@ -1,100 +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.component.list.template;
-
-import com.taobao.weex.WXEnvironment;
-import com.taobao.weex.WXSDKManager;
-import com.taobao.weex.dom.DOMActionContext;
-import com.taobao.weex.dom.WXDomObject;
-import com.taobao.weex.dom.action.TraceableAction;
-import com.taobao.weex.ui.component.WXComponent;
-import com.taobao.weex.ui.component.WXComponentFactory;
-import com.taobao.weex.ui.component.WXVContainer;
-import com.taobao.weex.utils.WXLogUtils;
-
-/**
- * Created by furture on 2017/10/2.
- */
-
-class DomTreeBuilder extends TraceableAction {
-
-
-
-
-    public WXComponent generateComponentTree(DOMActionContext context, 
WXDomObject dom, WXVContainer parent) {
-        if (dom == null) {
-            return null;
-        }
-       long startNanos = System.nanoTime();
-        dom.setCloneThis(true);
-        WXComponent component = 
WXComponentFactory.newInstance(context.getInstance(), dom, parent);
-        if (component != null) {
-            component.mTraceInfo.domThreadStart = dom.mDomThreadTimestamp;
-            component.mTraceInfo.rootEventId = mTracingEventId;
-            component.mTraceInfo.domQueueTime = mDomQueueTime;
-        }
-        context.registerComponent(dom.getRef(), component);
-        if (component instanceof WXVContainer) {
-            WXVContainer container = (WXVContainer) component;
-            WXDomObject parentDom = (WXDomObject) container.getDomObject();
-            for (int i = 0; i < dom.childCount(); ++i) {
-                WXDomObject child = dom.getChild(i);
-                if (child != null) {
-                    WXComponent childComponent = 
generateComponentTree(context, child, container);
-                    container.addChild(childComponent);
-                    WXDomObject childDomObject = (WXDomObject) 
childComponent.getDomObject();
-                    if(childDomObject != child) {
-                        int index = parentDom.index(child);
-                        parentDom.add(childDomObject, index);
-                        if(index >= 0) {
-                            parentDom.remove(child);
-                            i--;
-                        }
-                        RuntimeException exception = new 
IllegalArgumentException(childDomObject.getClass().getName()
-                                + " not support clone this");
-                        WXLogUtils.e("weex", exception);
-                        if(WXEnvironment.isApkDebugable()){
-                            throw  exception;
-                        }
-                    }
-                }
-            }
-        }
-        dom.setCloneThis(false);
-        if (component != null) {
-            component.mTraceInfo.domThreadNanos = System.nanoTime() - 
startNanos;
-        }
-        return component;
-    }
-
-    public static final WXComponent buildTree(WXDomObject domObject, 
WXVContainer parent){
-        DOMActionContext domActionContext = 
WXSDKManager.getInstance().getWXDomManager().getDomContext(parent.getInstanceId());
-        if(domActionContext == null){
-            return null;
-        }
-        DomTreeBuilder builder = new DomTreeBuilder();
-        domObject.traverseTree(
-                domActionContext.getAddDOMConsumer(),
-                domActionContext.getApplyStyleConsumer()
-        );
-        return builder.generateComponentTree(domActionContext, domObject, 
parent);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/PositionRef.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/PositionRef.java
 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/PositionRef.java
new file mode 100644
index 0000000..f25c9a9
--- /dev/null
+++ 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/PositionRef.java
@@ -0,0 +1,64 @@
+/**
+ * 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.component.list.template;
+
+/**
+ * position render state, when render state change, position changed
+ * Created by furture on 2018/2/2.
+ */
+public class PositionRef extends  Number{
+
+    private CellRenderState renderState;
+
+    public PositionRef(CellRenderState renderState) {
+        this.renderState = renderState;
+    }
+
+    @Override
+    public int intValue() {
+        return getPosition();
+    }
+
+    @Override
+    public long longValue() {
+        return getPosition();
+    }
+
+    @Override
+    public float floatValue() {
+        return getPosition();
+    }
+
+    @Override
+    public double doubleValue() {
+        return getPosition();
+    }
+
+    private int getPosition(){
+        if(renderState == null){
+            return  -1;
+        }
+        return renderState.position;
+    }
+
+    @Override
+    public String toString() {
+        return String.valueOf(getPosition());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/VirtualComponentLifecycle.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/VirtualComponentLifecycle.java
 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/VirtualComponentLifecycle.java
new file mode 100644
index 0000000..5466621
--- /dev/null
+++ 
b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/VirtualComponentLifecycle.java
@@ -0,0 +1,45 @@
+/**
+ * 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.component.list.template;
+
+
+/**
+ * Created by furture on 2018/2/1.
+ */
+
+public class VirtualComponentLifecycle {
+
+    /**
+     * lifecycle
+     * */
+    public static final  String LIFECYCLE = "lifecycle";
+
+
+    /**
+     * virtual component lifecycle
+     * */
+    public static final  String CREATE = "create";
+
+    public static final  String ATTACH = "attach";
+
+    public static final  String SYNSTATE = "syncState";
+
+    public static final  String DETACH = "detach";
+
+}

Reply via email to