+ [android] support the box-shadow attribute on android 4.3 or higher
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/b0e072a4 Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/b0e072a4 Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/b0e072a4 Branch: refs/heads/0.16-dev Commit: b0e072a4211d2b39cc3618c753a50efc3647cf23 Parents: 4490223 Author: misakuo <misa...@apache.org> Authored: Fri Sep 22 10:46:12 2017 +0800 Committer: misakuo <misa...@apache.org> Committed: Fri Sep 22 10:46:12 2017 +0800 ---------------------------------------------------------------------- .travis.yml | 47 +- POSSIBLE-NOTICES-FOR-BIN-DIST | 5 +- WeexSDK.podspec | 2 - android/build.gradle | 13 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../alibaba/weex/benchmark/BenchmarkTest.java | 6 +- android/sdk/libs/armeabi/libweexjsc.so | Bin 325660 -> 325660 bytes android/sdk/libs/armeabi/libweexjss.so | Bin 6754012 -> 6754016 bytes .../java/com/taobao/weex/WXSDKInstance.java | 102 +- .../appfram/websocket/WebSocketCloseCodes.java | 2 +- .../com/taobao/weex/bridge/WXBridgeManager.java | 27 +- .../java/com/taobao/weex/common/Constants.java | 2 + .../com/taobao/weex/dom/ImmutableDomObject.java | 21 +- .../main/java/com/taobao/weex/dom/WXStyle.java | 17 - .../com/taobao/weex/dom/WXTextDomObject.java | 11 +- .../com/taobao/weex/dom/action/Actions.java | 4 +- .../weex/dom/action/CreateBodyAction.java | 12 +- .../weex/dom/action/ReloadPageAction.java | 6 +- .../taobao/weex/ui/component/WXComponent.java | 143 +- .../com/taobao/weex/ui/component/WXDiv.java | 74 +- .../com/taobao/weex/ui/component/WXSlider.java | 4 +- .../com/taobao/weex/ui/component/WXText.java | 65 +- .../taobao/weex/ui/component/WXVContainer.java | 44 +- .../taobao/weex/ui/component/list/WXCell.java | 61 +- .../weex/ui/component/list/WXListComponent.java | 53 +- .../com/taobao/weex/ui/flat/FlatComponent.java | 33 + .../com/taobao/weex/ui/flat/FlatGUIContext.java | 146 ++ .../taobao/weex/ui/flat/WidgetContainer.java | 93 + .../weex/ui/flat/widget/AndroidViewWidget.java | 76 + .../taobao/weex/ui/flat/widget/BaseWidget.java | 130 ++ .../taobao/weex/ui/flat/widget/TextWidget.java | 49 + .../com/taobao/weex/ui/flat/widget/Widget.java | 51 + .../taobao/weex/ui/flat/widget/WidgetGroup.java | 54 + .../taobao/weex/ui/module/WXTimerModule.java | 9 +- .../weex/ui/view/WXBaseCircleIndicator.java | 131 +- .../com/taobao/weex/ui/view/WXFrameLayout.java | 53 +- .../weex/ui/view/border/BorderCorner.java | 37 +- .../taobao/weex/ui/view/border/BorderUtil.java | 26 - .../weex/ui/view/border/BottomLeftCorner.java | 7 +- .../weex/ui/view/border/BottomRightCorner.java | 7 +- .../weex/ui/view/border/TopLeftCorner.java | 7 +- .../weex/ui/view/border/TopRightCorner.java | 7 +- .../com/taobao/weex/utils/FunctionParser.java | 6 - .../java/com/taobao/weex/utils/LogLevel.java | 4 +- .../java/com/taobao/weex/utils/OsVersion.java | 2 +- .../main/java/com/taobao/weex/utils/Trace.java | 4 +- .../java/com/taobao/weex/utils/WXLogUtils.java | 14 + .../java/com/taobao/weex/utils/WXViewUtils.java | 31 + .../com/taobao/weex/ui/component/WXDivTest.java | 12 +- .../taobao/weex/ui/component/WXTextTest.java | 18 +- .../weex/ui/module/WXTimerModuleTest.java | 45 +- dangerfile-android.js | 108 ++ dangerfile-ios.js | 107 ++ dangerfile-jsfm.js | 105 + ios/sdk/WeexSDK.xcodeproj/project.pbxproj | 42 - .../Sources/Bridge/WXDebugLoggerBridge.h | 26 - .../Sources/Bridge/WXDebugLoggerBridge.m | 213 --- ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.m | 89 +- .../Component/Recycler/WXMultiColumnLayout.m | 32 +- .../Sources/Component/WXComponent_internal.h | 2 +- .../Sources/Component/WXImageComponent.m | 34 +- .../WeexSDK/Sources/Component/WXTextComponent.m | 6 +- .../Sources/Display/WXComponent+Display.m | 2 +- ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m | 4 - .../WeexSDK/Sources/Events/WXComponent+Events.m | 35 +- .../Sources/Manager/WXComponentManager.m | 9 +- ios/sdk/WeexSDK/Sources/Model/WXComponent.m | 30 +- .../WeexSDK/Sources/Module/WXAnimationModule.m | 26 +- .../WeexSDK/Sources/Module/WXModalUIModule.m | 4 +- .../WeexSDK/Sources/Module/WXWebSocketModule.m | 1 - ios/sdk/WeexSDK/Sources/Utility/WXConvert.m | 24 +- ios/sdk/WeexSDK/Sources/Utility/WXUtility.m | 4 + .../Sources/WebSocket/SRWebSocket+Weex.h | 29 - .../Sources/WebSocket/SRWebSocket+Weex.m | 47 - .../Sources/WebSocket/WXWebSocketDefaultImpl.h | 25 - .../Sources/WebSocket/WXWebSocketDefaultImpl.m | 121 -- ios/sdk/WeexSDK/dependency/SRWebSocket.h | 135 -- ios/sdk/WeexSDK/dependency/SRWebSocket.m | 1806 ------------------ package.json | 5 +- scripts/build_from_source.sh | 2 +- scripts/generate_apache_release.sh | 2 +- test/pages/components/iconfont.vue | 6 +- test/pages/modules/vue_timer.vue | 14 +- test/pages/modules/we_timer.we | 14 +- test/scripts/components/scroll-event.test.js | 2 +- 85 files changed, 1864 insertions(+), 3022 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/.travis.yml ---------------------------------------------------------------------- diff --git a/.travis.yml b/.travis.yml index a62ef95..dd3f139 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,11 +5,9 @@ language: node_js node_js: 7.6 rvm: 2.0.0 env: - - TEST_SUITE=ios - TEST_SUITE=danger - TEST_SUITE=jsfm - TEST_SUITE=android - - TEST_SUITE=release matrix: fast_finish: true exclude: @@ -25,16 +23,8 @@ matrix: env: TEST_SUITE=ios - os: linux env: TEST_SUITE=android - - os: osx - env: TEST_SUITE=release - - os: linux - env: TEST_SUITE=release include: - os: osx - env: TEST_SUITE=release - osx_image: xcode8.1 - language: objective-c - - os: osx env: TEST_SUITE=ios osx_image: xcode8.1 language: objective-c @@ -63,50 +53,19 @@ before_script: nvm install 7.0 npm install fi - - | - if [[ $TEST_SUITE = "ios" ]]; then - brew update - fi - - | - if [[ $TEST_SUITE = "release" ]]; then - brew update - #manual install android sdk - brew cask install android-sdk - brew install gradle - export ANDROID_HOME=/usr/local/share/android-sdk - export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools - echo yes | sdkmanager platform-tools - echo yes | sdkmanager tools #tools - echo yes | sdkmanager "build-tools;25.0.3" #build-tool - echo yes | sdkmanager "platforms;android-25" #compile target - echo yes | sdkmanager "extras;android;m2repository" #support - fi script: - | if [[ $TEST_SUITE = "android" ]]; then - cd android - ./gradlew clean assembleDebug :weex_sdk:testDebugUnitTest --info -PdisableCov=true -Dorg.gradle.daemon=true -Dorg.gradle.parallel=true -Dorg.gradle.jvmargs="-Xmx512m -XX:+HeapDumpOnOutOfMemoryError" -Dfile.encoding=UTF-8 && + npm run danger -- run --dangerfile ./dangerfile-android.js cd $TRAVIS_BUILD_DIR fi - | - if [[ $TEST_SUITE = "ios" ]]; then - xcodebuild -project ios/sdk/WeexSDK.xcodeproj test -scheme WeexSDKTests CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -destination 'platform=iOS Simulator,name=iPhone 6' - fi - - | if [[ $TEST_SUITE = "jsfm" ]]; then - npm run build && - npm run test + npm run danger -- run --dangerfile ./dangerfile-jsfm.js fi - | if [[ $TEST_SUITE = "danger" ]]; then - npm run danger - fi - - | - if [[ $TEST_SUITE = "release" ]]; then - bash scripts/generate_apache_release.sh && - cd apache_release_temp && - bash scripts/build_from_source.sh && - cd $TRAVIS_BUILD_DIR + npm run danger -- run --dangerfile ./dangerfile.js fi notifications: webhooks: http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/POSSIBLE-NOTICES-FOR-BIN-DIST ---------------------------------------------------------------------- diff --git a/POSSIBLE-NOTICES-FOR-BIN-DIST b/POSSIBLE-NOTICES-FOR-BIN-DIST index 350a00b..6efd6ee 100644 --- a/POSSIBLE-NOTICES-FOR-BIN-DIST +++ b/POSSIBLE-NOTICES-FOR-BIN-DIST @@ -99,4 +99,7 @@ This product contains software SDWebImage(https://github.com/rs/SDWebImage) deve by Olivier Poitrey , licensed under the MIT License. This product contains software Guava(https://github.com/google/guava) developed -by google , licensed under the Apache License. \ No newline at end of file +by google , licensed under the Apache License. + +This product contains shelljs Guava(https://github.com/shelljs/shelljs) developed +by shelljs , licensed under BSD 3-clause "New" or "Revised" License. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/WeexSDK.podspec ---------------------------------------------------------------------- diff --git a/WeexSDK.podspec b/WeexSDK.podspec index fbf8139..5cb6864 100644 --- a/WeexSDK.podspec +++ b/WeexSDK.podspec @@ -39,8 +39,6 @@ Pod::Spec.new do |s| s.xcconfig = { "OTHER_LINK_FLAG" => '$(inherited) -ObjC'} s.frameworks = 'CoreMedia','MediaPlayer','AVFoundation','AVKit','JavaScriptCore', 'GLKit', 'OpenGLES', 'CoreText', 'QuartzCore', 'CoreGraphics' - - s.dependency 'SocketRocket' s.libraries = "stdc++" end http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/build.gradle ---------------------------------------------------------------------- diff --git a/android/build.gradle b/android/build.gradle index 28cf76e..9c0e2d5 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -5,12 +5,13 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.3' + classpath 'com.android.tools.build:gradle:2.3.3' } } plugins { id "de.undercouch.download" version "3.2.0" +// id "com.github.dcendents.android-maven" version "1.5" } repositories { @@ -29,7 +30,9 @@ subprojects { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.3' + classpath 'com.android.tools.build:gradle:2.3.3' + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' } } ext { @@ -43,6 +46,6 @@ subprojects { } } -task clean(type: Delete) { - delete rootProject.buildDir -} +//task clean(type: Delete) { +// delete rootProject.buildDir +//} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/gradle/wrapper/gradle-wrapper.properties ---------------------------------------------------------------------- diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index d795868..73990aa 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/playground/app/src/androidTest/java/com/alibaba/weex/benchmark/BenchmarkTest.java ---------------------------------------------------------------------- diff --git a/android/playground/app/src/androidTest/java/com/alibaba/weex/benchmark/BenchmarkTest.java b/android/playground/app/src/androidTest/java/com/alibaba/weex/benchmark/BenchmarkTest.java index dddada7..5a5f74b 100644 --- a/android/playground/app/src/androidTest/java/com/alibaba/weex/benchmark/BenchmarkTest.java +++ b/android/playground/app/src/androidTest/java/com/alibaba/weex/benchmark/BenchmarkTest.java @@ -68,9 +68,7 @@ public class BenchmarkTest { private static List<Long> firstScreenRenderTime = new LinkedList<>(); private static List<Long> flingFrameSeconds = new LinkedList<>(); private static List<Long> scrollFrameSeconds = new LinkedList<>(); - private static final String DUMP_START = "Flags,IntendedVsync,Vsync,OldestInputEvent,NewestInputEvent," - + "HandleInputStart,AnimationStart,PerformTraversalsStart,DrawStart," - + "SyncQueued,SyncStart,IssueDrawCommandsStart,SwapBuffers,FrameCompleted,\n"; + private static final String DUMP_START = "QueueBufferDuration,\n"; private static final String DUMP_END = "---PROFILEDATA---"; private static final String DUMP_COMMAND = "dumpsys gfxinfo com.alibaba.weex framestats reset"; @@ -195,7 +193,7 @@ public class BenchmarkTest { private long calcTime() { BenchmarkActivity benchmarkActivity = mActivityRule.getActivity(); - benchmarkActivity.loadWeexPage(); + benchmarkActivity.loadWeexPage("http://30.8.53.163:8080/complicated.js"); onView(withClassName(Matchers.is(WXRecyclerView.class.getName()))).perform (RecyclerViewActions.scrollToPosition(0)); return benchmarkActivity.getWXInstance().getWXPerformance().screenRenderTime; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/libs/armeabi/libweexjsc.so ---------------------------------------------------------------------- diff --git a/android/sdk/libs/armeabi/libweexjsc.so b/android/sdk/libs/armeabi/libweexjsc.so index d3fb7e7..b08a455 100755 Binary files a/android/sdk/libs/armeabi/libweexjsc.so and b/android/sdk/libs/armeabi/libweexjsc.so differ http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/libs/armeabi/libweexjss.so ---------------------------------------------------------------------- diff --git a/android/sdk/libs/armeabi/libweexjss.so b/android/sdk/libs/armeabi/libweexjss.so index c0236b6..13e5bc6 100755 Binary files a/android/sdk/libs/armeabi/libweexjss.so and b/android/sdk/libs/armeabi/libweexjss.so differ http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java index 7e0da86..fcdcd0d 100644 --- a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java +++ b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java @@ -18,6 +18,8 @@ */ package com.taobao.weex; +import static com.taobao.weex.http.WXHttpUtil.KEY_USER_AGENT; + import android.app.AlertDialog; import android.content.Context; import android.content.Intent; @@ -28,13 +30,14 @@ import android.net.Uri; import android.os.Message; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.RestrictTo; +import android.support.annotation.RestrictTo.Scope; import android.text.TextUtils; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.ScrollView; - import com.alibaba.fastjson.JSONObject; import com.taobao.weex.adapter.IDrawableLoader; import com.taobao.weex.adapter.IWXHttpAdapter; @@ -68,6 +71,7 @@ import com.taobao.weex.ui.component.NestedContainer; import com.taobao.weex.ui.component.WXBasicComponentType; import com.taobao.weex.ui.component.WXComponent; import com.taobao.weex.ui.component.WXComponentFactory; +import com.taobao.weex.ui.flat.FlatGUIContext; import com.taobao.weex.ui.view.WXScrollView; import com.taobao.weex.ui.view.WXScrollView.WXScrollViewListener; import com.taobao.weex.utils.Trace; @@ -76,8 +80,6 @@ import com.taobao.weex.utils.WXJsonUtils; import com.taobao.weex.utils.WXLogUtils; import com.taobao.weex.utils.WXReflectionUtils; import com.taobao.weex.utils.WXViewUtils; -import com.taobao.weex.WXSDKEngine; - import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; @@ -86,9 +88,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import static com.taobao.weex.http.WXHttpUtil.KEY_USER_AGENT; - - /** * Each instance of WXSDKInstance represents an running weex instance. * It can be a pure weex view, or mixed with native view @@ -120,6 +119,8 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View. private boolean mNeedReLoad = false; private static volatile int mViewPortWidth = 750; private int mInstanceViewPortWidth = 750; + private @NonNull + FlatGUIContext mFlatGUIContext =new FlatGUIContext(); public long mRenderStartNanos; public int mExecJSTraceId = WXTracing.nextId(); @@ -200,6 +201,12 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View. enableLayerType = enable; } + @RestrictTo(Scope.LIBRARY) + public @NonNull + FlatGUIContext getFlatUIContext(){ + return mFlatGUIContext; + } + public boolean isNeedValidate() { return mNeedValidate; } @@ -251,6 +258,7 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View. /** * For unittest only. */ + @RestrictTo(Scope.TESTS) WXSDKInstance(Context context,String id) { mInstanceId = id; init(context); @@ -606,21 +614,23 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View. return ""; } - public void reloadPage() { + public void reloadPage(boolean reloadThis) { + WXSDKEngine.reload(); - // å¯ä»¥åé广æåï¼ - if (mContext != null) { - Intent intent = new Intent(); - intent.setAction(IWXDebugProxy.ACTION_INSTANCE_RELOAD); - intent.putExtra("url", mBundleUrl); - mContext.sendBroadcast(intent); + if (reloadThis) { + // å¯ä»¥åé广æåï¼ + if (mContext != null) { + Intent intent = new Intent(); + intent.setAction(IWXDebugProxy.ACTION_INSTANCE_RELOAD); + intent.putExtra("url", mBundleUrl); + mContext.sendBroadcast(intent); + } + // mRendered = false; + // destroy(); + // renderInternal(mPackage, mTemplate, mOptions, mJsonInitData, mFlag); + // refreshInstance("{}"); } - // mRendered = false; - // destroy(); - // renderInternal(mPackage, mTemplate, mOptions, mJsonInitData, mFlag); - // refreshInstance("{}"); - } /** * Refresh instance asynchronously. @@ -1249,35 +1259,41 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View. } public synchronized void destroy() { - WXSDKManager.getInstance().destroyInstance(mInstanceId); - WXComponentFactory.removeComponentTypesByInstanceId(getInstanceId()); + if(!isDestroy()) { + WXSDKManager.getInstance().destroyInstance(mInstanceId); + WXComponentFactory.removeComponentTypesByInstanceId(getInstanceId()); - if(mGlobalEventReceiver!=null){ - getContext().unregisterReceiver(mGlobalEventReceiver); - mGlobalEventReceiver=null; - } - if(mRootComp != null ) { - mRootComp.destroy(); - destroyView(mRenderContainer); - mRenderContainer = null; - mRootComp = null; - } + if (mGlobalEventReceiver != null) { + getContext().unregisterReceiver(mGlobalEventReceiver); + mGlobalEventReceiver = null; + } + if (mRootComp != null) { + mRootComp.destroy(); + destroyView(mRenderContainer); + mRootComp = null; + } - if(mGlobalEvents!=null){ - mGlobalEvents.clear(); - } + if (mGlobalEvents != null) { + mGlobalEvents.clear(); + } - if(mComponentObserver != null){ + if (mComponentObserver != null) { mComponentObserver = null; - } + } - mNestedInstanceInterceptor = null; - mUserTrackAdapter = null; - mScrollView = null; - mContext = null; - mRenderListener = null; - isDestroy = true; - mStatisticsListener = null; + getFlatUIContext().destroy(); + mFlatGUIContext = null; + + mWXScrollListeners = null; + mRenderContainer = null; + mNestedInstanceInterceptor = null; + mUserTrackAdapter = null; + mScrollView = null; + mContext = null; + mRenderListener = null; + isDestroy = true; + mStatisticsListener = null; + } } public boolean isDestroy(){ @@ -1484,7 +1500,7 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View. * Check whether the current module registered the event * @param eventName EventName register in weex * @param module Events occur in this Module - * @return register->true + * @return boolean true */ public boolean checkModuleEventRegistered(String eventName,WXModule module) { if (module != null) { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/appfram/websocket/WebSocketCloseCodes.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/appfram/websocket/WebSocketCloseCodes.java b/android/sdk/src/main/java/com/taobao/weex/appfram/websocket/WebSocketCloseCodes.java index 6251399..0f742ae 100644 --- a/android/sdk/src/main/java/com/taobao/weex/appfram/websocket/WebSocketCloseCodes.java +++ b/android/sdk/src/main/java/com/taobao/weex/appfram/websocket/WebSocketCloseCodes.java @@ -20,7 +20,7 @@ package com.taobao.weex.appfram.websocket; /** * Created by moxun on 17/1/3. - * @link {https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent} + * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent">CloseEvent</a> */ public enum WebSocketCloseCodes { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java index 89b2d3b..3b11387 100644 --- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java +++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java @@ -135,6 +135,9 @@ public class WXBridgeManager implements Callback,BactchExecutor { private static final int CRASHREINIT = 50; private static int reInitCount = 1; + private static String crashUrl = null; + private static long lastCrashTime = 0; + /** * next tick tasks, can set priority @@ -962,12 +965,15 @@ public class WXBridgeManager implements Callback,BactchExecutor { WXLogUtils.e("[WXBridgeManager] callReportCrashReloadPage exception: ", e); } try { + if (WXSDKManager.getInstance().getSDKInstance(instanceId) != null) { - // JSONObject domObject = JSON.parseObject(tasks); + boolean reloadThisInstance = shouReloadCurrentInstance( + WXSDKManager.getInstance().getSDKInstance(instanceId).getBundleUrl()); WXDomModule domModule = getDomModule(instanceId); - Action action = Actions.getReloadPage(instanceId); - domModule.postAction((DOMAction)action, true); + Action action = Actions.getReloadPage(instanceId, reloadThisInstance); + domModule.postAction((DOMAction) action, true); } + } catch (Exception e) { WXLogUtils.e("[WXBridgeManager] callReloadPage exception: ", e); commitJSBridgeAlarmMonitor(instanceId, WXErrorCode.WX_ERR_RELOAD_PAGE,"[WXBridgeManager] callReloadPage exception "+e.getCause()); @@ -975,6 +981,19 @@ public class WXBridgeManager implements Callback,BactchExecutor { return IWXBridge.INSTANCE_RENDERING_ERROR; } + public boolean shouReloadCurrentInstance(String aUrl) { + long time = System.currentTimeMillis(); + if (crashUrl == null || + (crashUrl != null && !crashUrl.equals(aUrl)) || + ((time - lastCrashTime) > 10000)) { + crashUrl = aUrl; + lastCrashTime = time; + return true; + } + lastCrashTime = time; + return false; + } + public void callReportCrash(String crashFile, final String instanceId, final String url) { // statistic weexjsc process crash Date date = new Date(); @@ -1809,7 +1828,7 @@ public class WXBridgeManager implements Callback,BactchExecutor { if (reInitCount > 1 && !instance.isNeedReLoad()) { // JSONObject domObject = JSON.parseObject(tasks); WXDomModule domModule = getDomModule(instanceId); - Action action = Actions.getReloadPage(instanceId); + Action action = Actions.getReloadPage(instanceId, true); domModule.postAction((DOMAction)action, true); instance.setNeedLoad(true); return; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/common/Constants.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/common/Constants.java b/android/sdk/src/main/java/com/taobao/weex/common/Constants.java index 8c87662..917fbcd 100644 --- a/android/sdk/src/main/java/com/taobao/weex/common/Constants.java +++ b/android/sdk/src/main/java/com/taobao/weex/common/Constants.java @@ -182,6 +182,8 @@ public class Constants { String ARIA_LABEL = "ariaLabel"; String ARIA_HIDDEN = "ariaHidden"; String UNDEFINED = "undefined"; + + String FLAT = "flat"; } public interface Value { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/dom/ImmutableDomObject.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/ImmutableDomObject.java b/android/sdk/src/main/java/com/taobao/weex/dom/ImmutableDomObject.java index 55439c3..c19ca59 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/ImmutableDomObject.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/ImmutableDomObject.java @@ -19,11 +19,8 @@ package com.taobao.weex.dom; import android.support.annotation.NonNull; - import com.taobao.weex.dom.flex.Spacing; -import static com.taobao.weex.dom.WXDomObject.DESTROYED; - /** * Created by sospartan on 25/10/2016. */ @@ -33,8 +30,26 @@ public interface ImmutableDomObject { @NonNull Spacing getMargin(); float getLayoutWidth(); float getLayoutHeight(); + + /** + * Use {@link #getCSSLayoutLeft()} ()} instead + */ + @Deprecated float getLayoutX(); + + /** + * Use {@link #getCSSLayoutTop()} instead + */ + @Deprecated float getLayoutY(); + + public float getCSSLayoutTop(); + + public float getCSSLayoutBottom(); + + public float getCSSLayoutLeft(); + + public float getCSSLayoutRight(); boolean isFixed(); @NonNull WXStyle getStyles(); @NonNull WXEvent getEvents(); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java index 01c25d2..6dc444a 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java @@ -346,23 +346,6 @@ public class WXStyle implements Map<String, Object>,Cloneable { return WXUtils.getFloatByViewport(get(Constants.Name.BORDER_WIDTH), viewport); } - public float getBorderRightWidth() { - return getBorderWidth(Constants.Name.BORDER_RIGHT_WIDTH); - } - - public float getBorderTopWidth() { - return getBorderWidth(Constants.Name.BORDER_TOP_WIDTH); - } - - public float getBorderBottomWidth() { - return getBorderWidth(Constants.Name.BORDER_BOTTOM_WIDTH); - } - - public float getBorderLeftWidth() { - return getBorderWidth(Constants.Name.BORDER_LEFT_WIDTH); - } - - public float getBorderRightWidth(int viewport) { return getBorderWidth(Constants.Name.BORDER_RIGHT_WIDTH, viewport); } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java index 06084a9..8adb991 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXTextDomObject.java @@ -337,12 +337,19 @@ public class WXTextDomObject extends WXDomObject { int desired, @Nullable TextUtils.TruncateAt truncateAt) { Spanned ret = new SpannedString(""); if (!TextUtils.isEmpty(source) && source.length() > 0) { - StaticLayout layout; if (truncateAt != null) { source.append(ELLIPSIS); } + + StaticLayout layout; + int startOffset; + while (source.length() > 1) { - source.delete(source.length() - 2, source.length() - 1); + startOffset = source.length() -1; + if (truncateAt != null) { + startOffset -= 1; + } + source.delete(startOffset, startOffset+1); layout = new StaticLayout(source, paint, desired, Layout.Alignment.ALIGN_NORMAL, 1, 0, true); if (layout.getLineCount() <= 1) { ret = source; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java index 6e87c68..779b4d6 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java @@ -225,7 +225,7 @@ public class Actions { return new ExecutableRenderAction(runnable); } - public static DOMAction getReloadPage(String instanceId) { - return new ReloadPageAction(instanceId); + public static DOMAction getReloadPage(String instanceId, boolean relaod) { + return new ReloadPageAction(instanceId, relaod); } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java index 8c4df7d..cd51668 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java @@ -50,11 +50,13 @@ class CreateBodyAction extends AbstractAddElementAction { @Override public void executeDom(DOMActionContext context) { - if (WXEnvironment.isApkDebugable()) { - WXTracing.TraceEvent execJsEndEvent = WXTracing.newEvent("executeBundleJS", context.getInstanceId(), -1); - execJsEndEvent.traceId = context.getInstance().mExecJSTraceId; - execJsEndEvent.ph = "E"; - execJsEndEvent.submit(); + if (WXTracing.isAvailable()) { + if (context != null && context.getInstance() != null) { + WXTracing.TraceEvent execJsEndEvent = WXTracing.newEvent("executeBundleJS", context.getInstanceId(), -1); + execJsEndEvent.traceId = context.getInstance().mExecJSTraceId; + execJsEndEvent.ph = "E"; + execJsEndEvent.submit(); + } } addDomInternal(context, mData); } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/dom/action/ReloadPageAction.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/ReloadPageAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/ReloadPageAction.java index aaf67e7..791a5f2 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/action/ReloadPageAction.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/ReloadPageAction.java @@ -36,9 +36,11 @@ import com.taobao.weex.dom.RenderActionContext; final class ReloadPageAction implements DOMAction, RenderAction { private final String TAG = "ReloadPageAction"; private String mInstanceId; + private boolean mReloadThis; - ReloadPageAction(String instanceId) { + ReloadPageAction(String instanceId, boolean reloadThis) { mInstanceId = instanceId; + mReloadThis = reloadThis; } @Override @@ -51,7 +53,7 @@ final class ReloadPageAction implements DOMAction, RenderAction { WXSDKInstance instance = context.getInstance(); if (instance != null) { // instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_SUCCESS); - instance.reloadPage(); + instance.reloadPage(mReloadThis); } else { Log.e(TAG, "ReloadPageAction executeDom reloadPage instance is null"); } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java index 88ffece..fd01aa5 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java @@ -22,6 +22,7 @@ import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; import android.graphics.Color; +import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.Shader; @@ -34,13 +35,15 @@ import android.support.annotation.CheckResult; import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.RestrictTo; +import android.support.annotation.RestrictTo.Scope; import android.support.v4.view.ViewCompat; import android.text.TextUtils; import android.view.Menu; import android.view.View; import android.view.ViewGroup; +import android.view.ViewGroup.MarginLayoutParams; import android.widget.FrameLayout; - import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.taobao.weex.ComponentObserver; @@ -66,6 +69,11 @@ import com.taobao.weex.ui.animation.WXAnimationModule; import com.taobao.weex.ui.component.pesudo.OnActivePseudoListner; import com.taobao.weex.ui.component.pesudo.PesudoStatus; import com.taobao.weex.ui.component.pesudo.TouchActivePseudoListener; +import com.taobao.weex.ui.flat.FlatComponent; +import com.taobao.weex.ui.flat.FlatGUIContext; +import com.taobao.weex.ui.flat.WidgetContainer; +import com.taobao.weex.ui.flat.widget.AndroidViewWidget; +import com.taobao.weex.ui.flat.widget.Widget; import com.taobao.weex.ui.view.border.BorderDrawable; import com.taobao.weex.ui.view.gesture.WXGesture; import com.taobao.weex.ui.view.gesture.WXGestureObservable; @@ -77,7 +85,6 @@ import com.taobao.weex.utils.WXReflectionUtils; import com.taobao.weex.utils.WXResourceUtils; import com.taobao.weex.utils.WXUtils; import com.taobao.weex.utils.WXViewUtils; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -143,6 +150,12 @@ public abstract class WXComponent<T extends View> implements IWXObject, IWXActi this.mAnimationHolder = holder; } + //This method will be removed once flatGUI is completed. + @RestrictTo(Scope.LIBRARY) + public boolean isFlatUIEnabled(){ + return mParent != null && mParent.isFlatUIEnabled(); + } + private OnClickListener mClickEventListener = new OnClickListener() { @Override public void onHostViewClick() { @@ -394,15 +407,17 @@ public abstract class WXComponent<T extends View> implements IWXObject, IWXActi protected BorderDrawable getOrCreateBorder() { if (mBackgroundDrawable == null) { - Drawable backgroundDrawable = mHost.getBackground(); - WXViewUtils.setBackGround(mHost,null); mBackgroundDrawable = new BorderDrawable(); - if (backgroundDrawable == null) { - WXViewUtils.setBackGround(mHost,mBackgroundDrawable); - } else { - //TODO Not strictly clip according to background-clip:border-box - WXViewUtils.setBackGround(mHost,new LayerDrawable(new Drawable[]{ - mBackgroundDrawable,backgroundDrawable})); + if (mHost != null) { + Drawable backgroundDrawable = mHost.getBackground(); + WXViewUtils.setBackGround(mHost, null); + if (backgroundDrawable == null) { + WXViewUtils.setBackGround(mHost, mBackgroundDrawable); + } else { + //TODO Not strictly clip according to background-clip:border-box + WXViewUtils.setBackGround(mHost, new LayerDrawable(new Drawable[]{ + mBackgroundDrawable, backgroundDrawable})); + } } } return mBackgroundDrawable; @@ -433,6 +448,9 @@ public abstract class WXComponent<T extends View> implements IWXObject, IWXActi parentBorder.get(Spacing.TOP)) + siblingOffset; int realRight = (int) margin.get(Spacing.RIGHT); int realBottom = (int) margin.get(Spacing.BOTTOM); + Point rawOffset = new Point( + (int) mDomObj.getCSSLayoutLeft(), + (int) mDomObj.getCSSLayoutTop()); if (mPreRealWidth == realWidth && mPreRealHeight == realHeight && mPreRealLeft == realLeft && mPreRealTop == realTop) { return; @@ -446,32 +464,79 @@ public abstract class WXComponent<T extends View> implements IWXObject, IWXActi mInstance.firstScreenRenderFinished(); } - if (mHost == null) { - return; - } MeasureOutput measureOutput = measure(realWidth, realHeight); realWidth = measureOutput.width; realHeight = measureOutput.height; - //fixed style - if (mDomObj.isFixed()) { - setFixedHostLayoutParams(mHost,realWidth,realHeight,realLeft,realRight,realTop,realBottom); - }else { - setHostLayoutParams(mHost, realWidth, realHeight, realLeft, realRight, realTop, realBottom); - } - - mPreRealWidth = realWidth; - mPreRealHeight = realHeight; - mPreRealLeft = realLeft; - mPreRealTop = realTop; - - onFinishLayout(); + setComponentLayoutParams(realWidth, realHeight, realLeft, realTop, realRight, realBottom, rawOffset); } + private void setComponentLayoutParams(int realWidth, int realHeight, int realLeft, int realTop, + int realRight, int realBottom, Point rawOffset) { + FlatGUIContext UIImp = getInstance().getFlatUIContext(); + WidgetContainer ancestor; + Widget widget; + if ((ancestor = UIImp.getFlatComponentAncestor(this)) != null) { + if (this instanceof FlatComponent && !((FlatComponent) this).promoteToView(true)) { + widget = ((FlatComponent) this).getOrCreateFlatWidget(); + } else { + widget = UIImp.getAndroidViewWidget(this); + } + setWidgetParams(widget, UIImp, rawOffset, realWidth, realHeight, realLeft, realRight, realTop, + realBottom); + } else if (mHost != null) { + if (mDomObj.isFixed()) { + setFixedHostLayoutParams(mHost, realWidth, realHeight, realLeft, realRight, realTop, + realBottom); + } else { + setHostLayoutParams(mHost, realWidth, realHeight, realLeft, realRight, realTop, realBottom); + } + mPreRealWidth = realWidth; + mPreRealHeight = realHeight; + mPreRealLeft = realLeft; + mPreRealTop = realTop; + onFinishLayout(); + } + } + + private void setWidgetParams(Widget widget, FlatGUIContext UIImp, Point rawoffset, + int width, int height, int left, int right, int top, int bottom) { + Point childOffset = new Point(); + if (mParent != null) { + if (mParent instanceof FlatComponent && + UIImp.getFlatComponentAncestor(mParent) != null && + UIImp.getAndroidViewWidget(mParent) == null) { + childOffset.set(rawoffset.x, rawoffset.y); + } + else{ + childOffset.set(left, top); + } - public int getLayoutTopOffsetForSibling(){ - return 0; + if (mParent instanceof FlatComponent && + UIImp.getFlatComponentAncestor(mParent) != null && + UIImp.getAndroidViewWidget(mParent) == null) { + Point parentLayoutOffset = ((FlatComponent) mParent).getOrCreateFlatWidget().getLocInFlatContainer(); + childOffset.offset(parentLayoutOffset.x, parentLayoutOffset.y); + } + ViewGroup.LayoutParams lp = mParent + .getChildLayoutParams(this, mHost, width, height, left, right, top, bottom); + if (lp instanceof MarginLayoutParams) { + width = lp.width; + height = lp.height; + left = ((MarginLayoutParams) lp).leftMargin; + right = ((MarginLayoutParams) lp).rightMargin; + top = ((MarginLayoutParams) lp).topMargin; + bottom = ((MarginLayoutParams) lp).bottomMargin; + } + } + widget.setLayout(width, height, left, right, top, bottom, childOffset); + + if (widget instanceof AndroidViewWidget && ((AndroidViewWidget) widget).getView()!=null) { + //TODO generic method if ever possible + setHostLayoutParams((T) ((AndroidViewWidget) widget).getView(), + width, height, childOffset.x, right, childOffset.y, bottom); + } } protected void setHostLayoutParams(T host, int width, int height, int left, int right, int top, int bottom){ @@ -514,6 +579,10 @@ public abstract class WXComponent<T extends View> implements IWXObject, IWXActi } } + public int getLayoutTopOffsetForSibling(){ + return 0; + } + public float getLayoutWidth(){ float w = 0f; if (mDomObj != null) { @@ -538,10 +607,11 @@ public abstract class WXComponent<T extends View> implements IWXObject, IWXActi int right = (int) (padding.get(Spacing.RIGHT) + border.get(Spacing.RIGHT)); int bottom = (int) (padding.get(Spacing.BOTTOM) + border.get(Spacing.BOTTOM)); - if (mHost == null) { - return; + if (this instanceof FlatComponent && !((FlatComponent) this).promoteToView(true)) { + ((FlatComponent) this).getOrCreateFlatWidget().setContentBox(left, top, right, bottom); + } else if (mHost != null) { + mHost.setPadding(left, top, right, bottom); } - mHost.setPadding(left, top, right, bottom); } private void addEvents() { @@ -611,6 +681,13 @@ public abstract class WXComponent<T extends View> implements IWXObject, IWXActi } } readyToRender(); + if (this instanceof FlatComponent && mBackgroundDrawable != null) { + FlatComponent flatComponent = (FlatComponent) this; + if (!flatComponent.promoteToView(true) && !(flatComponent + .getOrCreateFlatWidget() instanceof AndroidViewWidget)) { + flatComponent.getOrCreateFlatWidget().setBackgroundAndBorder(mBackgroundDrawable); + } + } } /** @@ -645,7 +722,7 @@ public abstract class WXComponent<T extends View> implements IWXObject, IWXActi return true; case Constants.Name.BACKGROUND_IMAGE: String bgImage = WXUtils.getString(param, null); - if (bgImage != null && mHost != null) { + if (bgImage != null) { setBackgroundImage(bgImage); } return true; @@ -1155,7 +1232,7 @@ public abstract class WXComponent<T extends View> implements IWXObject, IWXActi } public void setBackgroundColor(String color) { - if (!TextUtils.isEmpty(color)&& mHost!=null) { + if (!TextUtils.isEmpty(color)) { int colorInt = WXResourceUtils.getColor(color); if (!(colorInt == Color.TRANSPARENT && mBackgroundDrawable == null)){ getOrCreateBorder().setColor(colorInt); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/WXDiv.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXDiv.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXDiv.java index 2772cc6..b9b97e1 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXDiv.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXDiv.java @@ -20,41 +20,99 @@ package com.taobao.weex.ui.component; import android.content.Context; import android.support.annotation.NonNull; - import com.taobao.weex.WXSDKInstance; import com.taobao.weex.annotation.Component; import com.taobao.weex.dom.WXDomObject; import com.taobao.weex.ui.ComponentCreator; +import com.taobao.weex.ui.flat.FlatComponent; +import com.taobao.weex.ui.flat.WidgetContainer; +import com.taobao.weex.ui.flat.widget.WidgetGroup; import com.taobao.weex.ui.view.WXFrameLayout; - import java.lang.reflect.InvocationTargetException; /** * div component */ @Component(lazyload = false) -public class WXDiv extends WXVContainer<WXFrameLayout> { +public class WXDiv extends WidgetContainer<WXFrameLayout> implements FlatComponent<WidgetGroup> { + + private WidgetGroup mWidgetGroup; public static class Ceator implements ComponentCreator { - public WXComponent createInstance(WXSDKInstance instance, WXDomObject node, WXVContainer parent) throws IllegalAccessException, InvocationTargetException, InstantiationException { - return new WXDiv(instance,node,parent); + + public WXComponent createInstance(WXSDKInstance instance, WXDomObject node, WXVContainer parent) + throws IllegalAccessException, InvocationTargetException, InstantiationException { + return new WXDiv(instance, node, parent); } } @Deprecated - public WXDiv(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, String instanceId, boolean isLazy) { - this(instance,dom,parent); + public WXDiv(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, String instanceId, + boolean isLazy) { + this(instance, dom, parent); } public WXDiv(WXSDKInstance instance, WXDomObject node, WXVContainer parent) { super(instance, node, parent); } + @Override protected WXFrameLayout initComponentHostView(@NonNull Context context) { - WXFrameLayout frameLayout =new WXFrameLayout(context); + WXFrameLayout frameLayout = new WXFrameLayout(context); frameLayout.holdComponent(this); return frameLayout; } + @Override + public boolean promoteToView(boolean checkAncestor) { + return !intendToBeFlatContainer() || + getInstance().getFlatUIContext().promoteToView(this, checkAncestor, WXDiv.class); + } + + /** + * Create View tree there. Either this method or {@link #createViewImpl()} get called. + * If this object will be promoted to view, then getOrCreateFlatWidget() should never be called. + */ + @Override + @NonNull + public WidgetGroup getOrCreateFlatWidget() { + if (mWidgetGroup == null) { + mWidgetGroup = new WidgetGroup(getInstance().getFlatUIContext()); + for (int i = 0; i < getChildCount(); i++) { + createChildViewAt(i); + } + mountFlatGUI(); + } + return mWidgetGroup; + } + + @Override + protected void mountFlatGUI() { + if (promoteToView(true)) { + if(getHostView()!=null) { + getHostView().mountFlatGUI(widgets); + } + } else { + mWidgetGroup.replaceAll(widgets); + } + } + + @Override + public void unmountFlatGUI() { + if (getHostView() != null) { + getHostView().unmountFlatGUI(); + } + } + + @Override + public boolean intendToBeFlatContainer() { + return getInstance().getFlatUIContext().isFlatUIEnabled(this) && WXDiv.class.equals(getClass()); + } + + @Override + public boolean isVirtualComponent() { + return !promoteToView(true); + } + } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/WXSlider.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXSlider.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXSlider.java index 4ef51f3..1023e3e 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXSlider.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXSlider.java @@ -29,7 +29,6 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.FrameLayout; - import com.taobao.weex.WXEnvironment; import com.taobao.weex.WXSDKInstance; import com.taobao.weex.WXSDKManager; @@ -45,7 +44,6 @@ import com.taobao.weex.ui.view.gesture.WXGestureType; import com.taobao.weex.utils.WXLogUtils; import com.taobao.weex.utils.WXUtils; import com.taobao.weex.utils.WXViewUtils; - import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; @@ -132,7 +130,7 @@ public class WXSlider extends WXVContainer<FrameLayout> { */ @Override public LayoutParams getChildLayoutParams(WXComponent child,View childView, int width, int height, int left, int right, int top, int bottom) { - ViewGroup.LayoutParams lp = childView.getLayoutParams(); + ViewGroup.LayoutParams lp = childView == null ? null : childView.getLayoutParams(); if (lp == null) { lp = new FrameLayout.LayoutParams(width, height); } else { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/WXText.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXText.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXText.java index aad2bf4..ea7b9ea 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXText.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXText.java @@ -33,6 +33,8 @@ import com.taobao.weex.annotation.Component; import com.taobao.weex.common.Constants; import com.taobao.weex.dom.WXDomObject; import com.taobao.weex.ui.ComponentCreator; +import com.taobao.weex.ui.flat.FlatComponent; +import com.taobao.weex.ui.flat.widget.TextWidget; import com.taobao.weex.ui.view.WXTextView; import com.taobao.weex.utils.FontDO; import com.taobao.weex.utils.TypefaceUtil; @@ -44,7 +46,9 @@ import java.lang.reflect.InvocationTargetException; * Text component */ @Component(lazyload = false) -public class WXText extends WXComponent<WXTextView> { +public class WXText extends WXComponent<WXTextView> implements FlatComponent<TextWidget> { + + private TextWidget mTextWidget; /** * The default text size @@ -53,6 +57,25 @@ public class WXText extends WXComponent<WXTextView> { private BroadcastReceiver mTypefaceObserver; private String mFontFamily; + @Override + public boolean promoteToView(boolean checkAncestor) { + return getInstance().getFlatUIContext().promoteToView(this, checkAncestor, WXText.class); + } + + @Override + @NonNull + public TextWidget getOrCreateFlatWidget() { + if (mTextWidget == null) { + mTextWidget = new TextWidget(getInstance().getFlatUIContext()); + } + return mTextWidget; + } + + @Override + public boolean isVirtualComponent() { + return !promoteToView(true); + } + public static class Creator implements ComponentCreator { public WXComponent createInstance(WXSDKInstance instance, WXDomObject node, WXVContainer parent) throws IllegalAccessException, InvocationTargetException, InstantiationException { @@ -79,11 +102,14 @@ public class WXText extends WXComponent<WXTextView> { @Override public void updateExtra(Object extra) { - if (extra instanceof Layout && - getHostView() != null && !extra.equals(getHostView().getTextLayout())) { + if(extra instanceof Layout) { final Layout layout = (Layout) extra; - getHostView().setTextLayout(layout); - getHostView().invalidate(); + if (!promoteToView(true)) { + getOrCreateFlatWidget().updateTextDrawable(layout); + } else if (getHostView() != null && !extra.equals(getHostView().getTextLayout())) { + getHostView().setTextLayout(layout); + getHostView().invalidate(); + } } } @@ -127,28 +153,6 @@ public class WXText extends WXComponent<WXTextView> { } } - /** - * Flush view no matter what height and width the {@link WXDomObject} specifies. - * @param extra must be a {@link Layout} object, otherwise, nothing will happen. - */ - private void flushView(Object extra) { - if (extra instanceof Layout && - getHostView() != null && !extra.equals(getHostView().getTextLayout())) { - final Layout layout = (Layout) extra; - /**The following if block change the height of the width of the textView. - * other part of the code is the same to updateExtra - */ - ViewGroup.LayoutParams layoutParams = getHostView().getLayoutParams(); - if (layoutParams != null) { - layoutParams.height = layout.getHeight(); - layoutParams.width = layout.getWidth(); - getHostView().setLayoutParams(layoutParams); - } - getHostView().setTextLayout(layout); - getHostView().invalidate(); - } - } - @Override protected Object convertEmptyProperty(String propName, Object originalValue) { switch (propName) { @@ -161,6 +165,13 @@ public class WXText extends WXComponent<WXTextView> { } @Override + protected void createViewImpl() { + if(promoteToView(true)) { + super.createViewImpl(); + } + } + + @Override public void destroy() { super.destroy(); if (WXEnvironment.getApplication() != null && mTypefaceObserver != null) { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java index f769c2a..43b45a7 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java @@ -19,15 +19,14 @@ package com.taobao.weex.ui.component; import android.content.Intent; +import android.util.Pair; import android.support.annotation.Nullable; import android.view.Menu; import android.view.View; import android.view.ViewGroup; - import com.taobao.weex.WXSDKInstance; import com.taobao.weex.common.Constants; import com.taobao.weex.dom.WXDomObject; - import java.util.ArrayList; /** @@ -115,7 +114,11 @@ public abstract class WXVContainer<T extends ViewGroup> extends WXComponent<T> { * */ public ViewGroup.LayoutParams getChildLayoutParams(WXComponent child,View childView, int width, int height, int left, int right, int top, int bottom){ - ViewGroup.LayoutParams lp = childView.getLayoutParams(); + ViewGroup.LayoutParams lp = null; + if (childView != null) { + lp = childView.getLayoutParams(); + } + if(lp == null) { lp = new ViewGroup.LayoutParams(width,height); }else{ @@ -228,6 +231,11 @@ public abstract class WXVContainer<T extends ViewGroup> extends WXComponent<T> { return original; } + /** + * Use {@link #getChildCount()} instead + * @return + */ + @Deprecated public int childCount() { return mChildren == null ? 0 : mChildren.size(); } @@ -242,7 +250,7 @@ public abstract class WXVContainer<T extends ViewGroup> extends WXComponent<T> { } public int getChildCount() { - return mChildren.size(); + return childCount(); } public void addChild(WXComponent child) { @@ -268,21 +276,31 @@ public abstract class WXVContainer<T extends ViewGroup> extends WXComponent<T> { return mChildren.indexOf(comp); } - public void createChildViewAt(int index){ + public void createChildViewAt(int index) { long startNanos = System.nanoTime(); + Pair<WXComponent, Integer> ret = rearrangeIndexAndGetChild(index); + if (ret.first != null) { + WXComponent child = ret.first; + child.createView(); + if (!child.isVirtualComponent()) { + addSubView(child.getHostView(), ret.second); + } + } + mTraceInfo.uiThreadNanos += (System.nanoTime() - startNanos); + } + + protected Pair<WXComponent, Integer> rearrangeIndexAndGetChild(int index){ int indexToCreate = index; if(indexToCreate < 0){ indexToCreate = childCount()-1; - if(indexToCreate < 0 ){ - return; - } } - WXComponent child = getChild(indexToCreate); - child.createView(); - if(!child.isVirtualComponent()){ - addSubView(child.getHostView(),indexToCreate); + + if (indexToCreate<0){ + return new Pair<>(null, indexToCreate); + } + else { + return new Pair<>(getChild(indexToCreate), indexToCreate); } - mTraceInfo.uiThreadNanos += (System.nanoTime() - startNanos); } protected void addSubView(View child, int index) { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java index 3095c04..6ba985f 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java @@ -19,23 +19,31 @@ package com.taobao.weex.ui.component.list; import android.content.Context; +import android.os.Build; +import android.os.Build.VERSION_CODES; import android.support.annotation.NonNull; +import android.support.annotation.RestrictTo; +import android.support.annotation.RestrictTo.Scope; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; - import com.taobao.weex.WXSDKInstance; import com.taobao.weex.annotation.Component; +import com.taobao.weex.common.Constants.Name; +import com.taobao.weex.dom.WXAttr; import com.taobao.weex.dom.WXDomObject; import com.taobao.weex.ui.component.WXVContainer; +import com.taobao.weex.ui.flat.WidgetContainer; import com.taobao.weex.ui.view.WXFrameLayout; +import com.taobao.weex.utils.WXLogUtils; +import com.taobao.weex.utils.WXUtils; /** * Root component for components in {@link WXListComponent} */ @Component(lazyload = false) -public class WXCell extends WXVContainer<WXFrameLayout> { +public class WXCell extends WidgetContainer<WXFrameLayout> { private int mLastLocationY = 0; private ViewGroup mRealView; @@ -45,15 +53,26 @@ public class WXCell extends WXVContainer<WXFrameLayout> { /** used in list sticky detect **/ private int mScrollPositon = -1; - + private boolean mFlatUIEnabled = false; @Deprecated public WXCell(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, String instanceId, boolean isLazy) { - this(instance,dom,parent,isLazy); + super(instance, dom, parent); } public WXCell(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, boolean isLazy) { - super(instance, dom, parent,true ); + super(instance, dom, parent); + if(Build.VERSION.SDK_INT< VERSION_CODES.LOLLIPOP) { + try { + //TODO a WTF is necessary if anyone try to change the flat flag during update attrs. + WXAttr attr = getDomObject().getAttrs(); + if (attr.containsKey(Name.FLAT)) { + mFlatUIEnabled = WXUtils.getBoolean(attr.get(Name.FLAT), false); + } + } catch (NullPointerException e) { + WXLogUtils.e("Cell", WXLogUtils.getStackTrace(e)); + } + } } @Override @@ -65,6 +84,12 @@ public class WXCell extends WXVContainer<WXFrameLayout> { mLazy = lazy; } + @Override + @RestrictTo(Scope.LIBRARY) + public boolean isFlatUIEnabled() { + return mFlatUIEnabled; + } + /** * If Cell is Sticky, need wraped FrameLayout */ @@ -74,10 +99,17 @@ public class WXCell extends WXVContainer<WXFrameLayout> { WXFrameLayout view = new WXFrameLayout(context); mRealView = new WXFrameLayout(context); view.addView(mRealView); + //TODO Maybe there is a better solution for hardware-acceleration view's display list. + if (isFlatUIEnabled()) { + view.setLayerType(View.LAYER_TYPE_HARDWARE, null); + } return view; } else { WXFrameLayout view = new WXFrameLayout(context); mRealView = view; + if (isFlatUIEnabled()) { + view.setLayerType(View.LAYER_TYPE_HARDWARE, null); + } return view; } } @@ -127,4 +159,23 @@ public class WXCell extends WXVContainer<WXFrameLayout> { mHeadView.setTranslationX(0); mHeadView.setTranslationY(0); } + + @Override + protected void mountFlatGUI() { + if(getHostView()!=null) { + getHostView().mountFlatGUI(widgets); + } + } + + @Override + public void unmountFlatGUI() { + if (getHostView() != null) { + getHostView().unmountFlatGUI(); + } + } + + @Override + public boolean intendToBeFlatContainer() { + return getInstance().getFlatUIContext().isFlatUIEnabled(this) && WXCell.class.equals(getClass()) && !isSticky(); + } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXListComponent.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXListComponent.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXListComponent.java index ab53f78..c5ef8b5 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXListComponent.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXListComponent.java @@ -19,6 +19,7 @@ package com.taobao.weex.ui.component.list; import android.content.Context; +import android.util.Pair; import com.taobao.weex.WXSDKInstance; import com.taobao.weex.annotation.Component; @@ -187,35 +188,31 @@ public class WXListComponent extends BasicListComponent<BounceRecyclerView> { @Override public void createChildViewAt(int index) { - int indexToCreate = index; - if (indexToCreate < 0) { - indexToCreate = childCount() - 1; - if (indexToCreate < 0) { - return; - } - } - final WXComponent child = getChild(indexToCreate); - if (child instanceof WXBaseRefresh) { - child.createView(); - if (child instanceof WXRefresh) { - getHostView().setOnRefreshListener((WXRefresh) child); - getHostView().postDelayed(new Runnable() { - @Override - public void run() { - getHostView().setHeaderView(child); - } - }, 100); - } else if (child instanceof WXLoading) { - getHostView().setOnLoadingListener((WXLoading) child); - getHostView().postDelayed(new Runnable() { - @Override - public void run() { - getHostView().setFooterView(child); - } - }, 100); + Pair<WXComponent, Integer> ret = rearrangeIndexAndGetChild(index); + if(ret.first != null) { + final WXComponent child = getChild(ret.second); + if (child instanceof WXBaseRefresh) { + child.createView(); + if (child instanceof WXRefresh) { + getHostView().setOnRefreshListener((WXRefresh) child); + getHostView().postDelayed(new Runnable() { + @Override + public void run() { + getHostView().setHeaderView(child); + } + }, 100); + } else if (child instanceof WXLoading) { + getHostView().setOnLoadingListener((WXLoading) child); + getHostView().postDelayed(new Runnable() { + @Override + public void run() { + getHostView().setFooterView(child); + } + }, 100); + } + } else { + super.createChildViewAt(ret.second); } - } else { - super.createChildViewAt(indexToCreate); } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatComponent.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatComponent.java b/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatComponent.java new file mode 100644 index 0000000..2c0cc46 --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatComponent.java @@ -0,0 +1,33 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.taobao.weex.ui.flat; + + +import android.support.annotation.NonNull; +import android.support.annotation.RestrictTo; +import android.support.annotation.RestrictTo.Scope; +import com.taobao.weex.ui.flat.widget.Widget; + +@RestrictTo(Scope.LIBRARY) +public interface FlatComponent<T extends Widget> { + + boolean promoteToView(boolean checkAncestor); + + @NonNull T getOrCreateFlatWidget(); +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatGUIContext.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatGUIContext.java b/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatGUIContext.java new file mode 100644 index 0000000..4004bc8 --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/FlatGUIContext.java @@ -0,0 +1,146 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.taobao.weex.ui.flat; + + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.RestrictTo; +import android.support.annotation.RestrictTo.Scope; +import android.support.v4.util.ArrayMap; +import android.text.TextUtils; +import android.view.View; +import com.taobao.weex.common.Constants.Name; +import com.taobao.weex.common.Destroyable; +import com.taobao.weex.dom.ImmutableDomObject; +import com.taobao.weex.dom.WXAttr; +import com.taobao.weex.dom.WXDomObject; +import com.taobao.weex.dom.WXStyle; +import com.taobao.weex.ui.component.WXComponent; +import com.taobao.weex.ui.flat.widget.AndroidViewWidget; +import com.taobao.weex.ui.flat.widget.Widget; +import java.util.Map; +import java.util.Map.Entry; + +//TODO The constructor of FlatGUIContext should have a flag decide whether to enable flagGUI. + +@RestrictTo(Scope.LIBRARY) +public class FlatGUIContext implements Destroyable{ + + private Map<WXComponent, WidgetContainer> mWidgetRegistry = new ArrayMap<>(); + private Map<WXComponent, AndroidViewWidget> mViewWidgetRegistry = new ArrayMap<>(); + private Map<Widget, WXComponent> widgetToComponent = new ArrayMap<>(); + + public boolean isFlatUIEnabled(WXComponent component) { + return component.isFlatUIEnabled(); + } + + public void register(@NonNull WXComponent descendant, @NonNull WidgetContainer ancestor) { + if (!(ancestor instanceof FlatComponent) || + ((FlatComponent) ancestor).promoteToView(true)) { + mWidgetRegistry.put(descendant, ancestor); + } + } + + public void register(@NonNull WXComponent component, @NonNull AndroidViewWidget viewWidget){ + mViewWidgetRegistry.put(component, viewWidget); + } + + public void register(@NonNull Widget widget, @NonNull WXComponent component){ + widgetToComponent.put(widget, component); + } + + public + @Nullable + WidgetContainer getFlatComponentAncestor(@NonNull WXComponent flatWidget) { + return mWidgetRegistry.get(flatWidget); + } + + public + @Nullable + AndroidViewWidget getAndroidViewWidget(@NonNull WXComponent component) { + return mViewWidgetRegistry.get(component); + } + + public boolean promoteToView(@NonNull WXComponent component, boolean checkAncestor, + @NonNull Class<? extends WXComponent<?>> expectedClass) { + return !isFlatUIEnabled(component) || + !expectedClass.equals(component.getClass()) || + TextUtils.equals(component.getRef(), WXDomObject.ROOT) || + (checkAncestor && getFlatComponentAncestor(component) == null) || + checkComponent(component); + } + + public + @Nullable + View getWidgetContainerView(Widget widget) { + WXComponent component, ancestor; + View ret = null; + if ((component = getComponent(widget)) != null) { + if ((ancestor = getFlatComponentAncestor(component)) != null) { + ret = ancestor.getHostView(); + } + } + return ret; + } + + @Override + @RestrictTo(Scope.LIBRARY) + public void destroy(){ + widgetToComponent.clear(); + + for(Entry<WXComponent, AndroidViewWidget> entry: mViewWidgetRegistry.entrySet()){ + entry.getValue().destroy(); + } + mViewWidgetRegistry.clear(); + + for(Entry<WXComponent, WidgetContainer> entry:mWidgetRegistry.entrySet()){ + entry.getValue().unmountFlatGUI(); + } + mWidgetRegistry.clear(); + } + + private @Nullable WXComponent getComponent(@NonNull Widget widget){ + return widgetToComponent.get(widget); + } + + private boolean checkComponent(@NonNull WXComponent component) { + boolean ret = false; + ImmutableDomObject domObject = component.getDomObject(); + if (domObject != null) { + WXStyle style = domObject.getStyles(); + WXAttr attr = domObject.getAttrs(); + if (style.containsKey(Name.OPACITY) || + style.containsKey(Name.TRANSFORM) || + style.containsKey(Name.VISIBILITY) || + attr.containsKey(Name.ELEVATION) || + attr.containsKey(Name.ARIA_HIDDEN) || + attr.containsKey(Name.ARIA_LABEL) || + attr.containsKey(WXComponent.PROP_FIXED_SIZE) || + attr.containsKey(Name.DISABLED) || + style.isFixed() || + style.isSticky() || + !style.getPesudoStyles().isEmpty() || + domObject.getEvents().size() > 0) { + ret = true; + } + } + return ret; + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/flat/WidgetContainer.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/flat/WidgetContainer.java b/android/sdk/src/main/java/com/taobao/weex/ui/flat/WidgetContainer.java new file mode 100644 index 0000000..f68aaeb --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/WidgetContainer.java @@ -0,0 +1,93 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.taobao.weex.ui.flat; + + +import android.support.annotation.RestrictTo; +import android.support.annotation.RestrictTo.Scope; +import android.util.Pair; +import android.view.ViewGroup; +import com.taobao.weex.WXSDKInstance; +import com.taobao.weex.dom.WXDomObject; +import com.taobao.weex.ui.component.WXComponent; +import com.taobao.weex.ui.component.WXVContainer; +import com.taobao.weex.ui.flat.widget.AndroidViewWidget; +import com.taobao.weex.ui.flat.widget.Widget; +import java.util.LinkedList; +import java.util.List; + +@RestrictTo(Scope.LIBRARY) +public abstract class WidgetContainer<T extends ViewGroup> extends WXVContainer<T> { + + protected List<Widget> widgets = new LinkedList<>(); + + public WidgetContainer(WXSDKInstance instance, WXDomObject node, WXVContainer parent) { + super(instance, node, parent); + } + + protected abstract void mountFlatGUI(); + + protected abstract void unmountFlatGUI(); + + public boolean intendToBeFlatContainer() { + return false; + } + + @Override + public void createChildViewAt(int index) { + if (intendToBeFlatContainer()) { + Pair<WXComponent, Integer> ret = rearrangeIndexAndGetChild(index); + if (ret.first != null) { + WXComponent child = ret.first; + Widget flatChild; + FlatGUIContext uiImp = getInstance().getFlatUIContext(); + WidgetContainer parent = uiImp.getFlatComponentAncestor(this); + if (parent == null || uiImp.getAndroidViewWidget(this) != null) { + parent = this; + } + uiImp.register(child, parent); + + if (child instanceof FlatComponent && !((FlatComponent) child).promoteToView(false)) { + flatChild = ((FlatComponent) child).getOrCreateFlatWidget(); + } else { + flatChild = new AndroidViewWidget(uiImp); + uiImp.register(child, (AndroidViewWidget) flatChild); + child.createView(); + ((AndroidViewWidget) flatChild).setContentView(child.getHostView()); + //TODO Use a sort algorithm to decide the childIndex of AndroidViewWidget + parent.addSubView(child.getHostView(), -1); + } + uiImp.register(flatChild, child); + addFlatChild(flatChild, ret.second); + } + } else { + super.createChildViewAt(index); + } + } + + private void addFlatChild(Widget widget, int index) { + if (index >= widgets.size()) { + widgets.add(widget); + } else { + widgets.add(index, widget); + } + //TODO do a partial update, not mount the whole flatContainer. + mountFlatGUI(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/AndroidViewWidget.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/AndroidViewWidget.java b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/AndroidViewWidget.java new file mode 100644 index 0000000..0610a8e --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/AndroidViewWidget.java @@ -0,0 +1,76 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.taobao.weex.ui.flat.widget; + + +import android.graphics.Canvas; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.RestrictTo; +import android.support.annotation.RestrictTo.Scope; +import android.view.View; +import com.taobao.weex.common.Destroyable; +import com.taobao.weex.ui.flat.FlatGUIContext; + +@RestrictTo(Scope.LIBRARY) +public class AndroidViewWidget extends BaseWidget implements Destroyable { + + private @Nullable View mView; + public AndroidViewWidget(@NonNull FlatGUIContext context) { + super(context); + } + + public void setContentView(@Nullable View view){ + this.mView = view; + } + + @Override + public void setContentBox(int leftOffset, int topOffset, int rightOffset, int bottomOffset) { + if(mView!=null) { + mView.setPadding(leftOffset, topOffset, rightOffset, bottomOffset); + invalidate(); + } + } + + @Override + public void onDraw(@NonNull Canvas canvas) { + if(mView!=null) { + mView.draw(canvas); + } + } + + @Override + public void invalidate() { + super.invalidate(); + if (mView != null) { + mView.invalidate(); + } + } + + public @Nullable View getView() { + return mView; + } + + @Override + public void destroy() { + if (mView != null) { + mView = null; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/BaseWidget.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/BaseWidget.java b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/BaseWidget.java new file mode 100644 index 0000000..02432dc --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/BaseWidget.java @@ -0,0 +1,130 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.taobao.weex.ui.flat.widget; + + +import android.graphics.Canvas; +import android.graphics.Point; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.RestrictTo; +import android.support.annotation.RestrictTo.Scope; +import android.view.View; +import com.taobao.weex.ui.flat.FlatGUIContext; +import com.taobao.weex.ui.view.border.BorderDrawable; +import com.taobao.weex.utils.WXViewUtils; + +@RestrictTo(Scope.LIBRARY) +abstract class BaseWidget implements Widget { + + //TODO Reconsider the field parameter in this class and the operation during draw(); Make a CPU/Memory balance. + //TODO use float to avoid 1px problem + private BorderDrawable backgroundBorder; + private int leftOffset, topOffset, rightOffset, bottomOffset; + private Rect borderBox = new Rect(); + private Point offsetOfContainer = new Point(); + private final @NonNull + FlatGUIContext context; + + BaseWidget(@NonNull FlatGUIContext context){ + this.context = context; + } + + @Override + public void setLayout(int width, int height, int left, int right, int top, int bottom, Point offset) { + this.offsetOfContainer = offset; + borderBox.set(left, top, left + width, top + height); + if (backgroundBorder != null) { + setBackgroundAndBorder(backgroundBorder); + } + invalidate(); + } + + @Override + public void setContentBox(int leftOffset, int topOffset, int rightOffset, int bottomOffset) { + this.leftOffset = leftOffset; + this.topOffset = topOffset; + this.rightOffset = rightOffset; + this.bottomOffset = bottomOffset; + invalidate(); + } + + @Override + public void setBackgroundAndBorder(@NonNull BorderDrawable backgroundBorder) { + //TODO Change the code of BorderDrawable is more appropriate as it draws the borderLine from (0,0) not from getBounds + //TODO If the above is finished, no more traslate in draw in needed, only clip is enough. + this.backgroundBorder = backgroundBorder; + Rect backgroundBox = new Rect(borderBox); + backgroundBox.offset(-borderBox.left, -borderBox.top); + backgroundBorder.setBounds(backgroundBox); + setCallback(backgroundBorder); + invalidate(); + } + + @NonNull + @Override + public final Point getLocInFlatContainer() { + return offsetOfContainer; + } + + @Nullable + @Override + public final BorderDrawable getBackgroundAndBorder() { + return backgroundBorder; + } + + @NonNull + @Override + public final Rect getBorderBox() { + return borderBox; + } + + @Override + public final void draw(@NonNull Canvas canvas) { + canvas.save(); + WXViewUtils.clipCanvasWithinBorderBox(this, canvas); + canvas.translate(borderBox.left, borderBox.top); + if (backgroundBorder != null) { + backgroundBorder.draw(canvas); + } + canvas.clipRect(leftOffset, topOffset, borderBox.width()-rightOffset, borderBox.height() - bottomOffset); + canvas.translate(leftOffset, topOffset); + onDraw(canvas); + canvas.restore(); + } + + protected void invalidate() { + Rect dirtyRegion = new Rect(borderBox); + dirtyRegion.offset(offsetOfContainer.x, offsetOfContainer.y); + View widgetContainer; + if ((widgetContainer = context.getWidgetContainerView(this)) != null) { + widgetContainer.invalidate(dirtyRegion); + } + } + + protected void setCallback(@NonNull Drawable drawable) { + View widgetContainer; + if ((widgetContainer = context.getWidgetContainerView(this)) != null) { + drawable.setCallback(widgetContainer); + } + } +} + http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/TextWidget.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/TextWidget.java b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/TextWidget.java new file mode 100644 index 0000000..2a69b46 --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/TextWidget.java @@ -0,0 +1,49 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.taobao.weex.ui.flat.widget; + + +import android.graphics.Canvas; +import android.support.annotation.NonNull; +import android.support.annotation.RestrictTo; +import android.support.annotation.RestrictTo.Scope; +import android.text.Layout; +import com.taobao.weex.ui.flat.FlatGUIContext; + +@RestrictTo(Scope.LIBRARY) +public class TextWidget extends BaseWidget { + + private Layout mLayout; + + public TextWidget(@NonNull FlatGUIContext context) { + super(context); + } + + @Override + public void onDraw(@NonNull Canvas canvas) { + if (mLayout != null) { + mLayout.draw(canvas); + } + } + + public void updateTextDrawable(Layout layout) { + this.mLayout = layout; + invalidate(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/Widget.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/Widget.java b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/Widget.java new file mode 100644 index 0000000..761d3b0 --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/Widget.java @@ -0,0 +1,51 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.taobao.weex.ui.flat.widget; + + +import android.graphics.Canvas; +import android.graphics.Point; +import android.graphics.Rect; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.RestrictTo; +import android.support.annotation.RestrictTo.Scope; +import com.taobao.weex.ui.view.border.BorderDrawable; + +@RestrictTo(Scope.LIBRARY) +public interface Widget { + + public static final String TAG = "Widget"; + + void draw(@NonNull Canvas canvas); + + void onDraw(@NonNull Canvas canvas); + + void setBackgroundAndBorder(@NonNull BorderDrawable backgroundBorder); + + void setLayout(int width, int height, int left, int right, int top, int bottom, Point offset); + + void setContentBox(int leftOffset, int topOffset, int rightOffset, int bottomOffset); + + @NonNull Point getLocInFlatContainer(); + + @Nullable BorderDrawable getBackgroundAndBorder(); + + @NonNull Rect getBorderBox(); +}