Merge pull request #67 from liufsd/feature/dataparser

add: DataParser By Developer
This commit is contained in:
Xiaolong Hong
2017-12-14 10:05:26 +08:00
committed by GitHub
6 changed files with 448 additions and 1 deletions
+2
View File
@@ -53,4 +53,6 @@ dependencies {
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.android.support:appcompat-v7:21.0.0'
compile 'com.android.support:support-annotations:21.0.0'
compile 'com.google.code.gson:gson:2.8.1'
}
+6
View File
@@ -40,6 +40,12 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!--<activity android:name="com.tmall.wireless.tangram.example.TangramDataParserActivity">-->
<!--<intent-filter>-->
<!--<action android:name="android.intent.action.MAIN"/>-->
<!--<category android:name="android.intent.category.LAUNCHER"/>-->
<!--</intent-filter>-->
<!--</activity>-->
</application>
</manifest>
+53
View File
@@ -0,0 +1,53 @@
[
{
"items": [
{
"msg": "banner item 0",
"type": 110
},
{
"msg": "banner item 1",
"type": 110
}
],
"type": 1000
},
{
"iconList": [
{
"subTitle": "测试内容10jm",
"title": "测试内容7774",
"type": 1
},
{
"subTitle": "测试内容10jm",
"title": "测试内容7774",
"type": 1
},
{
"subTitle": "测试内容10jm",
"title": "测试内容7774",
"type": 1
},
{
"subTitle": "测试内容10jm",
"title": "测试内容7774",
"type": 1
}
],
"type": 2000
},
{
"centerBannerList": [
{
"msg": "centerBannerList 0",
"type": 110
},
{
"msg": "centerBannerList 1",
"type": 110
}
],
"type": 1000
}
]
@@ -0,0 +1,265 @@
package com.tmall.wireless.tangram.example;
import com.alibaba.android.vlayout.Range;
import com.libra.Utils;
import com.squareup.picasso.Picasso;
import com.tmall.wireless.tangram.TangramBuilder;
import com.tmall.wireless.tangram.TangramEngine;
import com.tmall.wireless.tangram.core.adapter.GroupBasicAdapter;
import com.tmall.wireless.tangram.dataparser.concrete.Card;
import com.tmall.wireless.tangram.example.data.RatioTextView;
import com.tmall.wireless.tangram.example.data.SimpleImgView;
import com.tmall.wireless.tangram.example.data.SingleImageView;
import com.tmall.wireless.tangram.example.data.TestView;
import com.tmall.wireless.tangram.example.data.TestViewHolder;
import com.tmall.wireless.tangram.example.data.TestViewHolderCell;
import com.tmall.wireless.tangram.example.data.VVTEST;
import com.tmall.wireless.tangram.example.dataparser.SampleDataParser;
import com.tmall.wireless.tangram.example.support.SampleClickSupport;
import com.tmall.wireless.tangram.structure.BaseCell;
import com.tmall.wireless.tangram.structure.card.BannerCard;
import com.tmall.wireless.tangram.structure.card.FourColumnCard;
import com.tmall.wireless.tangram.structure.viewcreator.ViewHolderCreator;
import com.tmall.wireless.tangram.support.async.AsyncLoader;
import com.tmall.wireless.tangram.support.async.AsyncPageLoader;
import com.tmall.wireless.tangram.support.async.CardLoadSupport;
import com.tmall.wireless.tangram.util.IInnerImageSetter;
import com.tmall.wireless.vaf.framework.VafContext;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
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.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* Created by liupeng on 13/12/2017.
*/
public class TangramDataParserActivity extends Activity {
private static final String TAG = TangramActivity.class.getSimpleName();
private Handler mMainHandler;
TangramEngine engine;
TangramBuilder.InnerBuilder builder;
RecyclerView recyclerView;
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
protected void onCreate(Bundle savedInstanceState) {
try {
Picasso.setSingletonInstance(new Picasso.Builder(this).loggingEnabled(true).build());
} catch (Exception e) {
}
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
recyclerView = (RecyclerView) findViewById(R.id.main_view);
//Step 1: init tangram
TangramBuilder.init(this, new IInnerImageSetter() {
@Override
public <IMAGE extends ImageView> void doLoadImageUrl(@NonNull IMAGE view,
@Nullable String url) {
Picasso.with(TangramDataParserActivity.this).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);
//add: custom dataParser
builder.setDataParser(new SampleDataParser());
//Step 3: register business cells and cards
builder.registerCard(1000, BannerCard.class);
builder.registerCard(2000, FourColumnCard.class);
builder.registerCell(1, TestView.class);
builder.registerCell(10, SimpleImgView.class);
builder.registerCell(2, SimpleImgView.class);
builder.registerCell(4, RatioTextView.class);
builder.registerCell(110,
TestViewHolderCell.class,
new ViewHolderCreator<>(R.layout.item_holder, TestViewHolder.class, TextView.class));
builder.registerCell(199,SingleImageView.class);
builder.registerVirtualView("vvtest");
//Step 4: new engine
engine = builder.build();
engine.setVirtualViewTemplate(VVTEST.BIN);
Utils.setUedScreenWidth(720);
VafContext.loadImageLoader(getApplicationContext());
//Step 5: add card load support if you have card that loading cells async
engine.addCardLoadSupport(new CardLoadSupport(
new AsyncLoader() {
@Override
public void loadData(Card card, @NonNull final LoadedCallback callback) {
Log.w("Load Card", card.load);
mMainHandler.postDelayed(new Runnable() {
@Override
public void run() {
// do loading
JSONArray cells = new JSONArray();
for (int i = 0; i < 10; i++) {
try {
JSONObject obj = new JSONObject();
obj.put("type", 1);
obj.put("msg", "async loaded");
JSONObject style = new JSONObject();
style.put("bgColor", "#FF1111");
obj.put("style", style.toString());
cells.put(obj);
} catch (JSONException e) {
e.printStackTrace();
}
}
// callback.fail(false);
callback.finish(engine.parseComponent(cells));
}
}, 200);
}
},
new AsyncPageLoader() {
@Override
public void loadData(final int page, @NonNull final Card card, @NonNull final LoadedCallback callback) {
mMainHandler.postDelayed(new Runnable() {
@Override
public void run() {
Log.w("Load page", card.load + " page " + page);
JSONArray cells = new JSONArray();
for (int i = 0; i < 9; i++) {
try {
JSONObject obj = new JSONObject();
obj.put("type", 1);
obj.put("msg", "async page loaded, params: " + card.getParams().toString());
cells.put(obj);
} catch (JSONException e) {
e.printStackTrace();
}
}
List<BaseCell> cs = engine.parseComponent(cells);
if (card.page == 1) {
GroupBasicAdapter<Card, ?> adapter = engine.getGroupBasicAdapter();
card.setCells(cs);
adapter.refreshWithoutNotify();
Range<Integer> range = adapter.getCardRange(card);
adapter.notifyItemRemoved(range.getLower());
adapter.notifyItemRangeInserted(range.getLower(), cs.size());
} else
card.addCells(cs);
//mock load 6 pages
callback.finish(card.page != 6);
card.notifyDataChange();
}
}, 400);
}
}));
engine.addSimpleClickSupport(new SampleClickSupport());
//Step 6: enable auto load more if your page's data is lazy loaded
engine.enableAutoLoadMore(true);
//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, "data_third.json"));
JSONArray data = null;
try {
data = new JSONArray(json);
engine.setData(data);
} catch (JSONException e) {
e.printStackTrace();
}
findViewById(R.id.first).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
engine.refresh(true);
}
});
}
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;
}
}
@@ -0,0 +1,121 @@
package com.tmall.wireless.tangram.example.dataparser;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.tmall.wireless.tangram.MVHelper;
import com.tmall.wireless.tangram.core.service.ServiceManager;
import com.tmall.wireless.tangram.dataparser.DataParser;
import com.tmall.wireless.tangram.dataparser.concrete.Card;
import com.tmall.wireless.tangram.dataparser.concrete.CardResolver;
import com.tmall.wireless.tangram.structure.BaseCell;
import com.tmall.wireless.tangram.structure.card.BannerCard;
import com.tmall.wireless.tangram.structure.card.GridCard;
import com.tmall.wireless.tangram.util.Preconditions;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* Created by liupeng on 13/12/2017.
*/
public class SampleDataParser extends DataParser<JSONArray, Card, BaseCell> {
@Nullable
@Override
public List<Card> parseGroup(@Nullable JSONArray data, ServiceManager serviceManager) {
final CardResolver cardResolver = serviceManager.getService(CardResolver.class);
Preconditions.checkState(cardResolver != null, "Must register CardResolver into ServiceManager first");
final MVHelper cellResolver = serviceManager.getService(MVHelper.class);
Preconditions.checkState(cellResolver != null, "Must register CellResolver into ServiceManager first");
final int size = data.length();
final List<Card> result = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
JSONObject cardData = data.optJSONObject(i);
if (cardData != null) {
//maybe custom card
final String cardType = cardData.optString(Card.KEY_TYPE);
if (!TextUtils.isEmpty(cardType)) {
final Card card = cardResolver.create(cardType);
if (card != null) {
card.rowId = i;
card.serviceManager = serviceManager;
//add card style
addCardStyle(cardData, card);
//custom items element key if need.
transformCardCellData(cardData);
//parser card
card.parseWith(cardData, cellResolver);
card.type = cardData.optInt(Card.KEY_TYPE, -1);
card.stringType = cardType;
result.add(card);
}
}
}
}
cellResolver.resolver().setCards(result);
return result;
}
private void addCardStyle(JSONObject cardData, Card card) {
try {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Float.class, new JsonSerializer<Float>() {
@Override
public JsonElement serialize(final Float src, final Type typeOfSrc, final JsonSerializationContext context) {
try {
if (src.isInfinite() || src.isNaN()) {
return new JsonPrimitive(0f);
}
BigDecimal value = BigDecimal.valueOf(src);
return new JsonPrimitive(value);
} catch (Exception e) {
e.printStackTrace();
}
return new JsonPrimitive(0f);
}
});
Gson gson = gsonBuilder.create();
GridCard.GridStyle gridStyle = new GridCard.GridStyle();
if (card instanceof BannerCard) {
gridStyle.aspectRatio = 3.223f;
}
cardData.put(Card.KEY_STYLE, new JSONObject(gson.toJson(gridStyle)));
} catch (JSONException e) {
e.printStackTrace();
}
}
private void transformCardCellData(JSONObject cardData) {
try {
if (cardData.has("iconList")) {
cardData.put(Card.KEY_ITEMS, cardData.getJSONArray("iconList"));
} else if (cardData.has("centerBannerList")) {
cardData.put(Card.KEY_ITEMS, cardData.getJSONArray("centerBannerList"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Nullable
@Override
public List<BaseCell> parseComponent(@Nullable JSONArray data, ServiceManager serviceManager) {
return null;
}
}
@@ -182,7 +182,7 @@ public abstract class Card extends ComponentLifecycle implements ITangramExprPar
* serviceManager
*/
@Nullable
protected ServiceManager serviceManager;
public ServiceManager serviceManager;
// TODO: back store refactor