diff --git a/examples/src/main/AndroidManifest.xml b/examples/src/main/AndroidManifest.xml
index 578f045..5991a78 100644
--- a/examples/src/main/AndroidManifest.xml
+++ b/examples/src/main/AndroidManifest.xml
@@ -46,6 +46,8 @@
+
+
diff --git a/examples/src/main/assets/data3.0.json b/examples/src/main/assets/data3.0.json
new file mode 100644
index 0000000..c000d8c
--- /dev/null
+++ b/examples/src/main/assets/data3.0.json
@@ -0,0 +1,740 @@
+[
+ {
+ "type": "container-scroll",
+ "style": {
+ "pageWidth": 200,
+ "hGap": 10,
+ "pageHeight": 100
+ },
+ "componentInfo": [
+ {
+ "name": "vvtest",
+ "type": "VirtualView",
+ "version": "1",
+ "url": ""
+ }
+ ],
+ "items": [
+ {
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "arrowImgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "title": "rs标题1",
+ "type": "dxTest"
+ },
+ {
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "arrowImgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "title": "rs标题2",
+ "type": "vvtest"
+ },
+ {
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "arrowImgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "title": "rs标题3",
+ "type": "vvtest"
+ },
+ {
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "arrowImgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "title": "rs标题4",
+ "type": "vvtest"
+ }
+ ]
+ },
+ {
+ "type": "container-oneColumn",
+ "items": [
+ {
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "arrowImgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "msg": "暴走大事件第五季暴走大事件第五季暴走大事件第五季",
+ "play": "23343454",
+ "danmu": "13234",
+ "test": "分区1",
+ "type": "Debug"
+ },
+ {
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "arrowImgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "msg": "说说你在B站的故事",
+ "play": "5445667",
+ "danmu": "2134",
+ "test": "分区2",
+ "type": "Debug"
+ },
+ {
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "arrowImgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "msg": "切格瓦拉东京偷车切格瓦拉东京偷车切格瓦拉东京偷车",
+ "play": "496",
+ "danmu": "23",
+ "test": "分区3",
+ "type": "Debug"
+ },
+ {
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "arrowImgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "msg": "Five to Go 大学生短片",
+ "play": "369",
+ "danmu": "5",
+ "test": "分区4",
+ "type": "Debug"
+ }
+ ]
+ },
+ {
+ "id": "banner1",
+ "type": "container-oneColumn",
+ "style": {
+ "aspectRatio": 3.223
+ },
+ "items": [
+ {
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "arrowImgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "msg": "标题1",
+ "title": "说说你的故事",
+ "type": "vvtest"
+ },
+ {
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "arrowImgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "msg": "标题2",
+ "title": "Five to Go 大学生短片",
+ "type": "vvtest"
+ }
+ ]
+ },
+ {
+ "type": "container-banner",
+ "style": {
+ "pageWidth": 200,
+ "pageHeight": 100,
+ "indicatorMargin": "5",
+ "infinite": "true",
+ "indicatorImg2": "https://img.alicdn.com/tps/TB1XRNFNXXXXXXKXXXXXXXXXXXX-32-4.png",
+ "indicatorImg1": "https://img.alicdn.com/tps/TB16i4qNXXXXXbBXFXXXXXXXXXX-32-4.png",
+ "scrollMarginLeft": "10",
+ "indicatorGap": "2",
+ "indicatorHeight": "1.5",
+ "itemRatio": "2.654",
+ "scrollMarginRight": "10",
+ "indicatorGravity": "center",
+ "hGap": "20"
+ },
+ "items": [
+ {
+ "type": "testView",
+ "msg": "info1",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info2",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info3",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info4",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info5",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info6",
+ "style": {
+ }
+ }
+ ]
+ },
+ {
+ "type": "container-oneColumn",
+ "items": [
+ {
+ "id": "banner1",
+ "type": "container-banner",
+ "style": {
+ "indicatorMargin": "5",
+ "infinite": "true",
+ "indicatorImg2": "https://img.alicdn.com/tps/TB1XRNFNXXXXXXKXXXXXXXXXXXX-32-4.png",
+ "indicatorImg1": "https://img.alicdn.com/tps/TB16i4qNXXXXXbBXFXXXXXXXXXX-32-4.png",
+ "scrollMarginLeft": "10",
+ "indicatorGap": "2",
+ "indicatorHeight": "1.5",
+ "itemRatio": "2.654",
+ "scrollMarginRight": "10",
+ "indicatorGravity": "center",
+ "hGap": "20",
+ "height": 200
+ },
+ "items": [
+ {
+ "type": "testView",
+ "msg": "info1",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info2",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info3",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info4",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info5",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info6",
+ "style": {
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "container-oneColumn",
+ "items": [
+ {
+ "type": "container-scroll",
+ "style": {
+ "pageWidth": 200,
+ "pageHeight": 100,
+ "indicatorMargin": "5",
+ "infinite": "true",
+ "indicatorImg2": "https://img.alicdn.com/tps/TB1XRNFNXXXXXXKXXXXXXXXXXXX-32-4.png",
+ "indicatorImg1": "https://img.alicdn.com/tps/TB16i4qNXXXXXbBXFXXXXXXXXXX-32-4.png",
+ "scrollMarginLeft": "10",
+ "indicatorGap": "2",
+ "indicatorHeight": "1.5",
+ "itemRatio": "2.654",
+ "scrollMarginRight": "10",
+ "indicatorGravity": "center",
+ "hGap": "20"
+ },
+ "items": [
+ {
+ "type": "testView",
+ "msg": "info1",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info2",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info3",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info4",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info5",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info6",
+ "style": {
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": "BuyCate",
+ "style": {
+ "hGap": "15",
+ "vGap": "15",
+ "margin": [
+ null,
+ null,
+ null,
+ null
+ ],
+ "padding": [
+ "15",
+ "15",
+ "15",
+ "15"
+ ]
+ },
+ "type": "container-waterfall",
+ "items": [
+ {
+ "title": "A",
+ "type": "testView"
+ },
+ {
+ "title": "B",
+ "type": "testView"
+ },
+ {
+ "title": "C",
+ "type": "testView"
+ },
+ {
+ "title": "D",
+ "type": "testView"
+ },
+ {
+ "title": "E",
+ "type": "testView"
+ },
+ {
+ "title": "F",
+ "type": "testView"
+ },
+ {
+ "title": "G",
+ "type": "testView"
+ },
+ {
+ "title": "H",
+ "type": "testView"
+ },
+ {
+ "title": "I",
+ "type": "testView"
+ },
+ {
+ "title": "G",
+ "type": "testView"
+ }
+ ]
+ },
+ {
+ "type": "container-oneColumn",
+ "style": {
+ "aspectRatio": 3.223
+ },
+ "items": [
+ {
+ "type": "singleImgView",
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1pdJFQpXXXXbUXpXXXXXXXXXX-750-243.png"
+ },
+ {
+ "type": "singleImgView",
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1pdJFQpXXXXbUXpXXXXXXXXXX-750-243.png"
+ }
+ ]
+ },
+ {
+ "type": "container-sticky",
+ "style": {
+ "sticky": "start"
+ },
+ "items": [
+ {
+ "type": "testView",
+ "msg": "sticky",
+ "style": {
+ }
+ }
+ ]
+ },
+ {
+ "type": "container-banner",
+ "id": "banner2",
+ "style": {
+ "indicatorImg1": "https://gw.alicdn.com/tps/TB16RaxLpXXXXbIXFXXXXXXXXXX-14-14.png",
+ "indicatorImg2": "https://gw.alicdn.com/tps/TB1m79uLpXXXXXUXVXXXXXXXXXX-18-16.png",
+ "indicatorGravity": "center",
+ "indicatorPosition": "inside",
+ "indicatorMargin": 10,
+ "indicatorGap": 2,
+ "scrollMarginLeft": 20,
+ "scrollMarginRight": 20,
+ "hGap": 12,
+ "pageRatio": 0.5,
+ "bgColor": "#ffffff"
+ },
+ "items": [
+ {
+ "type": "testView",
+ "msg": "info11",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info12",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info13",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info14",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info15",
+ "style": {
+ }
+ },
+ {
+ "type": "testView",
+ "msg": "info16",
+ "style": {
+ }
+ }
+ ]
+ },
+ {
+ "type": "container-onePlusN",
+ "style": {
+ "aspectRatio": "1.778",
+ "cols": [
+ 43.467
+ ],
+ "rows": [
+ 43.602
+ ]
+ },
+ "items": [
+ {
+ "type": "testView",
+ "action": "xxx",
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1pdJFQpXXXXbUXpXXXXXXXXXX-750-243.png",
+ "style": {
+ "margin": "[0,1,0,0]"
+ }
+ },
+ {
+ "type": "testView",
+ "action": "xxx",
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1pdJFQpXXXXbUXpXXXXXXXXXX-750-243.png",
+ "style": {
+ "margin": "[0,0,1,0]"
+ }
+ },
+ {
+ "type": "testView",
+ "action": "xxx",
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1pdJFQpXXXXbUXpXXXXXXXXXX-750-243.png",
+ "style": {
+ "margin": "[0,1,0,0]"
+ }
+ },
+ {
+ "type": "testView",
+ "action": "xxx",
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1pdJFQpXXXXbUXpXXXXXXXXXX-750-243.png",
+ "style": {
+ }
+ }
+ ]
+ },
+ {
+ "type": "container-twoColumn",
+ "style": {
+ "hGap": 10,
+ "vGap": 10,
+ "cols": [
+ 35.5
+ ]
+ },
+ "items": [
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ }
+ ]
+ },
+ {
+ "type": "container-threeColumn",
+ "items": [
+ {
+ "type": "testView",
+ "msg": "block",
+ "style": {
+ "display": "block"
+ }
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ }
+ ]
+ },
+ {
+ "type": "container-fourColumn",
+ "items": [
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ }
+ ]
+ },
+ {
+ "type": "container-scrollFix",
+ "id": "scrollFixShowOnEnter",
+ "style": {
+ "showType": "showONEnter"
+ },
+ "items": [
+ {
+ "type": "testView",
+ "style": {
+ "height": 120
+ },
+ "msg": "showOnEnter"
+ }
+ ]
+ },
+ {
+ "type": "container-oneColumn",
+ "id": "dividerShow",
+ "items": [
+ {
+ "type": "testView",
+ "msg": "I am a divider"
+ }
+ ]
+ },
+ {
+ "type": "container-onePlusN",
+ "style": {
+ "bgColor": "#e3e3e3",
+ "cols": [
+ "46.667"
+ ]
+ },
+ "items": [
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ }
+ ]
+ },
+ {
+ "type": "container-onePlusN",
+ "style": {
+ "cols": [
+ 40
+ ]
+ },
+ "items": [
+ {
+ "type": "testView",
+ "style": {
+ "margin": [
+ 4,
+ 4,
+ 2,
+ 0
+ ]
+ }
+ },
+ {
+ "type": "testView",
+ "style": {
+ "margin": [
+ 0,
+ 0,
+ 4,
+ 0
+ ]
+ }
+ },
+ {
+ "type": "testView"
+ }
+ ]
+ },
+ {
+ "type": "container-onePlusN",
+ "style": {
+ },
+ "items": [
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ }
+ ]
+ },
+ {
+ "type": "container-oneColumn",
+ "items": [
+ {
+ "type": "testView"
+ }
+ ]
+ },
+ {
+ "type": "container-fiveColumn",
+ "load": "com.tmall.request.test",
+ "header": {
+ "imgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "arrowImgUrl": "https://gw.alicdn.com/tfs/TB1vqF.PpXXXXaRaXXXXXXXXXXX-110-72.png",
+ "title": "标题1",
+ "type": "vvtest",
+ "renderService": "VirtualView"
+ },
+ "style": {
+ "autoExpand": true
+ },
+ "items": [
+ ]
+ },
+ {
+ "type": "container-fourColumn",
+ "style": {
+ "autoExpand": true,
+ "enableColspan": true,
+ "vGap": "2",
+ "hGap": "2"
+ },
+ "items": [
+ {
+ "type": "testView",
+ "style": {
+ "colspan": 2
+ }
+ },
+ {
+ "type": "testView",
+ "style": {
+ "colspan": 2
+ }
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ },
+ {
+ "type": "testView"
+ }
+ ]
+ },
+ {
+ "type": "container-float",
+ "style": {
+ "align": "bottom_left",
+ "x": 10,
+ "y": 100
+ },
+ "items": [
+ {
+ "type": "2",
+ "action": "xxx",
+ "imgUrl": "https://img.alicdn.com/tps/TB11Y5hPVXXXXbaXpXXXXXXXXXX-186-158.png",
+ "style": {
+ "margin": [
+ 10,
+ 10,
+ 10,
+ 10
+ ],
+ "height": 50,
+ "width": 50
+ }
+ }
+ ]
+ },
+ {
+ "type": "container-oneColumn",
+ "load": "com.tmall.request.load.more",
+ "loadType": 1,
+ "items": [
+ ]
+ }
+]
\ No newline at end of file
diff --git a/examples/src/main/java/com/tmall/wireless/tangram/example/DemoListActivity.java b/examples/src/main/java/com/tmall/wireless/tangram/example/DemoListActivity.java
index fb0392d..7a82531 100644
--- a/examples/src/main/java/com/tmall/wireless/tangram/example/DemoListActivity.java
+++ b/examples/src/main/java/com/tmall/wireless/tangram/example/DemoListActivity.java
@@ -39,6 +39,8 @@ import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
+import com.tmall.wireless.tangram.example.tangram3.Tangram3Activity;
+
/**
* Created by longerian on 2017/7/24.
*
@@ -57,6 +59,10 @@ public class DemoListActivity extends ListActivity {
parse.put("name", "基本Tangram");
parse.put("class", TangramActivity.class.getName());
list.add(parse);
+ HashMap newTangram = new HashMap();
+ newTangram.put("name", "Tangram 3.0");
+ newTangram.put("class", Tangram3Activity.class.getName());
+ list.add(newTangram);
HashMap api = new HashMap();
api.put("name", "响应式Tangram");
api.put("class", RxTangramActivity.class.getName());
@@ -71,7 +77,7 @@ public class DemoListActivity extends ListActivity {
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
- Map item = (Map)l.getItemAtPosition(position);
+ Map item = (Map) l.getItemAtPosition(position);
String className = item.get("class");
if (className != null) {
Intent intent = new Intent();
diff --git a/examples/src/main/java/com/tmall/wireless/tangram/example/tangram3/Tangram3Activity.java b/examples/src/main/java/com/tmall/wireless/tangram/example/tangram3/Tangram3Activity.java
new file mode 100644
index 0000000..dab4f37
--- /dev/null
+++ b/examples/src/main/java/com/tmall/wireless/tangram/example/tangram3/Tangram3Activity.java
@@ -0,0 +1,182 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2018 Alibaba Group
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.tmall.wireless.tangram.example.tangram3;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.RecyclerView;
+import android.widget.ImageView;
+
+import com.libra.Utils;
+import com.squareup.picasso.Picasso;
+import com.tmall.wireless.tangram.example.R;
+import com.tmall.wireless.tangram3.TangramBuilder;
+import com.tmall.wireless.tangram3.TangramEngine;
+import com.tmall.wireless.tangram.example.support.SampleScrollSupport;
+import com.tmall.wireless.tangram3.util.IInnerImageSetter;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created by villadora on 15/8/18.
+ */
+public class Tangram3Activity extends Activity {
+
+ private static final String TAG = Tangram3Activity.class.getSimpleName();
+
+ private Handler mMainHandler;
+ TangramEngine engine;
+ TangramBuilder.InnerBuilder builder;
+ RecyclerView recyclerView;
+
+ @TargetApi(Build.VERSION_CODES.KITKAT)
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main_activity);
+ recyclerView = (RecyclerView) findViewById(R.id.main_view);
+
+ //Step 1: init tangram
+ TangramBuilder.init(this.getApplicationContext(), new IInnerImageSetter() {
+ @Override
+ public void doLoadImageUrl(@NonNull IMAGE view,
+ @Nullable String url) {
+ Picasso.with(Tangram3Activity.this.getApplicationContext()).load(url).into(view);
+ }
+ }, ImageView.class);
+
+ //Tangram.switchLog(true);
+ mMainHandler = new Handler(getMainLooper());
+
+ //Step 2: register build=in cells and cards
+ builder = TangramBuilder.newInnerBuilder(this);
+
+ //Step 3: register business cells and cards
+ // recommend to use string type to register component
+ builder.registerCell("testView", TestBlockView.class);
+ builder.registerCell("Debug", TestBlockView.class);
+ builder.registerCell("singleImgView", TestImageView.class);
+
+ builder.registerRenderService(new VirtualViewRenderService3());
+ //Step 4: new engine
+ engine = builder.build();
+
+ Utils.setUedScreenWidth(720);
+
+// engine.addSimpleClickSupport(new SampleClickSupport());
+
+ //Step 6: enable auto load more if your page's data is lazy loaded
+ engine.enableAutoLoadMore(true);
+// engine.register(InternalErrorSupport.class, new SampleErrorSupport());
+
+ //Step 7: bind recyclerView to engine
+ engine.bindView(recyclerView);
+
+ //Step 8: listener recyclerView onScroll event to trigger auto load more
+ recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ super.onScrolled(recyclerView, dx, dy);
+ engine.onScrolled();
+ }
+ });
+
+ //Step 9: set an offset to fix card
+ engine.getLayoutManager().setFixOffset(0, 40, 0, 0);
+
+ //Step 10: get tangram data and pass it to engine
+ String json = new String(getAssertsFile(this, "data3.0.json"));
+ JSONArray data = null;
+ try {
+ data = new JSONArray(json);
+ engine.setData(data);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+
+ //Demo for component to listen container's event
+ engine.register(SampleScrollSupport.class, new SampleScrollSupport(recyclerView));
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (engine != null) {
+ engine.destroy();
+ }
+ }
+
+ public static byte[] getAssertsFile(Context context, String fileName) {
+ InputStream inputStream = null;
+ AssetManager assetManager = context.getAssets();
+ try {
+ inputStream = assetManager.open(fileName);
+ if (inputStream == null) {
+ return null;
+ }
+
+ BufferedInputStream bis = null;
+ int length;
+ try {
+ bis = new BufferedInputStream(inputStream);
+ length = bis.available();
+ byte[] data = new byte[length];
+ bis.read(data);
+
+ return data;
+ } catch (IOException e) {
+
+ } finally {
+ if (bis != null) {
+ try {
+ bis.close();
+ } catch (Exception e) {
+
+ }
+ }
+ }
+
+ return null;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+
+}
diff --git a/examples/src/main/java/com/tmall/wireless/tangram/example/tangram3/TestBlockView.java b/examples/src/main/java/com/tmall/wireless/tangram/example/tangram3/TestBlockView.java
new file mode 100644
index 0000000..c313e60
--- /dev/null
+++ b/examples/src/main/java/com/tmall/wireless/tangram/example/tangram3/TestBlockView.java
@@ -0,0 +1,109 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2018 Alibaba Group
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.tmall.wireless.tangram.example.tangram3;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+import com.tmall.wireless.tangram.example.R;
+import com.tmall.wireless.tangram.example.support.SampleScrollSupport;
+import com.tmall.wireless.tangram3.structure.BaseCell;
+import com.tmall.wireless.tangram3.structure.view.ITangramViewLifeCycle;
+
+/**
+ * Created by villadora on 15/8/24.
+ */
+public class TestBlockView extends FrameLayout implements ITangramViewLifeCycle, SampleScrollSupport.IScrollListener {
+ private TextView textView;
+ private BaseCell cell;
+
+ public TestBlockView(Context context) {
+ super(context);
+ init();
+ }
+
+ public TestBlockView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public TestBlockView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ private void init() {
+ inflate(getContext(), R.layout.item, this);
+ textView = (TextView) findViewById(R.id.title);
+ }
+
+ @Override
+ public void cellInited(BaseCell cell) {
+ setOnClickListener(cell);
+ this.cell = cell;
+ if (cell.serviceManager != null) {
+ SampleScrollSupport scrollSupport = cell.serviceManager.getService(SampleScrollSupport.class);
+ scrollSupport.register(this);
+ }
+ }
+
+ @Override
+ public void postBindView(BaseCell cell) {
+ int pos = cell.pos;
+ String parent = "";
+ if (cell.parent != null) {
+ parent = cell.parent.getClass().getSimpleName();
+ }
+ textView.setText(
+ cell.id + " pos: " + pos + " " + parent + " " + cell
+ .optParam("msg"));
+
+ if (pos > 57) {
+ textView.setBackgroundColor(0x66cccf00 + (pos - 50) * 128);
+ } else if (pos % 2 == 0) {
+ textView.setBackgroundColor(0xaaaaff55);
+ } else {
+ textView.setBackgroundColor(0xcceeeeee);
+ }
+ }
+
+ @Override
+ public void postUnBindView(BaseCell cell) {
+ }
+
+ @Override
+ public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+ Log.i("TestView", "onScrollStateChanged: ");
+ }
+
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ Log.i("TestView", "onScrolled: ");
+ }
+}
diff --git a/examples/src/main/java/com/tmall/wireless/tangram/example/tangram3/TestImageView.java b/examples/src/main/java/com/tmall/wireless/tangram/example/tangram3/TestImageView.java
new file mode 100644
index 0000000..a43cc75
--- /dev/null
+++ b/examples/src/main/java/com/tmall/wireless/tangram/example/tangram3/TestImageView.java
@@ -0,0 +1,180 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2018 Alibaba Group
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.tmall.wireless.tangram.example.tangram3;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.Space;
+import android.widget.TextView;
+
+import com.tmall.wireless.tangram3.dataparser.concrete.Style;
+import com.tmall.wireless.tangram3.structure.BaseCell;
+import com.tmall.wireless.tangram3.structure.view.ITangramViewLifeCycle;
+import com.tmall.wireless.tangram3.util.BDE;
+import com.tmall.wireless.tangram3.util.LifeCycleProviderImpl;
+
+import io.reactivex.Observable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.functions.Consumer;
+import io.reactivex.functions.Function;
+import io.reactivex.schedulers.Schedulers;
+
+public class TestImageView extends LinearLayout implements ITangramViewLifeCycle {
+
+ public ImageView icon;
+
+ public TextView titleTextView;
+
+ private Context context;
+
+ private final int DEFAULT_ICON_SIZE = Style.dp2px(100);
+
+ public TestImageView(Context context) {
+ this(context, null);
+ }
+
+ public TestImageView(Context context, AttributeSet attrs) {
+ this(context, attrs, -1);
+ }
+
+ public TestImageView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ this.context = context;
+ initUI(context, DEFAULT_ICON_SIZE);
+ }
+
+ private void initUI(Context context, int size){
+ setOrientation(VERTICAL);
+ setGravity(Gravity.CENTER_HORIZONTAL);
+ setBackgroundColor(Color.WHITE);
+
+ icon = new ImageView(context);
+ icon.setScaleType(ImageView.ScaleType.CENTER_CROP);
+
+ LayoutParams iconLp = new LayoutParams(size, size);
+ iconLp.topMargin = Style.dp2px(8);
+ addView(icon, iconLp);
+
+ titleTextView = new TextView(context);
+ titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
+ LayoutParams titleLp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT);
+ titleLp.topMargin = Style.dp2px(4.0);
+ addView(titleTextView, titleLp);
+
+ Space space = new Space(context);
+ LayoutParams spaceLp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ Style.dp2px(8));
+ addView(space, spaceLp);
+ }
+
+
+ @Override
+ public void cellInited(BaseCell cell) {
+ setOnClickListener(cell);
+ }
+
+ @Override
+ public void postBindView(BaseCell cell) {
+ if (cell.serviceManager != null && cell.serviceManager.supportRx()) {
+ LifeCycleProviderImpl lifeCycleProvider = cell.getLifeCycleProvider();
+ Observable.just(cell).map(new Function() {
+ @Override
+ public String apply(BaseCell cell) throws Exception {
+ Thread.sleep(500L);
+ int pos = cell.pos;
+ return cell.id + " pos: " + pos + " " + cell.parent.getClass().getSimpleName() + " " + cell
+ .optStringParam("title");
+ }
+ }).subscribeOn(Schedulers.computation())
+ .observeOn(AndroidSchedulers.mainThread())
+ .compose(lifeCycleProvider.bindUntil(BDE.UNBIND))
+ .subscribe(new Consumer() {
+ @Override
+ public void accept(String s) throws Exception {
+ titleTextView.setText(s);
+ }
+ });
+
+ Observable.just(cell).map(new Function() {
+ @Override
+ public Integer apply(BaseCell cell) throws Exception {
+ Thread.sleep(500L);
+ int pos = cell.pos;
+ if (pos > 57) {
+ return 0x66cccf00 + (pos - 50) * 128;
+ } else if (pos % 2 == 0) {
+ return 0xaaaaff55;
+ } else {
+ return 0xcceeeeee;
+ }
+ }
+ }).subscribeOn(Schedulers.computation())
+ .observeOn(AndroidSchedulers.mainThread())
+ .compose(lifeCycleProvider.bindUntil(BDE.UNBIND))
+ .subscribe(new Consumer() {
+ @Override
+ public void accept(Integer s) throws Exception {
+ icon.setBackgroundColor(s);
+ }
+ });
+ } else {
+ int pos = cell.pos;
+ titleTextView.setText(cell.id + " pos: " + pos + " " + cell.parent.getClass().getSimpleName() + " " + cell
+ .optStringParam("title"));
+ if (pos > 57) {
+ icon.setBackgroundColor(0x66cccf00 + (pos - 50) * 128);
+ } else if (pos % 2 == 0) {
+ icon.setBackgroundColor(0xaaaaff55);
+ } else {
+ icon.setBackgroundColor(0xcceeeeee);
+ }
+ }
+ }
+
+ @Override
+ public void postUnBindView(BaseCell cell) {
+
+ }
+
+ public static int parseColor(String colorStr, String defaultColor) {
+ try {
+ return Color.parseColor(colorStr);
+ } catch (Exception e) {
+ return Color.parseColor(defaultColor);
+ }
+ }
+
+ public static boolean isEmpty(String string){
+ return string == null || string.isEmpty() || "null".equalsIgnoreCase(string);
+ }
+
+}
diff --git a/examples/src/main/java/com/tmall/wireless/tangram/example/tangram3/VirtualViewRenderService3.java b/examples/src/main/java/com/tmall/wireless/tangram/example/tangram3/VirtualViewRenderService3.java
new file mode 100644
index 0000000..5fcefe4
--- /dev/null
+++ b/examples/src/main/java/com/tmall/wireless/tangram/example/tangram3/VirtualViewRenderService3.java
@@ -0,0 +1,159 @@
+package com.tmall.wireless.tangram.example.tangram3;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.squareup.picasso.Picasso;
+import com.squareup.picasso.RequestCreator;
+import com.squareup.picasso.Target;
+import com.tmall.wireless.tangram3.TangramEngine;
+import com.tmall.wireless.tangram3.core.protocol.ElementRenderService;
+import com.tmall.wireless.tangram3.dataparser.concrete.ComponentInfo;
+import com.tmall.wireless.tangram.example.data.DEBUG;
+import com.tmall.wireless.tangram.example.data.VVTEST;
+import com.tmall.wireless.vaf.framework.VafContext;
+import com.tmall.wireless.vaf.virtualview.Helper.ImageLoader;
+import com.tmall.wireless.vaf.virtualview.core.IContainer;
+import com.tmall.wireless.vaf.virtualview.core.ViewBase;
+import com.tmall.wireless.vaf.virtualview.event.EventData;
+import com.tmall.wireless.vaf.virtualview.event.EventManager;
+import com.tmall.wireless.vaf.virtualview.view.image.ImageBase;
+
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class VirtualViewRenderService3 extends ElementRenderService {
+ private VafContext vafContext;
+
+ private TangramEngine tangramEngine;
+
+ private static class ImageTarget implements Target {
+
+ ImageBase mImageBase;
+
+ ImageLoader.Listener mListener;
+
+ public ImageTarget(ImageBase imageBase) {
+ mImageBase = imageBase;
+ }
+
+ public ImageTarget(ImageLoader.Listener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
+ mImageBase.setBitmap(bitmap, true);
+ if (mListener != null) {
+ mListener.onImageLoadSuccess(bitmap);
+ }
+ Log.d("TangramActivity", "onBitmapLoaded " + from);
+ }
+
+ @Override
+ public void onBitmapFailed(Drawable errorDrawable) {
+ if (mListener != null) {
+ mListener.onImageLoadFailed();
+ }
+ Log.d("TangramActivity", "onBitmapFailed ");
+ }
+
+ @Override
+ public void onPrepareLoad(Drawable placeHolderDrawable) {
+ Log.d("TangramActivity", "onPrepareLoad ");
+ }
+ }
+
+ private ImageLoader.IImageLoaderAdapter imageLoaderAdapter = new ImageLoader.IImageLoaderAdapter() {
+
+ private List cache = new ArrayList();
+
+ @Override
+ public void bindImage(String uri, final ImageBase imageBase, int reqWidth, int reqHeight) {
+ RequestCreator requestCreator = Picasso.with(tangramEngine.getContext()).load(uri);
+ Log.d("TangramActivity", "bindImage request width height " + reqHeight + " " + reqWidth);
+ if (reqHeight > 0 || reqWidth > 0) {
+ requestCreator.resize(reqWidth, reqHeight);
+ }
+ ImageTarget imageTarget = new ImageTarget(imageBase);
+ cache.add(imageTarget);
+ requestCreator.into(imageTarget);
+ }
+
+ @Override
+ public void getBitmap(String uri, int reqWidth, int reqHeight, final ImageLoader.Listener lis) {
+ RequestCreator requestCreator = Picasso.with(tangramEngine.getContext()).load(uri);
+ Log.d("TangramActivity", "getBitmap request width height " + reqHeight + " " + reqWidth);
+ if (reqHeight > 0 || reqWidth > 0) {
+ requestCreator.resize(reqWidth, reqHeight);
+ }
+ ImageTarget imageTarget = new ImageTarget(lis);
+ cache.add(imageTarget);
+ requestCreator.into(imageTarget);
+ }
+ };
+
+ @Override
+ public void init(TangramEngine tangramEngine) {
+ this.tangramEngine = tangramEngine;
+ vafContext = new VafContext(tangramEngine.getContext());
+ tangramEngine.register(VafContext.class, vafContext);
+ vafContext.getViewManager().init(tangramEngine.getContext());
+ vafContext.setImageLoaderAdapter(imageLoaderAdapter);
+ vafContext.getViewManager().loadBinBufferSync(VVTEST.BIN);
+ vafContext.getViewManager().loadBinBufferSync(DEBUG.BIN);
+ }
+
+ @Override
+ public View createView(Context context, ViewGroup parent, ComponentInfo info) {
+ return vafContext.getContainerService().getContainer(info.getName(), true);
+ }
+
+ @Override
+ public boolean mountView(JSONObject json, View view) {
+ ViewBase vb = ((IContainer) view).getVirtualView();
+ vb.setVData(json);
+ if (vb.supportExposure()) {
+ vafContext.getEventManager().emitEvent(
+ EventManager.TYPE_Exposure, EventData.obtainData(vafContext, vb));
+ }
+
+ return true;
+ }
+
+ @Override
+ public void unmountView(JSONObject json, View view) {
+ if (view instanceof IContainer) {
+ ViewBase vb = ((IContainer) view).getVirtualView();
+ vb.reset();
+ }
+ }
+
+ @Override
+ public void destroy() {
+ if (vafContext != null) {
+ vafContext.onDestroy();
+ }
+ }
+
+ @Override
+ public ComponentInfo onParseComponentInfo(ComponentInfo info) {
+ return info;
+ }
+
+ @Override
+ public String getSDKBizName() {
+ return "VirtualView";
+ }
+
+ @Override
+ public void onDownloadComponentInfo(List componentInfoList) {
+
+ }
+}
diff --git a/gradle.properties b/gradle.properties
index e98132c..61050fd 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -46,7 +46,7 @@ org.gradle.jvmargs=-Xmx1536M
GROUP=com.alibaba.android
ARTIFACT=tangram
VERSION=1
-VERSION_NAME=3.2.0.3
+VERSION_NAME=3.2.0.4
PACKAGING_TYPE=aar
systemProp.compileSdkVersion=26
systemProp.targetSdkVersion=26
diff --git a/tangram/src/main/java/com/tmall/wireless/tangram3/TangramBuilder.java b/tangram/src/main/java/com/tmall/wireless/tangram3/TangramBuilder.java
index aa29c57..1225625 100644
--- a/tangram/src/main/java/com/tmall/wireless/tangram3/TangramBuilder.java
+++ b/tangram/src/main/java/com/tmall/wireless/tangram3/TangramBuilder.java
@@ -418,16 +418,6 @@ public class TangramBuilder {
mDefaultResolverRegistry.registerCard(type, cardClz);
}
- /**
- * Now do noting, just exist for compatibility.
- * register item render by virtual view
- *
- * @param type
- */
- @Deprecated
- public void registerVirtualView(String type) {
- }
-
/**
* set a custom {@link IAdapterBuilder} to build adapter, the default is {@link PojoAdapterBuilder} which
* would create a {@link PojoGroupBasicAdapter}
diff --git a/tangram/src/main/java/com/tmall/wireless/tangram3/dataparser/concrete/PojoDataParser.java b/tangram/src/main/java/com/tmall/wireless/tangram3/dataparser/concrete/PojoDataParser.java
index fdd2e01..e89091d 100644
--- a/tangram/src/main/java/com/tmall/wireless/tangram3/dataparser/concrete/PojoDataParser.java
+++ b/tangram/src/main/java/com/tmall/wireless/tangram3/dataparser/concrete/PojoDataParser.java
@@ -491,6 +491,7 @@ public class PojoDataParser extends DataParser {
fixStyle.x = Style.parseSize(styleJson.optString(KEY_X), 0);
fixStyle.y = Style.parseSize(styleJson.optString(KEY_Y), 0);
+ card.style = fixStyle;
} else if (card instanceof LinearScrollCard) {
LinearScrollCard linearScrollCard = (LinearScrollCard) card;
JSONObject obj = new JSONObject();
@@ -715,6 +716,12 @@ public class PojoDataParser extends DataParser {
}
parseCell(cell, cellData);
+ if (parent != null) {
+ boolean ret = parent.addCellInternal(cell, false);
+ if (!ret && TangramBuilder.isPrintLog()) {
+ LogUtils.w(TAG, "Parse invalid cell with data: " + cellData.toString());
+ }
+ }
return cell;
} else {
BaseCellBinderResolver componentBinderResolver = serviceManager.getService(BaseCellBinderResolver.class);
diff --git a/tangram/src/main/java/com/tmall/wireless/tangram3/structure/cell/LinearScrollCell.java b/tangram/src/main/java/com/tmall/wireless/tangram3/structure/cell/LinearScrollCell.java
index 4340d1f..4f3010f 100644
--- a/tangram/src/main/java/com/tmall/wireless/tangram3/structure/cell/LinearScrollCell.java
+++ b/tangram/src/main/java/com/tmall/wireless/tangram3/structure/cell/LinearScrollCell.java
@@ -120,10 +120,13 @@ public class LinearScrollCell extends BaseCell {
@Override
public void onAdded() {
super.onAdded();
- adapter = new Adapter(getAdapter());
}
public void setCells(List cells) {
+ if (adapter == null) {
+ adapter = new Adapter(getAdapter());
+ }
+
this.cells.clear();
if (cells != null && cells.size() > 0) {
this.cells.addAll(cells);
@@ -151,7 +154,7 @@ public class LinearScrollCell extends BaseCell {
return rawPosition;
}
- int columnCount = (int)(cellCount * 1.0f / maxRows + 0.5f);
+ int columnCount = (int) (cellCount * 1.0f / maxRows + 0.5f);
int rowIndex = rawPosition / maxRows;
int columnIndex = rawPosition % maxRows;