Repository: incubator-weex Updated Branches: refs/heads/master 0d2681fcd -> b049f80ee
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java index 83a4246..3375500 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java @@ -42,7 +42,6 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.taobao.weex.WXEnvironment; import com.taobao.weex.WXSDKInstance; -import com.taobao.weex.WXSDKManager; import com.taobao.weex.annotation.Component; import com.taobao.weex.annotation.JSMethod; import com.taobao.weex.common.Constants; @@ -55,7 +54,6 @@ import com.taobao.weex.dom.WXEvent; import com.taobao.weex.el.parse.ArrayStack; import com.taobao.weex.ui.action.BasicComponentData; import com.taobao.weex.ui.component.AppearanceHelper; -import com.taobao.weex.ui.component.ComponentUtils; import com.taobao.weex.ui.component.Scrollable; import com.taobao.weex.ui.component.WXBaseRefresh; import com.taobao.weex.ui.component.WXComponent; @@ -99,7 +97,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp /** * trace log for template list * */ - public static final boolean ENABLE_TRACE_LOG = false; + public static final boolean ENABLE_TRACE_LOG = true; public static final String TAG = "WXRecyclerTemplateList"; @@ -137,14 +135,12 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp private CellDataManager cellDataManager; - private String listDataKey = Constants.Name.Recycler.LIST_DATA; private String listDataItemKey = null; private String listDataIndexKey = null; private ArrayMap<String, Integer> mTemplateViewTypes; - private Map<String, WXCell> mTemplateSources; private String listDataTemplateKey = Constants.Name.Recycler.SLOT_TEMPLATE_CASE; private Runnable listUpdateRunnable; @@ -164,7 +160,6 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp private ScrollStartEndHelper mScrollStartEndHelper; - /** * sticky helper * */ @@ -186,22 +181,27 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp private CellRenderContext cellRenderContext = new CellRenderContext(); + private Runnable mAppearChangeRunnable = null; + private static final long APPEAR_CHANGE_RUNNABLE_DELAY = 50; + + /** + * has append tree done + * */ + private boolean hasAppendTreeDone = false; + + /** + * has layout done + * */ + private boolean hasLayoutDone = false; + public WXRecyclerTemplateList(WXSDKInstance instance, WXVContainer parent, BasicComponentData basicComponentData) { super(instance, parent, basicComponentData); - initRecyclerTemplateList(instance, - // TODO -// , node - parent); + initRecyclerTemplateList(instance, basicComponentData, parent); } - private void initRecyclerTemplateList(WXSDKInstance instance, - // TODO -// WXDomObject node, + private void initRecyclerTemplateList(WXSDKInstance instance, BasicComponentData basicComponentData, WXVContainer parent){ - // TODO -// mDomObject = (WXRecyclerDomObject) node; -// mDomObject.preCalculateCellWidth(); -// mLayoutType = mDomObject.getLayoutType(); + updateRecyclerAttr(); mTemplateViewTypes = new ArrayMap<>(); @@ -209,18 +209,12 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp mTemplateSources = new HashMap<>(); mTemplatesCache = new ConcurrentHashMap<>(); mStickyHelper = new TemplateStickyHelper(this); - // TODO -// orientation = mDomObject.getOrientation(); + orientation = basicComponentData.getAttrs().getOrientation(); listDataTemplateKey = WXUtils.getString(getAttrs().get(Constants.Name.Recycler.LIST_DATA_TEMPLATE_SWITCH_KEY), Constants.Name.Recycler.SLOT_TEMPLATE_CASE); listDataItemKey = WXUtils.getString(getAttrs().get(Constants.Name.Recycler.LIST_DATA_ITEM), listDataItemKey); listDataIndexKey = WXUtils.getString(getAttrs().get(Constants.Name.Recycler.LIST_DATA_ITEM_INDEX), listDataIndexKey); cellDataManager = new CellDataManager(this); - if(getAttrs().get(Constants.Name.Recycler.LIST_DATA) instanceof JSONArray) { - JSONArray array = (JSONArray) getAttrs().get(Constants.Name.Recycler.LIST_DATA); - if(array.size() > 0) { - cellDataManager.listData = array; - } - } + cellDataManager.listData = parseListDataToJSONArray(getAttrs().get(Constants.Name.Recycler.LIST_DATA)); /** * we have separate cell with list, post add cell in dom thread ensure * list has layout and can archive better user experience and better load time, @@ -413,7 +407,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp if(template == null){ return; } - if(cellDataManager.listData == null || mStickyHelper == null){ + if(mStickyHelper == null){ return; } if(!mStickyHelper.getStickyTypes().contains(template.getRef())){ @@ -426,7 +420,6 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp public void unbindStickStyle(WXComponent component) { WXComponent template = findParentType(component, WXCell.class); if(template == null - || cellDataManager.listData == null || mStickyHelper == null){ return; } @@ -483,11 +476,39 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp @Override public void bindAppearEvent(WXComponent component) { setAppearanceWatch(component, AppearanceHelper.APPEAR, true); + if(mAppearChangeRunnable == null){ + mAppearChangeRunnable = new Runnable() { + @Override + public void run() { + if(mAppearChangeRunnable != null) { + notifyAppearStateChange(0, 0, 0, 0); + } + } + }; + } + if (getHostView() != null) { + getHostView().removeCallbacks(mAppearChangeRunnable); + getHostView().postDelayed(mAppearChangeRunnable, APPEAR_CHANGE_RUNNABLE_DELAY); + } } @Override public void bindDisappearEvent(WXComponent component) { setAppearanceWatch(component, AppearanceHelper.DISAPPEAR, true); + if(mAppearChangeRunnable == null){ + mAppearChangeRunnable = new Runnable() { + @Override + public void run() { + if(mAppearChangeRunnable != null) { + notifyAppearStateChange(0, 0, 0, 0); + } + } + }; + } + if (getHostView() != null) { + getHostView().removeCallbacks(mAppearChangeRunnable); + getHostView().postDelayed(mAppearChangeRunnable, APPEAR_CHANGE_RUNNABLE_DELAY); + } } @Override @@ -652,18 +673,50 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp // domObject.setRecyclerDomObject((WXRecyclerDomObject) getDomObject()); // } mTemplateSources.put(key, (WXCell) child); - renderTemplateCellWithData((WXCell)child); if(mTemplateViewTypes.get(key) == null){ mTemplateViewTypes.put(key, mTemplateViewTypes.size()); } } } - notifyUpdateList(); + + ((WXCell) child).setCellAppendTreeListener(new WXCell.CellAppendTreeListener() { + @Override + public void onAppendTreeDone() { + checkAppendDone(false); + } + }); } } + /** + * check all the cell has append tree done, then show list + * */ + private void checkAppendDone(boolean listDone){ + if(mTemplateSources.size() == 0){ + return; + } + Set<Map.Entry<String,WXCell>> cells = mTemplateSources.entrySet(); + for(Map.Entry<String,WXCell> entry : cells){ + if(!entry.getValue().isAppendTreeDone()){ + return; + } + } + hasAppendTreeDone = true; + if(hasLayoutDone) { + notifyUpdateList(); + } + } + @Override + protected void setHostLayoutParams(BounceRecyclerView host, int width, int height, int left, int right, int top, int bottom) { + super.setHostLayoutParams(host, width, height, left, right, top, bottom); + if(!hasLayoutDone){ + hasLayoutDone = true; + hasAppendTreeDone = true; + notifyUpdateList(); + } + } /** @@ -764,6 +817,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp private void updateRecyclerAttr(){ + mLayoutType = getAttrs().getLayoutType(); mColumnCount = getAttrs().getColumnCount(); mColumnGap = getAttrs().getColumnGap(); mColumnWidth = getAttrs().getColumnWidth(); @@ -832,6 +886,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp @JSMethod public void setListData(Object param){ + param = parseListDataToJSONArray(param); boolean update = cellDataManager.listData != param; if(param instanceof JSONArray){ if(update){ @@ -1118,7 +1173,12 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp @Override public void destroy() { + if(getHostView() != null){ + if(mAppearChangeRunnable != null) { + getHostView().removeCallbacks(mAppearChangeRunnable); + mAppearChangeRunnable = null; + } getHostView().removeCallbacks(listUpdateRunnable); if(getHostView().getInnerView() != null){ getHostView().getInnerView().setAdapter(null); @@ -1163,9 +1223,10 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp templateViewHolder.setHolderPosition(position); Object data = cellDataManager.listData.get(position); CellRenderState cellRenderState = cellDataManager.getRenderState(position); - if(component.getRenderData() == data && (cellRenderState == null || !cellRenderState.isDirty())){ + if((component.getRenderData() == data && (cellRenderState == null || !cellRenderState.isDirty()))){ if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG){ - WXLogUtils.d(TAG, position + " position "+ getTemplateKey(position) + " onBindViewHolder none data update "); + WXLogUtils.d(TAG, position + " position "+ getTemplateKey(position) + " onBindViewHolder none data update " + + " component " + component.hashCode()); } return; //none update just return }else{ @@ -1174,7 +1235,8 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp component.setRenderData(data); Layouts.doLayoutAsync(templateViewHolder, true); if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG){ - WXLogUtils.d(TAG, position + " position "+ getTemplateKey(position) + " onBindViewHolder used " + (System.currentTimeMillis() - start)); + WXLogUtils.d(TAG, position + " position "+ getTemplateKey(position) + " onBindViewHolder used " + (System.currentTimeMillis() - start) + + " component " + component.hashCode()); } } } @@ -1186,7 +1248,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp if(source == null){ FrameLayout view = new FrameLayout(getContext()); view.setLayoutParams(new FrameLayout.LayoutParams(0, 0)); - return new TemplateViewHolder(view, viewType); + return new TemplateViewHolder(this, view, viewType); } WXCell component = getCellTemplateFromCache(template); boolean cacheHit = true; @@ -1208,64 +1270,22 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp WXLogUtils.d(TAG, template + " onCreateViewHolder copy used " + (System.currentTimeMillis() - start)); } } - if(component.isLazy()) { + if(component.isLazy() || component.getHostView() == null) { doCreateCellViewBindData(component, template, false); if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG) { WXLogUtils.d(TAG, template + " onCreateViewHolder cache hit " + cacheHit + " view not idle init"); } }else{ if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG) { - WXLogUtils.d(TAG, template + " onCreateViewHolder cache hit " + cacheHit + " view idle init"); + WXLogUtils.d(TAG, template + " onCreateViewHolder cache hit " + cacheHit + " view idle init " + component.hashCode() + + " " + source.hashCode()); } } - TemplateViewHolder templateViewHolder = new TemplateViewHolder(component, viewType); + TemplateViewHolder templateViewHolder = new TemplateViewHolder(this, component, viewType); return templateViewHolder; } - /** - * copy cell component from source, init render data, and return source - * if none data, return null - * */ - public WXComponent copyComponentFromSourceCell(WXCell cell){ - renderTemplateCellWithData(cell); - WXCell component = (WXCell) Statements.copyComponentTree(cell); - // TODO -// if(component.getDomObject() instanceof WXCellDomObject -// && getDomObject() instanceof WXRecyclerDomObject){ -// WXCellDomObject domObject = (WXCellDomObject) component.getDomObject(); -// domObject.setRecyclerDomObject((WXRecyclerDomObject) getDomObject()); -// } - component.setRenderData(cell.getRenderData()); - return component; - } - - /** - * render init with cell with one data, - * if template has already render with data, done nothing - * @param cell - * */ - private synchronized void renderTemplateCellWithData(WXCell cell){ - if(cell.getRenderData() == null){ - if(cellDataManager.listData != null && cellDataManager.listData.size() > 0){ - synchronized (this){ - if(cell.getRenderData() == null){ - for(int i = 0; i< cellDataManager.listData.size(); i++){ - if(cell == getSourceTemplate(i)){ - Object data = cellDataManager.listData.get(i); - doRenderTemplate(cell, i); - Layouts.doSafeLayout(cell -// , new CSSLayoutContext() - ); - cell.setRenderData(data); - break; - } - } - } - } - } - } - } /** * @param position @@ -1391,6 +1411,12 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp @Override public int getItemCount() { + if(!hasLayoutDone){ + return 0; + } + if(!hasAppendTreeDone){ + return 0; + } if(cellDataManager.listData == null){ return 0; } @@ -1474,6 +1500,10 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp || mAppearHelpers.size() <= 0){ return; } + if(mAppearChangeRunnable != null) { + getHostView().removeCallbacks(mAppearChangeRunnable); + mAppearChangeRunnable = null; + } String direction = directionY > 0 ? Constants.Value.DIRECTION_UP : directionY < 0 ? Constants.Value.DIRECTION_DOWN : null; if (getOrientation() == Constants.Orientation.HORIZONTAL && directionX != 0) { @@ -1660,7 +1690,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp * find certain class type parent * */ public WXComponent findParentType(WXComponent component, Class type){ - if(component.getClass() == type){ + if(type.isAssignableFrom(component.getClass())){ return component; } if(component.getParent() != null) { @@ -1744,12 +1774,49 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp } /** + * copy cell component from source, init render data, and return source + * if none data, return null + * */ + public WXComponent copyComponentFromSourceCell(WXCell cell){ + renderTemplateCellWithData(cell); + WXCell component = (WXCell) Statements.copyComponentTree(cell); + return component; + } + + /** + * render init with cell with one data, + * if template has already render with data, done nothing + * @param cell + * */ + private synchronized void renderTemplateCellWithData(WXCell cell){ + if(cell.getRenderData() == null){ + if(cellDataManager.listData != null && cellDataManager.listData.size() > 0){ + synchronized (this){ + if(cell.getRenderData() == null){ + Statements.parseStatementsToken(cell); + for(int i = 0; i< cellDataManager.listData.size(); i++){ + if(cell == getSourceTemplate(i)){ + Object data = cellDataManager.listData.get(i); + doRenderTemplate(cell, i); + Layouts.doLayoutSync(cell, getLayoutWidth(), getLayoutHeight()); + cell.setRenderData(data); + break; + } + } + } + } + } + } + } + + + /** * create view for lazy cell and bind data * */ public static void doCreateCellViewBindData(WXCell component, String template, boolean inPreload){ - if(component.isLazy()){ + if(component.isLazy() || component.getHostView() == null){ long start = System.currentTimeMillis(); - ComponentUtils.initLazyComponent(component, null); + Statements.initLazyComponent(component, null); if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG) { WXLogUtils.d(TAG, " doCreateCellViewBindData " + template + " in preload "+ inPreload + " used " + (System.currentTimeMillis() - start)); } @@ -1778,4 +1845,20 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp public CellDataManager getCellDataManager() { return cellDataManager; } + + + private JSONArray parseListDataToJSONArray(Object value){ + try{ + if(value instanceof JSONArray){ + return (JSONArray) value; + } + if(value instanceof String){ + JSONArray array = JSONArray.parseArray(getAttrs().get(Constants.Name.Recycler.LIST_DATA).toString()); + return array; + } + }catch (Exception e){ + WXLogUtils.e(TAG, "parseListDataException" + e.getMessage()); + } + return new JSONArray(); + } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/jni/NativeRenderObjectUtils.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/jni/NativeRenderObjectUtils.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/jni/NativeRenderObjectUtils.java new file mode 100644 index 0000000..c477413 --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/jni/NativeRenderObjectUtils.java @@ -0,0 +1,78 @@ +/** + * 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.jni; + +import android.util.Log; + +import com.taobao.weex.base.CalledByNative; +import com.taobao.weex.ui.component.WXComponent; + +/** + * Created by furture on 2018/5/3. + */ + +public class NativeRenderObjectUtils { + + + /** + * getRenderObject + * */ + public static native long nativeGetRenderObject(String instanceId, String ref); + + /** + * render object layout + * */ + public static native void nativeUpdateRenderObjectStyle(long ptr, String key, String value); + public static native void nativeUpdateRenderObjectAttr(long ptr, String key, String value); + + /** + * copy render object + * */ + public static native long nativeCopyRenderObject(long ptr); + + /** + * layout render object + * */ + public static native int nativeLayoutRenderObject(long ptr, float width, float height); + + /** + * get child length + * */ + public static native void nativeAddChildRenderObject(long parent, long child); + + /** + * get component, tranverse child and update component + * */ + public static native boolean nativeRenderObjectHasNewLayout(long ptr); + public static native int nativeRenderObjectChildCount(long ptr); + public static native long nativeRenderObjectGetChild(long ptr, int index); + public static native long nativeRenderObjectUpdateComponent(long ptr, WXComponent component); + public static native void nativeRenderObjectChildWaste(long ptr, boolean waster); + + + /** + * component size + * */ + @CalledByNative + public static void updateComponentSize(WXComponent component, float top, float bottom, float left, float right, float height, float width){ + component.updateDemission(top, bottom, left, right, height, width); + component.applyLayoutOnly(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/android/sdk/src/main/java/com/taobao/weex/ui/module/WXDomModule.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXDomModule.java b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXDomModule.java index 38daf3f..14fa644 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXDomModule.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXDomModule.java @@ -23,10 +23,12 @@ import com.alibaba.fastjson.JSONObject; import com.taobao.weex.WXSDKInstance; import com.taobao.weex.bridge.WXBridgeManager; import com.taobao.weex.common.WXModule; +import com.taobao.weex.dom.binding.JSONUtils; import com.taobao.weex.ui.action.ActionAddRule; import com.taobao.weex.ui.action.ActionGetComponentRect; import com.taobao.weex.ui.action.ActionInvokeMethod; import com.taobao.weex.ui.action.GraphicActionScrollToElement; +import com.taobao.weex.ui.action.UpdateComponentDataAction; import com.taobao.weex.utils.WXLogUtils; /** @@ -46,6 +48,8 @@ public final class WXDomModule extends WXModule { public static final String WXDOM = "dom"; public static final String INVOKE_METHOD = "invokeMethod"; + public static final String UPDATE_COMPONENT_DATA = "updateComponentData"; + /** * Methods expose to js. Every method which will be called in js should add to this array. */ @@ -108,6 +112,12 @@ public final class WXDomModule extends WXModule { .executeAction(); break; } + case UPDATE_COMPONENT_DATA: + if(args == null || args.size() < 3){ + return null; + } + new UpdateComponentDataAction(mWXSDKInstance.getInstanceId(), args.getString(0), JSONUtils.toJSON(args.get(1)), args.getString(2)).executeAction(); + break; default: WXLogUtils.e("Unknown dom action."); break; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/weex_core/Source/CMakeLists.txt b/weex_core/Source/CMakeLists.txt index 478680a..ef92a1f 100644 --- a/weex_core/Source/CMakeLists.txt +++ b/weex_core/Source/CMakeLists.txt @@ -37,6 +37,7 @@ add_library(weexjsc SHARED ./android/bridge/impl/measure_mode_impl_android.cpp ./android/bridge/impl/content_box_measurement_impl_android.cpp ./android/bridge/impl/jsfunction_impl_android.cpp + ./android/bridge/impl/native_render_object_utils_impl_android.cpp ./android/jsengine/multiprocess/WeexJSConnection.cpp ./android/jsengine/multiprocess/WeexProxy.cpp http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp b/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp index 9e0dc9b..27a4b92 100644 --- a/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp +++ b/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp @@ -472,7 +472,8 @@ namespace WeexCore { std::set<std::string> *events, const WXCoreMargin &margins, const WXCorePadding &paddings, - const WXCoreBorderWidth &borders) { + const WXCoreBorderWidth &borders, + bool willLayout) { JNIEnv *env = getJNIEnv(); jstring jPageId = env->NewStringUTF(pageId); jstring jRef = env->NewStringUTF(ref); @@ -535,7 +536,7 @@ namespace WeexCore { if (jCallAddElementMethodId == NULL) jCallAddElementMethodId = env->GetMethodID(jBridgeClazz, "callAddElement", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/util/HashMap;Ljava/util/HashMap;Ljava/util/HashSet;[F[F[F)I"); + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/util/HashMap;Ljava/util/HashMap;Ljava/util/HashSet;[F[F[FZ)I"); jstring jComponentType = getComponentTypeFromCache(componentType); if (jComponentType == nullptr) { @@ -544,7 +545,7 @@ namespace WeexCore { int flag = 0; flag = env->CallIntMethod(jThis, jCallAddElementMethodId, jPageId, jComponentType, jRef, index, - jParentRef, jStyles, jAttributes, jEvents, jMargins, jPaddings, jBorders); + jParentRef, jStyles, jAttributes, jEvents, jMargins, jPaddings, jBorders, willLayout); page->CallBridgeTime(getCurrentTime() - startTimeCallBridge); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/android/bridge/impl/bridge_impl_android.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/bridge/impl/bridge_impl_android.h b/weex_core/Source/android/bridge/impl/bridge_impl_android.h index 3f73370..fee8942 100644 --- a/weex_core/Source/android/bridge/impl/bridge_impl_android.h +++ b/weex_core/Source/android/bridge/impl/bridge_impl_android.h @@ -101,7 +101,8 @@ namespace WeexCore { std::set<std::string> *events, const WXCoreMargin &margins, const WXCorePadding &paddings, - const WXCoreBorderWidth &borders); + const WXCoreBorderWidth &borders, + bool willLayout= true); int callRemoveElement(const char* pageId, const char* ref); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/android/bridge/impl/native_render_object_utils_impl_android.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/bridge/impl/native_render_object_utils_impl_android.cpp b/weex_core/Source/android/bridge/impl/native_render_object_utils_impl_android.cpp new file mode 100644 index 0000000..6d43347 --- /dev/null +++ b/weex_core/Source/android/bridge/impl/native_render_object_utils_impl_android.cpp @@ -0,0 +1,209 @@ +/** + * 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. + */ +// +// Created by furture on 2018/5/4. +// + +#include "native_render_object_utils_impl_android.h" +#include <android/base/jni/android_jni.h> +#include <android/jniprebuild/jniheader/NativeRenderObjectUtils_jni.h> +#include <core/render/page/render_page.h> +#include <core/render/manager/render_manager.h> +#include <android/base/string/string_utils.h> +#include <core/render/node/factory/render_creator.h> +#include <core/render/node/render_object.h> +#include <core/render/node/factory/render_type.h> +#include <android/log.h> +#include <core/render/node/render_list.h> + + +using namespace WeexCore; + +namespace WeexCore { + bool RegisterJNINativeRenderObjectUtils(JNIEnv *env){ + RegisterNativesImpl(env); + return true; + } +} + + + +static jlong GetRenderObject(JNIEnv* env, jclass jcaller, + jstring instanceId, + jstring ref){ + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page == nullptr){ + return 0; + } + + RenderObject *render = page->GetRenderObject(jString2StrFast(env, ref)); + if (render == nullptr){ + return 0; + } + return convert_render_object_to_long(render); +} + + + +static void UpdateRenderObjectStyle(JNIEnv* env, jclass jcaller, + jlong ptr, + jstring key, + jstring value){ + + RenderObject *render = convert_long_to_render_object(ptr); + render->UpdateStyle(jString2StrFast(env, key), jString2StrFast(env, value)); +} + +static void UpdateRenderObjectAttr(JNIEnv* env, jclass jcaller, + jlong ptr, + jstring key, + jstring value){ + RenderObject *render = convert_long_to_render_object(ptr); + render->UpdateAttr(jString2StrFast(env, key), jString2StrFast(env, value)); + render->markDirty(true); +} + +static jlong CopyRenderObject(JNIEnv* env, jclass jcaller, jlong ptr){ + RenderObject *render = convert_long_to_render_object(ptr); + RenderObject *copy = (RenderObject*)RenderCreator::GetInstance()->CreateRender(render->Type(), render->Ref()); + copy->copyFrom(render); + if(render->Type() == WeexCore::kRenderCellSlot || render->Type() == WeexCore::kRenderCell){ + RenderList* renderList = static_cast<RenderList*>(render->getParent()); + if(renderList != nullptr){ + renderList->addCellSlotCopyTrack(copy); + }else{ + __android_log_print(ANDROID_LOG_ERROR, " LayoutRenderObject","copy error parent null"); + } + } + return convert_render_object_to_long(copy); +} + +static void showRenderObjectLayout(RenderObject *renderObject, int level){ + LOGE("RenderObject", "layout %s %d %p %f %f %f %f ", renderObject->Type().c_str(), + renderObject->getStypePositionType(), + renderObject, renderObject->getLayoutHeight(), renderObject->getLayoutWidth(), + renderObject->getLayoutPositionLeft(), renderObject->getLayoutPositionRight()); + for(auto it = renderObject->ChildListIterBegin(); it != renderObject->ChildListIterEnd(); it++){ + RenderObject* child = static_cast<RenderObject*>(*it); + showRenderObjectLayout(child, level + 1); + } +} + +static jint LayoutRenderObject(JNIEnv* env, jclass jcaller, + jlong ptr, + jfloat width, + jfloat height){ + if(width <= 0){ + width = WXCoreEnvironment::getInstance()->DeviceWidth(); + } + + std::pair<float,float> renderPageSize; + renderPageSize.first= width; + + if(height > 0){ + renderPageSize.second = height; + }else{ + renderPageSize.second = NAN; + } + + RenderObject *render = convert_long_to_render_object(ptr); + if(render->Type() == WeexCore::kRenderCell || render->Type() == WeexCore::kRenderCellSlot){ + RenderList* renderList = static_cast<RenderList*>(render->getParent()); + if(renderList != nullptr){ + if(renderList->getColumnCount() > 1 && renderList->getColumnWidth() > 0){ + renderPageSize.first = renderList->getColumnWidth(); + } + } + } + + if(render->getStyleWidth() != renderPageSize.first){ + render->setStyleWidth(renderPageSize.first, true); + render->setStyleWidthLevel(CSS_STYLE); + } + + render->LayoutBefore(); + render->calculateLayout(renderPageSize); + render->LayoutAfter(); + + return (jint)render->getLayoutHeight(); +} + + + + +static jboolean RenderObjectHasNewLayout(JNIEnv* env, jclass jcaller, + jlong ptr){ + RenderObject* renderObject = convert_long_to_render_object(ptr); + return renderObject->hasNewLayout(); +} + +static jint RenderObjectChildCount(JNIEnv* env, jclass jcaller, + jlong ptr){ + RenderObject* renderObject = convert_long_to_render_object(ptr); + return renderObject->getChildCount(); +} + +static jlong RenderObjectGetChild(JNIEnv* env, jclass jcaller, + jlong ptr, + jint index){ + RenderObject* parent = convert_long_to_render_object(ptr); + RenderObject* child = (RenderObject *) parent->getChildAt(index); + return convert_render_object_to_long(child); +} + +static jlong RenderObjectUpdateComponent(JNIEnv* env, jclass jcaller, + jlong ptr, + jobject component){ + RenderObject* renderObject = convert_long_to_render_object(ptr); + float mTop = renderObject->getLayoutPositionTop(); + float mBottom = renderObject->getLayoutPositionBottom(); + float mRight = renderObject->getLayoutPositionRight(); + float mLeft = renderObject->getLayoutPositionLeft(); + float mHeight = renderObject->getLayoutHeight(); + float mWidth = renderObject->getLayoutWidth(); + Java_NativeRenderObjectUtils_updateComponentSize(env, component,mTop, mBottom,mLeft, mRight, mHeight, mWidth); + renderObject->setHasNewLayout(false); +} + + +static void RenderObjectChildWaste(JNIEnv* env, jclass jcaller, + jlong ptr, + jboolean waster){ + RenderObject* renderObject = convert_long_to_render_object(ptr); + if(waster){ + if(renderObject->getStypePositionType() != WXCorePositionType::kFixed){ + renderObject->setStylePositionType(WXCorePositionType::kFixed); + } + }else{ + if(renderObject->getStypePositionType() != WXCorePositionType::kRelative){ + renderObject->setStylePositionType(WXCorePositionType::kRelative); + } + } +} + + + + +static void AddChildRenderObject(JNIEnv* env, jclass jcaller, + jlong parent, + jlong child){ + RenderObject *renderParent = convert_long_to_render_object(parent); + RenderObject *renderChild = convert_long_to_render_object(child); + renderParent->AddRenderObject(-1, renderChild); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/android/bridge/impl/native_render_object_utils_impl_android.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/bridge/impl/native_render_object_utils_impl_android.h b/weex_core/Source/android/bridge/impl/native_render_object_utils_impl_android.h new file mode 100644 index 0000000..4887659 --- /dev/null +++ b/weex_core/Source/android/bridge/impl/native_render_object_utils_impl_android.h @@ -0,0 +1,34 @@ +/** + * 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. + */ +// +// Created by furture on 2018/5/4. +// + +#ifndef WEEX_PROJECT_NATIVE_RENDER_OBJECT_UTILS_IMPL_ANDROID_H +#define WEEX_PROJECT_NATIVE_RENDER_OBJECT_UTILS_IMPL_ANDROID_H + + +#include <jni.h> + +namespace WeexCore{ + bool RegisterJNINativeRenderObjectUtils(JNIEnv *env); +} + + +#endif //WEEX_PROJECT_NATIVE_RENDER_OBJECT_UTILS_IMPL_ANDROID_H http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp b/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp index 133b2ed..d5dcd10 100644 --- a/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp +++ b/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp @@ -115,6 +115,15 @@ static void BindMeasurementToWXCore(JNIEnv *env, jobject jcaller, jstring instan render->BindMeasureFuncImplAndroid(contentBoxMeasurement); } +static void BindMeasurementToRenderObject(JNIEnv* env, jobject jcaller, + jlong ptr, + jobject contentBoxMeasurement){ + RenderObject *render = convert_long_to_render_object(ptr); + if(render){ + render->BindMeasureFuncImplAndroid(contentBoxMeasurement); + } +} + static void OnInstanceClose(JNIEnv *env, jobject jcaller, jstring instanceId) { RenderManager::GetInstance()->ClosePage(jString2StrFast(env, instanceId)); } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/android/jniprebuild/jni_files ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/jniprebuild/jni_files b/weex_core/Source/android/jniprebuild/jni_files index 5aadd44..0fc5493 100644 --- a/weex_core/Source/android/jniprebuild/jni_files +++ b/weex_core/Source/android/jniprebuild/jni_files @@ -1,3 +1,4 @@ +com/taobao/weex/ui/component/list/template/jni/NativeRenderObjectUtils.java com/taobao/weex/base/SystemMessageHandler.java com/taobao/weex/bridge/WXBridge.java com/taobao/weex/layout/MeasureMode.java http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/android/jniprebuild/jni_load.cc ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/jniprebuild/jni_load.cc b/weex_core/Source/android/jniprebuild/jni_load.cc index 77ffb7f..365ebbd 100644 --- a/weex_core/Source/android/jniprebuild/jni_load.cc +++ b/weex_core/Source/android/jniprebuild/jni_load.cc @@ -4,6 +4,7 @@ #include <android/bridge/impl/measure_mode_impl_android.h> #include <android/bridge/impl/content_box_measurement_impl_android.h> #include <android/bridge/impl/jsfunction_impl_android.h> +#include <android/bridge/impl/native_render_object_utils_impl_android.h> jint JNI_OnLoad (JavaVM *vm, void *reserved) { @@ -18,6 +19,7 @@ jint JNI_OnLoad (JavaVM *vm, void *reserved) WeexCore::RegisterJNIMeasureMode(env); WeexCore::RegisterJNIContentBoxMeasurement(env); WeexCore::RegisterWXJsFunction(env); + WeexCore::RegisterJNINativeRenderObjectUtils(env); return WeexCore::OnLoad(vm, reserved); } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/android/jniprebuild/jniheader/ContentBoxMeasurement_jni.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/jniprebuild/jniheader/ContentBoxMeasurement_jni.h b/weex_core/Source/android/jniprebuild/jniheader/ContentBoxMeasurement_jni.h index 38bc77b..05c62f7 100644 --- a/weex_core/Source/android/jniprebuild/jniheader/ContentBoxMeasurement_jni.h +++ b/weex_core/Source/android/jniprebuild/jniheader/ContentBoxMeasurement_jni.h @@ -3,7 +3,7 @@ // found in the LICENSE file. // This file is autogenerated by -// weex_core_debug/Source/WeexCore/platform/android/jniprebuild/jni_generator.py +// weex-core2/weex_core/Source/android/jniprebuild/jni_generator.py // For // com/taobao/weex/layout/ContentBoxMeasurement http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/android/jniprebuild/jniheader/NativeRenderObjectUtils_jni.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/jniprebuild/jniheader/NativeRenderObjectUtils_jni.h b/weex_core/Source/android/jniprebuild/jniheader/NativeRenderObjectUtils_jni.h new file mode 100644 index 0000000..0a100e2 --- /dev/null +++ b/weex_core/Source/android/jniprebuild/jniheader/NativeRenderObjectUtils_jni.h @@ -0,0 +1,200 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is autogenerated by +// /Users/furture/weex- +// core2/weex_core/Source/android/jniprebuild/jni_generator.py +// For +// com/taobao/weex/ui/component/list/template/jni/NativeRenderObjectUtils + +#ifndef com_taobao_weex_ui_component_list_template_jni_NativeRenderObjectUtils_JNI +#define com_taobao_weex_ui_component_list_template_jni_NativeRenderObjectUtils_JNI + +#include <jni.h> + +//#include "base/android/jni_int_wrapper.h" + +// Step 1: forward declarations. +namespace { +const char kNativeRenderObjectUtilsClassPath[] = + "com/taobao/weex/ui/component/list/template/jni/NativeRenderObjectUtils"; +// Leaking this jclass as we cannot use LazyInstance from some threads. +jclass g_NativeRenderObjectUtils_clazz = NULL; +#define NativeRenderObjectUtils_clazz(env) g_NativeRenderObjectUtils_clazz + +} // namespace + +static jlong GetRenderObject(JNIEnv* env, jclass jcaller, + jstring instanceId, + jstring ref); + +static void UpdateRenderObjectStyle(JNIEnv* env, jclass jcaller, + jlong ptr, + jstring key, + jstring value); + +static void UpdateRenderObjectAttr(JNIEnv* env, jclass jcaller, + jlong ptr, + jstring key, + jstring value); + +static jlong CopyRenderObject(JNIEnv* env, jclass jcaller, + jlong ptr); + +static jint LayoutRenderObject(JNIEnv* env, jclass jcaller, + jlong ptr, + jfloat width, + jfloat height); + +static void AddChildRenderObject(JNIEnv* env, jclass jcaller, + jlong parent, + jlong child); + +static jboolean RenderObjectHasNewLayout(JNIEnv* env, jclass jcaller, + jlong ptr); + +static jint RenderObjectChildCount(JNIEnv* env, jclass jcaller, + jlong ptr); + +static jlong RenderObjectGetChild(JNIEnv* env, jclass jcaller, + jlong ptr, + jint index); + +static jlong RenderObjectUpdateComponent(JNIEnv* env, jclass jcaller, + jlong ptr, + jobject component); + +static void RenderObjectChildWaste(JNIEnv* env, jclass jcaller, + jlong ptr, + jboolean waster); + +// Step 2: method stubs. + +static intptr_t g_NativeRenderObjectUtils_updateComponentSize = 0; +static void Java_NativeRenderObjectUtils_updateComponentSize(JNIEnv* env, + jobject component, + jfloat top, + jfloat bottom, + jfloat left, + jfloat right, + jfloat height, + jfloat width) { + /* Must call RegisterNativesImpl() */ + //CHECK_CLAZZ(env, NativeRenderObjectUtils_clazz(env), + // NativeRenderObjectUtils_clazz(env)); + jmethodID method_id = + base::android::GetMethod( + env, NativeRenderObjectUtils_clazz(env), + base::android::STATIC_METHOD, + "updateComponentSize", + +"(" +"Lcom/taobao/weex/ui/component/WXComponent;" +"F" +"F" +"F" +"F" +"F" +"F" +")" +"V", + &g_NativeRenderObjectUtils_updateComponentSize); + + env->CallStaticVoidMethod(NativeRenderObjectUtils_clazz(env), + method_id, component, top, bottom, left, right, height, width); + base::android::CheckException(env); + +} + +// Step 3: RegisterNatives. + +static const JNINativeMethod kMethodsNativeRenderObjectUtils[] = { + { "nativeGetRenderObject", +"(" +"Ljava/lang/String;" +"Ljava/lang/String;" +")" +"J", reinterpret_cast<void*>(GetRenderObject) }, + { "nativeUpdateRenderObjectStyle", +"(" +"J" +"Ljava/lang/String;" +"Ljava/lang/String;" +")" +"V", reinterpret_cast<void*>(UpdateRenderObjectStyle) }, + { "nativeUpdateRenderObjectAttr", +"(" +"J" +"Ljava/lang/String;" +"Ljava/lang/String;" +")" +"V", reinterpret_cast<void*>(UpdateRenderObjectAttr) }, + { "nativeCopyRenderObject", +"(" +"J" +")" +"J", reinterpret_cast<void*>(CopyRenderObject) }, + { "nativeLayoutRenderObject", +"(" +"J" +"F" +"F" +")" +"I", reinterpret_cast<void*>(LayoutRenderObject) }, + { "nativeAddChildRenderObject", +"(" +"J" +"J" +")" +"V", reinterpret_cast<void*>(AddChildRenderObject) }, + { "nativeRenderObjectHasNewLayout", +"(" +"J" +")" +"Z", reinterpret_cast<void*>(RenderObjectHasNewLayout) }, + { "nativeRenderObjectChildCount", +"(" +"J" +")" +"I", reinterpret_cast<void*>(RenderObjectChildCount) }, + { "nativeRenderObjectGetChild", +"(" +"J" +"I" +")" +"J", reinterpret_cast<void*>(RenderObjectGetChild) }, + { "nativeRenderObjectUpdateComponent", +"(" +"J" +"Lcom/taobao/weex/ui/component/WXComponent;" +")" +"J", reinterpret_cast<void*>(RenderObjectUpdateComponent) }, + { "nativeRenderObjectChildWaste", +"(" +"J" +"Z" +")" +"V", reinterpret_cast<void*>(RenderObjectChildWaste) }, +}; + +static bool RegisterNativesImpl(JNIEnv* env) { + + g_NativeRenderObjectUtils_clazz = reinterpret_cast<jclass>(env->NewGlobalRef( + base::android::GetClass(env, kNativeRenderObjectUtilsClassPath).Get())); + + const int kMethodsNativeRenderObjectUtilsSize = + sizeof(kMethodsNativeRenderObjectUtils)/sizeof(kMethodsNativeRenderObjectUtils[0]); + + if (env->RegisterNatives(NativeRenderObjectUtils_clazz(env), + kMethodsNativeRenderObjectUtils, + kMethodsNativeRenderObjectUtilsSize) < 0) { + //jni_generator::HandleRegistrationError( + // env, NativeRenderObjectUtils_clazz(env), __FILE__); + return false; + } + + return true; +} + +#endif // com_taobao_weex_ui_component_list_template_jni_NativeRenderObjectUtils_JNI http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/android/jniprebuild/jniheader/WXBridge_jni.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/jniprebuild/jniheader/WXBridge_jni.h b/weex_core/Source/android/jniprebuild/jniheader/WXBridge_jni.h index c3b99c3..201799f 100644 --- a/weex_core/Source/android/jniprebuild/jniheader/WXBridge_jni.h +++ b/weex_core/Source/android/jniprebuild/jniheader/WXBridge_jni.h @@ -3,7 +3,7 @@ // found in the LICENSE file. // This file is autogenerated by -// weex_core_debug/Source/WeexCore/platform/android/jniprebuild/jni_generator.py +// weex-core2/weex_core/Source/android/jniprebuild/jni_generator.py // For // com/taobao/weex/bridge/WXBridge @@ -73,6 +73,10 @@ static void BindMeasurementToWXCore(JNIEnv* env, jobject jcaller, jstring ref, jobject contentBoxMeasurement); +static void BindMeasurementToRenderObject(JNIEnv* env, jobject jcaller, + jlong ptr, + jobject contentBoxMeasurement); + static void SetRenderContainerWrapContent(JNIEnv* env, jobject jcaller, jboolean wrap, jstring instanceId); @@ -218,6 +222,12 @@ static const JNINativeMethod kMethodsWXBridge[] = { "Lcom/taobao/weex/layout/ContentBoxMeasurement;" ")" "V", reinterpret_cast<void*>(BindMeasurementToWXCore) }, + { "nativeBindMeasurementToRenderObject", +"(" +"J" +"Lcom/taobao/weex/layout/ContentBoxMeasurement;" +")" +"V", reinterpret_cast<void*>(BindMeasurementToRenderObject) }, { "nativeSetRenderContainerWrapContent", "(" "Z" http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/android/jniprebuild/prebuild.sh ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/jniprebuild/prebuild.sh b/weex_core/Source/android/jniprebuild/prebuild.sh index a496821..c7db1fe 100755 --- a/weex_core/Source/android/jniprebuild/prebuild.sh +++ b/weex_core/Source/android/jniprebuild/prebuild.sh @@ -1,6 +1,6 @@ #!/bin/bash CURRENT_PATH=$(cd `dirname $0`; pwd) -ROOT_WEEX_JAVA_PATH=$CURRENT_PATH"../../../../android/sdk/src/main/java/" +ROOT_WEEX_JAVA_PATH=$CURRENT_PATH"/../../../../android/sdk/src/main/java/" WEEX_OUTPUT_DIR=$CURRENT_PATH"/jniheader/" WEEX_GEN_FILE=$CURRENT_PATH"/jni_generator.py" while read line http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/bridge/bridge.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/bridge/bridge.h b/weex_core/Source/core/bridge/bridge.h index 9261445..4494ac5 100644 --- a/weex_core/Source/core/bridge/bridge.h +++ b/weex_core/Source/core/bridge/bridge.h @@ -74,7 +74,8 @@ namespace WeexCore { std::set<std::string> *events, const WXCoreMargin &margins, const WXCorePadding &paddings, - const WXCoreBorderWidth &borders) = 0; + const WXCoreBorderWidth &borders, + bool willLayout= true) = 0; virtual int callLayout(const char* pageId, const char* ref, int top, int bottom, int left, int right, http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/layout/layout.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/layout/layout.h b/weex_core/Source/core/layout/layout.h index 7d50fe8..4233896 100644 --- a/weex_core/Source/core/layout/layout.h +++ b/weex_core/Source/core/layout/layout.h @@ -261,6 +261,10 @@ namespace WeexCore { } } + void copyFrom(WXCoreLayoutNode* srcNode){ + memcpy(mCssStyle, srcNode->mCssStyle, sizeof(WXCoreCSSStyle)); + } + inline void copyMeasureFunc(WXCoreLayoutNode *srcNode) { if (memcmp(&measureFunc, &srcNode->measureFunc, sizeof(WXCoreMeasureFunc)) != 0) { memcpy(&measureFunc, &srcNode->measureFunc, sizeof(WXCoreMeasureFunc)); @@ -673,6 +677,14 @@ namespace WeexCore { return mChildList.cend(); } + inline bool hasChild(const WXCoreLayoutNode* const child){ + if(std::find(mChildList.begin(), mChildList.end(), child) != mChildList.end()){ + return true; + }else{ + return false; + } + } + inline void removeChild(const WXCoreLayoutNode* const child) { for (int index = 0; index < mChildList.size(); index++) { if (child == mChildList[index]) { @@ -708,6 +720,10 @@ namespace WeexCore { return mParent; } + inline void setParent(WXCoreLayoutNode * const parent, WXCoreLayoutNode * const child) const { + child->mParent = parent; + } + inline bool isBFC(WXCoreLayoutNode* const node) const { return node->mCssStyle->mPositionType == kAbsolute || node->mCssStyle->mPositionType == kFixed; } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/parser/dom_parser.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/parser/dom_parser.cpp b/weex_core/Source/core/parser/dom_parser.cpp index b2b126f..89aac39 100644 --- a/weex_core/Source/core/parser/dom_parser.cpp +++ b/weex_core/Source/core/parser/dom_parser.cpp @@ -22,7 +22,6 @@ #include <core/render/node/render_object.h> #include <core/render/page/render_page.h> #include <core/render/node/factory/render_creator.h> -#include <android/base/log_utils.h> using namespace std; using namespace rapidjson; @@ -43,6 +42,26 @@ namespace WeexCore { return num; } + static inline int GetSplitIndex(std::string temp, const char * leftChar, const char * rightChar){ + int endIndex = temp.find(rightChar); + if(endIndex > 0) { + // has found! + int temp_length = temp.length(); + int startIndex = 0; + int leftMatchSize = matchNum(temp, leftChar, startIndex, endIndex) - 1; + while (leftMatchSize > 0 && startIndex <= endIndex && startIndex < temp_length) { + startIndex = endIndex + 1; + int markIndex = temp.find(rightChar, startIndex); + if(markIndex > 0) { + endIndex = markIndex; + leftMatchSize--; + } + leftMatchSize += matchNum(temp, leftChar, startIndex, endIndex); + } + } + return endIndex; + } + bool JsonParserHandler::Null() { st_ = kHasNull; v_.SetNull(); @@ -240,6 +259,22 @@ namespace WeexCore { return result; } + const std::string JsonParser::GetObjectStr() { + std::string temp = "{"; + temp.append(Stringify()); + int endIndex = GetSplitIndex(temp, "{", "}"); + SkipValue(); + return temp.substr(0, endIndex + 1); + } + + const std::string JsonParser::GetArrayStr() { + std::string temp = "["; + temp.append(Stringify()); + int endIndex = GetSplitIndex(temp, "[", "]"); + SkipValue(); + return temp.substr(0, endIndex + 1); + } + const char *JsonParser::Stringify() { return ss_.src_; } @@ -362,30 +397,12 @@ namespace WeexCore { } } else if (r.PeekType() == kArrayType) { RAPIDJSON_ASSERT(r.PeekType() == kArrayType); - std::string temp = "["; - temp.append(r.Stringify()); - int endIndex = temp.find(']'); - if(endIndex > 0) { - // has found! - int startIndex = 0; - int leftMatchSize = matchNum(temp, "[", startIndex, endIndex) - 1; - while (leftMatchSize > 0 && startIndex < endIndex) { - startIndex = endIndex + 1; - int markIndex = temp.find(']', startIndex); - if(markIndex > 0) { - endIndex = markIndex; - leftMatchSize--; - } - leftMatchSize += matchNum(temp, "[", startIndex, endIndex); - } - } - std::string value = temp.substr(0, endIndex + 1); + std::string value = r.GetArrayStr(); if (0 == strcmp(key, "attr")) { render->AddAttr(key2, value); } else if (0 == strcmp(key, "style")) { render->AddStyle(key2, value); } - r.SkipValue(); } else if (r.PeekType() == kTrueType) { RAPIDJSON_ASSERT(r.PeekType() == kTrueType); if (0 == strcmp(key, "attr")) { @@ -404,47 +421,40 @@ namespace WeexCore { r.SkipValue(); } else if (r.PeekType() == kObjectType) { RAPIDJSON_ASSERT(r.PeekType() == kObjectType); - std::string temp = "{"; - temp.append(r.Stringify()); - int endIndex = temp.find('}'); - if(endIndex > 0) { - // has found! - int startIndex = 0; - int leftMatchSize = matchNum(temp, "{", startIndex, endIndex) - 1; - while (leftMatchSize > 0 && startIndex < endIndex) { - startIndex = endIndex + 1; - int markIndex = temp.find('}', startIndex); - if(markIndex > 0) { - endIndex = markIndex; - leftMatchSize--; - } - leftMatchSize += matchNum(temp, "{", startIndex, endIndex); - } - } - std::string value = temp.substr(0, endIndex + 1); - + std::string value = r.GetObjectStr(); if (0 == strcmp(key, "attr")) { render->AddAttr(key2, value); } else if (0 == strcmp(key, "style")) { render->AddStyle(key2, value); } - r.SkipValue(); } else { r.SkipValue(); } } } else if (0 == strcmp(key, "event")) { - RAPIDJSON_ASSERT(r.PeekType() == kArrayType); - r.EnterArray(); - while (r.NextArrayValue()) { - RAPIDJSON_ASSERT(r.PeekType() == kStringType); - const char *temp_event = r.GetString(); - render->AddEvent(temp_event); - if (temp_event != nullptr) { - delete[]temp_event; - temp_event = nullptr; + if (r.PeekType() == kArrayType) { + RAPIDJSON_ASSERT(r.PeekType() == kArrayType); + r.EnterArray(); + while (r.NextArrayValue()) { + std::string temp_event_str; + if(r.PeekType() == kStringType) { + RAPIDJSON_ASSERT(r.PeekType() == kStringType); + const char *temp_event = r.GetString(); + temp_event_str.append(temp_event); + delete[]temp_event; + } else if(r.PeekType() == kObjectType){ + RAPIDJSON_ASSERT(r.PeekType() == kObjectType); + temp_event_str = r.GetObjectStr(); + } else { + r.SkipValue(); + } + + if (temp_event_str.length() > 0) { + render->AddEvent(temp_event_str); + } + } } - } + } else if (0 == strcmp(key, "children")) { RAPIDJSON_ASSERT(r.PeekType() == kArrayType); r.EnterArray(); @@ -476,7 +486,6 @@ namespace WeexCore { * @return {@link RenderObject*} */ RenderObject *Json2RenderObject(char *data, const std::string &pageId) { - JsonParser r(data); return ParseJsonObject(r, nullptr, 0, pageId); } @@ -512,27 +521,9 @@ namespace WeexCore { } } else if (r.PeekType() == kArrayType) { RAPIDJSON_ASSERT(r.PeekType() == kArrayType); - std::string temp = "["; - temp.append(r.Stringify()); - int endIndex = temp.find(']'); - if(endIndex > 0) { - // has found! - int startIndex = 0; - int leftMatchSize = matchNum(temp, "[", startIndex, endIndex) - 1; - while (leftMatchSize > 0 && startIndex < endIndex) { - startIndex = endIndex + 1; - int markIndex = temp.find(']', startIndex); - if(markIndex > 0) { - endIndex = markIndex; - leftMatchSize--; - } - leftMatchSize += matchNum(temp, "[", startIndex, endIndex); - } - } - std::string value = temp.substr(0, endIndex + 1); + std::string value = r.GetArrayStr(); std::pair<std::string, std::string> myPair(key, value); pairs->insert(pairs->end(), myPair); - r.SkipValue(); } else if (r.PeekType() == kTrueType) { RAPIDJSON_ASSERT(r.PeekType() == kTrueType); std::pair<std::string, std::string> myPair(key, "true"); @@ -550,25 +541,7 @@ namespace WeexCore { r.SkipValue(); } else if (r.PeekType() == kObjectType) { RAPIDJSON_ASSERT(r.PeekType() == kObjectType); - std::string temp = "{"; - temp.append(r.Stringify()); - int endIndex = temp.find('}'); - if(endIndex > 0) { - // has found! - int startIndex = 0; - int leftMatchSize = matchNum(temp, "{", startIndex, endIndex) - 1; - while (leftMatchSize > 0 && startIndex < endIndex) { - startIndex = endIndex + 1; - int markIndex = temp.find('}', startIndex); - if(markIndex > 0) { - endIndex = markIndex; - leftMatchSize--; - } - leftMatchSize += matchNum(temp, "{", startIndex, endIndex); - } - } - std::string value = temp.substr(0, endIndex + 1); - + std::string value = r.GetObjectStr(); std::pair<std::string, std::string> myPair(key, value); pairs->insert(pairs->end(), myPair); r.SkipValue(); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/parser/dom_parser.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/parser/dom_parser.h b/weex_core/Source/core/parser/dom_parser.h index f099ff2..e5ae4be 100644 --- a/weex_core/Source/core/parser/dom_parser.h +++ b/weex_core/Source/core/parser/dom_parser.h @@ -111,6 +111,10 @@ namespace WeexCore { const char *GetString(); + const std::string GetObjectStr(); + + const std::string GetArrayStr(); + const char *Stringify(); bool GetBool(); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/render/action/render_action_add_element.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action_add_element.cpp b/weex_core/Source/core/render/action/render_action_add_element.cpp index c522d41..fd039db 100644 --- a/weex_core/Source/core/render/action/render_action_add_element.cpp +++ b/weex_core/Source/core/render/action/render_action_add_element.cpp @@ -21,7 +21,7 @@ namespace WeexCore { RenderActionAddElement::RenderActionAddElement(const std::string &pageId, const RenderObject *render, - const RenderObject *parent, int index) { + const RenderObject *parent, int index, bool willLayout) { this->mAttributes = render->Attributes(); this->mStyles = render->Styles(); this->mEvents = render->Events(); @@ -33,6 +33,7 @@ namespace WeexCore { this->mRef = render->Ref(); this->mParentRef = parent->Ref(); this->mIndex = index; + this->mWillLayout = willLayout; } void RenderActionAddElement::ExecuteAction() { @@ -43,7 +44,7 @@ namespace WeexCore { long long startTime = getCurrentTime(); Bridge_Impl_Android::getInstance()->callAddElement(mPageId.c_str(), mComponentType.c_str(), mRef.c_str(), mIndex, mParentRef.c_str(), mStyles, mAttributes, - mEvents, mMargins, mPaddings, mBorders); + mEvents, mMargins, mPaddings, mBorders, mWillLayout); page->JniCallTime(getCurrentTime() - startTime); page->AddElementActionJNITime(getCurrentTime() - startTime); } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/render/action/render_action_add_element.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action_add_element.h b/weex_core/Source/core/render/action/render_action_add_element.h index 4b278c8..25cc8ea 100644 --- a/weex_core/Source/core/render/action/render_action_add_element.h +++ b/weex_core/Source/core/render/action/render_action_add_element.h @@ -27,7 +27,7 @@ namespace WeexCore { public: RenderActionAddElement(const std::string &pageId, const RenderObject *render, const RenderObject *parent, - int index); + int index, bool willLayout= true); void ExecuteAction(); @@ -43,6 +43,7 @@ namespace WeexCore { std::string mParentRef; std::string mRef; int mIndex; + bool mWillLayout; }; } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/render/node/factory/i_render_object.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/node/factory/i_render_object.h b/weex_core/Source/core/render/node/factory/i_render_object.h index e101fc4..6d13569 100644 --- a/weex_core/Source/core/render/node/factory/i_render_object.h +++ b/weex_core/Source/core/render/node/factory/i_render_object.h @@ -50,6 +50,13 @@ namespace WeexCore { return mType; } + void copyFrom(IRenderObject* src){ + WXCoreLayoutNode::copyFrom(src); + SetRef(src->Ref()); + SetPageId(src->PageId()); + SetType(src->Type()); + } + private: std::string mPageId = ""; std::string mRef = ""; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/render/node/factory/render_creator.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/node/factory/render_creator.cpp b/weex_core/Source/core/render/node/factory/render_creator.cpp index 6660dfb..7318d40 100644 --- a/weex_core/Source/core/render/node/factory/render_creator.cpp +++ b/weex_core/Source/core/render/node/factory/render_creator.cpp @@ -40,13 +40,15 @@ namespace WeexCore { IRenderFactory *factory; if (type == kRenderText) { factory = new RenderTextFactory(); - } else if (type == kRenderCell || type == kRenderHeader) { + } else if (type == kRenderCell + || type == kRenderHeader + || type == kRenderCellSlot) { factory = new RenderCellFactory(); } else if (type == kRenderIndicator) { factory = new RenderIndicatorFactory(); } else if (type == kRenderInput) { factory = new RenderInputFactory(); - } else if (type == kRenderList || type == kRenderWaterfall) { + } else if (type == kRenderList || type == kRenderWaterfall || type == kRenderRecycleList) { factory = new RenderListFactory(); } else if (type == kRenderMask) { factory = new RenderMaskFactory(); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/render/node/factory/render_type.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/node/factory/render_type.h b/weex_core/Source/core/render/node/factory/render_type.h index 5a63fb1..aab8245 100644 --- a/weex_core/Source/core/render/node/factory/render_type.h +++ b/weex_core/Source/core/render/node/factory/render_type.h @@ -23,10 +23,12 @@ namespace WeexCore { constexpr char kRenderCell[] = "cell"; + constexpr char kRenderCellSlot[] = "cell-slot"; constexpr char kRenderIndicator[] = "indicator"; constexpr char kRenderInput[] = "input"; constexpr char kRenderList[] = "list"; constexpr char kHList[] = "hlist"; + constexpr char kRenderRecycleList[] = "recycle-list"; constexpr char kRenderMask[] = "mask"; constexpr char kRenderScroller[] = "scroller"; constexpr char kRenderSwitch[] = "switch"; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/render/node/render_list.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/node/render_list.h b/weex_core/Source/core/render/node/render_list.h index e4d4373..2e985bf 100644 --- a/weex_core/Source/core/render/node/render_list.h +++ b/weex_core/Source/core/render/node/render_list.h @@ -38,7 +38,45 @@ namespace WeexCore { float mAvailableWidth = 0; float mColumnGap = COLUMN_GAP_NORMAL; bool mIsSetFlex = false; + std::vector<RenderObject*> cellSlots; + std::vector<RenderObject*> cellSlotsCopys; + + public: + ~RenderList(){ + + if(cellSlotsCopys.size() > 0){ + for(auto it = cellSlotsCopys.begin(); it != cellSlotsCopys.end(); ++it){ + RenderObject* child = *it; + if(child){ + delete child; + child = nullptr; + } + } + cellSlotsCopys.clear(); + } + if(cellSlots.size() > 0){ + for(auto it = cellSlots.begin(); it != cellSlots.end(); ++it){ + RenderObject* child = *it; + if(child){ + delete child; + child = nullptr; + } + } + cellSlots.clear(); + } + } + + public: + void addCellSlotCopyTrack(RenderObject* cellSlot){ + cellSlot->setParent(this, cellSlot); + cellSlotsCopys.push_back(cellSlot); + } + + std::vector<RenderObject*> &CellSlots(){ + return cellSlots; + } + std::map<std::string, std::string> *GetDefaultStyle() { std::map<std::string, std::string> *style = new std::map<std::string, std::string>(); @@ -117,10 +155,11 @@ namespace WeexCore { } mIsPreCalculateCellWidth = true; - attrs->insert(std::pair<std::string, std::string>(COLUMN_COUNT, std::to_string(mColumnCount))); - attrs->insert(std::pair<std::string, std::string>(COLUMN_WIDTH, std::to_string(mColumnWidth))); - attrs->insert(std::pair<std::string, std::string>(COLUMN_GAP, std::to_string(mColumnGap))); - + if(getColumnCount() > 0 || getColumnWidth() > 0 || mColumnCount > COLUMN_COUNT_NORMAL){ + attrs->insert(std::pair<std::string, std::string>(COLUMN_COUNT, std::to_string(mColumnCount))); + attrs->insert(std::pair<std::string, std::string>(COLUMN_GAP, std::to_string(mColumnGap))); + attrs->insert(std::pair<std::string, std::string>(COLUMN_WIDTH, std::to_string(mColumnWidth))); + } } return attrs; } @@ -143,36 +182,57 @@ namespace WeexCore { int AddRenderObject(int index, RenderObject *child) { - index = RenderObject::AddRenderObject(index, child); + if(Type() == kRenderRecycleList + && (child->Type() == kRenderCellSlot || child->Type() == kRenderCell || child->Type() == kRenderHeader)){ + child->setParent(this, child); + cellSlots.insert(cellSlots.end(), child); + index = -1; + }else{ + index = RenderObject::AddRenderObject(index, child); + } - if (!mIsPreCalculateCellWidth) { - preCalculateCellWidth(); - } + if (!mIsPreCalculateCellWidth) { + preCalculateCellWidth(); + } - if(mColumnWidth != 0 && !isnan(mColumnWidth)) { - //LOGE("listen child->ApplyStyle %s %s", child->Ref().c_str(), std::to_string(mColumnWidth).c_str()); - AddRenderObjectWidth(child, false); - } - return index; + if(mColumnWidth != 0 && !isnan(mColumnWidth)) { + //LOGE("listen child->ApplyStyle %s %s", child->Ref().c_str(), std::to_string(mColumnWidth).c_str()); + AddRenderObjectWidth(child, false); + } + return index; } void AddRenderObjectWidth(RenderObject *child, const bool updating) { - if (Type() == kRenderWaterfall) { + if (Type() == kRenderWaterfall || Type() == kRenderRecycleList) { if(child->Type() == kRenderHeader || child->Type() == kRenderFooter) { child->ApplyStyle(WIDTH, std::to_string(mAvailableWidth), updating); - } else if (child->Type() == kRenderCell){ - child->ApplyStyle(WIDTH, std::to_string(mColumnWidth), updating); } else if (child->getStypePositionType() == kSticky) { child->ApplyStyle(WIDTH, std::to_string(GetViewPortWidth()), updating); + } else if (child->Type() == kRenderCell || child->Type() == kRenderCellSlot){ + child->ApplyStyle(WIDTH, std::to_string(mColumnWidth), updating); } } } + void UpdatePreCalculateCellAttrs(std::map<std::string, std::string> * attrs){ + if (attrs == nullptr){ + return; + } + + for (auto iter = attrs->cbegin(); iter != attrs->cend(); iter++) { + RenderObject::UpdateAttr(iter->first, iter->second); + } + if (attrs != nullptr) { + delete attrs; + attrs = nullptr; + } + } + void UpdateAttr(std::string key, std::string value) { RenderObject::UpdateAttr(key, value); if(!GetAttr(COLUMN_COUNT).empty() || !GetAttr(COLUMN_GAP).empty() || !GetAttr(COLUMN_WIDTH).empty()){ - preCalculateCellWidth(); + UpdatePreCalculateCellAttrs(preCalculateCellWidth()); if(mColumnWidth == 0 && isnan(mColumnWidth)) { return; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/render/node/render_object.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/node/render_object.h b/weex_core/Source/core/render/node/render_object.h index 6aa676b..6fa638c 100644 --- a/weex_core/Source/core/render/node/render_object.h +++ b/weex_core/Source/core/render/node/render_object.h @@ -33,6 +33,14 @@ #include <core/css/constants_value.h> #include <android/base/log_utils.h> + +#define JSON_OBJECT_MARK_CHAR '{' +#define JSON_ARRAY_MARK_CHAR '[' + +#define convert_render_object_to_long(render) ((jlong)((intptr_t)render)) + +#define convert_long_to_render_object(ptr) ((RenderObject *)((intptr_t)ptr)) + namespace WeexCore { class RenderObject; @@ -55,7 +63,7 @@ namespace WeexCore { friend class RenderPage; - private: + public: inline void LayoutBefore() { if (isDirty()) { onLayoutBefore(); @@ -95,6 +103,22 @@ namespace WeexCore { return nullptr; } + void copyFrom(RenderObject* src){ + IRenderObject::copyFrom(src); + this->mStyles->insert(src->mStyles->begin(), src->mStyles->end()); + this->mAttributes->insert(src->mAttributes->begin(), src->mAttributes->end()); + this->mEvents->insert(src->mEvents->begin(), src->mEvents->end()); + } + + inline void mapInsertOrAssign(std::map<std::string, std::string> *targetMap, const std::string& key, const std::string& value) { + std::map<std::string, std::string>::iterator it = targetMap->find(key); + if(it != targetMap->end()){ + it->second = value; + }else{ + targetMap->insert({key, value}); + } + } + protected: bool UpdateStyle(const std::string key, const std::string value, float fallback, std::function<void(float)> functor){ @@ -126,7 +150,16 @@ namespace WeexCore { void onLayoutAfter(float width, float height); + + virtual StyleType ApplyStyle(const std::string &key, const std::string &value, const bool updating) { + bool insert = false; + if(value.length() > 0 && value.at(0) == JSON_OBJECT_MARK_CHAR + || value.at(0) == JSON_ARRAY_MARK_CHAR){ + mapInsertOrAssign(mStyles, key, value); + insert = true; + } + if (key == ALIGN_ITEMS) { setAlignItems(GetWXCoreAlignItem(value)); return kTypeLayout; @@ -176,7 +209,7 @@ namespace WeexCore { return kTypeLayout; } else if (key == POSITION) { setStylePositionType(GetWXCorePositionType(value)); - mStyles->insert(std::pair<std::string, std::string>(key, value)); + mapInsertOrAssign(mStyles, key, value); return kTypeStyle; } else if (key == LEFT) { UpdateStyle(key, value, NAN, [=](float foo){setStylePosition(kPositionEdgeLeft, foo);}); @@ -236,7 +269,9 @@ namespace WeexCore { UpdateStyle(key, value, 0, [=](float foo){setPadding(kPaddingBottom, foo);}); return kTypePadding; } else { - mStyles->insert(std::pair<std::string, std::string>(key, value)); + if(!insert){ + mapInsertOrAssign(mStyles, key, value); + } return kTypeStyle; } } @@ -294,11 +329,11 @@ namespace WeexCore { } inline void AddAttr(std::string key, std::string value) { - mAttributes->insert(std::pair<std::string, std::string>(key, value)); + mapInsertOrAssign(mAttributes, key, value); } virtual void UpdateAttr(std::string key, std::string value) { - AddAttr(key, value); + mapInsertOrAssign(mAttributes, key, value); } virtual StyleType UpdateStyle(std::string key, std::string value) { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/render/node/render_text.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/node/render_text.h b/weex_core/Source/core/render/node/render_text.h index 1354624..165e8a7 100644 --- a/weex_core/Source/core/render/node/render_text.h +++ b/weex_core/Source/core/render/node/render_text.h @@ -28,9 +28,6 @@ namespace WeexCore { inline void UpdateAttr(std::string key, std::string value) { RenderObject::UpdateAttr(key, value); markDirty(); - RenderPage* page = GetRenderPage(); - if (page != nullptr) - GetRenderPage()->Batch(); } inline StyleType UpdateStyle(std::string key, std::string value) { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/render/page/render_page.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/page/render_page.cpp b/weex_core/Source/core/render/page/render_page.cpp index 5139481..6acf8be 100644 --- a/weex_core/Source/core/render/page/render_page.cpp +++ b/weex_core/Source/core/render/page/render_page.cpp @@ -34,6 +34,8 @@ #include <core/render/action/render_action_add_event.h> #include <core/render/action/render_action_remove_event.h> #include <core/css/constants_value.h> +#include <core/render/node/factory/render_type.h> +#include <core/render/node/render_list.h> #include "render_page.h" #include "core/render/manager/render_manager.h" #include "core/render/node/render_object.h" @@ -366,7 +368,7 @@ namespace WeexCore { for (auto iter = attrs->cbegin(); iter != attrs->cend(); iter++) { render->UpdateAttr((*iter).first, (*iter).second); } - + Batch(); if (attrs != nullptr) { attrs->clear(); attrs->shrink_to_fit(); @@ -507,22 +509,37 @@ namespace WeexCore { } } - void RenderPage::SendAddElementAction(RenderObject *child, RenderObject *parent, int index, bool is_recursion) { + void RenderPage::SendAddElementAction(RenderObject *child, RenderObject *parent, int index, bool is_recursion, bool willLayout) { if (child == nullptr || parent == nullptr) return; + if(parent != nullptr && parent->Type() == WeexCore::kRenderRecycleList){ + willLayout = false; + } - render_action *action = new RenderActionAddElement(PageId(), child, parent, index); + render_action *action = new RenderActionAddElement(PageId(), child, parent, index, willLayout); PostRenderAction(action); Index i = 0; for(auto it = child->ChildListIterBegin(); it != child->ChildListIterEnd(); it++) { RenderObject* grandson = static_cast<RenderObject*>(*it); if (grandson != nullptr) { - SendAddElementAction(grandson, child, i, true); + SendAddElementAction(grandson, child, i, true, willLayout); } ++i; } + if(child->Type() == WeexCore::kRenderRecycleList){ + RenderList* renderList = (RenderList*)child; + std::vector<RenderObject*>& cellSlots = renderList->CellSlots(); + for(auto it = cellSlots.begin(); it != cellSlots.end(); it++) { + RenderObject* grandson = static_cast<RenderObject*>(*it); + if (grandson != nullptr) { + SendAddElementAction(grandson, child, -1, true, willLayout); + } + ++i; + } + } + if (!is_recursion && i > 0 && child->IsAppendTree()) { SendAppendTreeCreateFinish(child->Ref()); } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/Source/core/render/page/render_page.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/page/render_page.h b/weex_core/Source/core/render/page/render_page.h index c3e1d3f..cffcc99 100644 --- a/weex_core/Source/core/render/page/render_page.h +++ b/weex_core/Source/core/render/page/render_page.h @@ -47,7 +47,7 @@ namespace WeexCore { void SendCreateBodyAction(RenderObject *render); - void SendAddElementAction(RenderObject *child, RenderObject *parent, int index, bool is_recursion); + void SendAddElementAction(RenderObject *child, RenderObject *parent, int index, bool is_recursion, bool willLayout= true); void SendRemoveElementAction(const std::string &ref); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b049f80e/weex_core/debug.sh ---------------------------------------------------------------------- diff --git a/weex_core/debug.sh b/weex_core/debug.sh new file mode 100755 index 0000000..79152ef --- /dev/null +++ b/weex_core/debug.sh @@ -0,0 +1,2 @@ +## show c plus plus crash stack +adb logcat | $NDK/ndk-stack -sym ../android/sdk/build/intermediates/cmake/debug/obj/x86
