feat:add onLoadMore for Android

This commit is contained in:
pengfei.zhou 2019-12-10 16:40:12 +08:00
parent 6ea333e482
commit 6045a08360
4 changed files with 46 additions and 18 deletions

View File

@ -85,6 +85,10 @@ public abstract class SuperNode<V extends View> extends ViewNode<V> {
subNodes.clear(); subNodes.clear();
} }
public void removeSubModel(String id) {
subNodes.remove(id);
}
protected abstract void blendSubNode(JSObject subProperties); protected abstract void blendSubNode(JSObject subProperties);
protected void blendSubLayoutConfig(ViewNode viewNode, JSObject jsObject) { protected void blendSubLayoutConfig(ViewNode viewNode, JSObject jsObject) {

View File

@ -39,6 +39,7 @@ public class TextNode extends ViewNode<TextView> {
protected TextView build() { protected TextView build() {
TextView tv = new TextView(getContext()); TextView tv = new TextView(getContext());
tv.setGravity(Gravity.CENTER); tv.setGravity(Gravity.CENTER);
tv.setMaxLines(1);
return tv; return tv;
} }

View File

@ -16,7 +16,6 @@
package pub.doric.shader.list; package pub.doric.shader.list;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.SparseArray;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -40,10 +39,6 @@ import pub.doric.shader.ViewNode;
class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolder> { class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolder> {
private final ListNode listNode; private final ListNode listNode;
String renderItemFuncId;
int itemCount = 0;
int batchCount = 15;
SparseArray<String> itemValues = new SparseArray<>();
ListAdapter(ListNode listNode) { ListAdapter(ListNode listNode) {
this.listNode = listNode; this.listNode = listNode;
@ -65,15 +60,21 @@ class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolder> {
holder.listItemNode.setId(jsObject.getProperty("id").asString().value()); holder.listItemNode.setId(jsObject.getProperty("id").asString().value());
holder.listItemNode.blend(jsObject.getProperty("props").asObject()); holder.listItemNode.blend(jsObject.getProperty("props").asObject());
} }
if (position >= this.listNode.itemCount) {
this.listNode.callJSResponse(this.listNode.onLoadMoreFuncId);
}
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return itemCount; return this.listNode.itemCount + (this.listNode.loadMore ? 1 : 0);
} }
@Override @Override
public int getItemViewType(int position) { public int getItemViewType(int position) {
if (position >= this.listNode.itemCount) {
return Integer.MAX_VALUE;
}
JSValue value = getItemModel(position); JSValue value = getItemModel(position);
if (value != null && value.isObject()) { if (value != null && value.isObject()) {
if (value.asObject().getProperty("identifier").isString()) { if (value.asObject().getProperty("identifier").isString()) {
@ -84,12 +85,15 @@ class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolder> {
} }
private JSValue getItemModel(final int position) { private JSValue getItemModel(final int position) {
String id = itemValues.get(position); if (position >= this.listNode.itemCount) {
return this.listNode.getSubModel(this.listNode.loadMoreViewId);
}
String id = listNode.itemValues.get(position);
if (TextUtils.isEmpty(id)) { if (TextUtils.isEmpty(id)) {
AsyncResult<JSDecoder> asyncResult = listNode.callJSResponse( AsyncResult<JSDecoder> asyncResult = listNode.callJSResponse(
"renderBunchedItems", "renderBunchedItems",
position, position,
batchCount); listNode.batchCount);
try { try {
JSDecoder jsDecoder = asyncResult.synchronous().get(); JSDecoder jsDecoder = asyncResult.synchronous().get();
JSValue result = jsDecoder.decode(); JSValue result = jsDecoder.decode();
@ -98,10 +102,10 @@ class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolder> {
for (int i = 0; i < jsArray.size(); i++) { for (int i = 0; i < jsArray.size(); i++) {
JSObject itemModel = jsArray.get(i).asObject(); JSObject itemModel = jsArray.get(i).asObject();
String itemId = itemModel.getProperty("id").asString().value(); String itemId = itemModel.getProperty("id").asString().value();
itemValues.put(i + position, itemId); listNode.itemValues.put(i + position, itemId);
listNode.setSubModel(itemId, itemModel); listNode.setSubModel(itemId, itemModel);
} }
return listNode.getSubModel(itemValues.get(position)); return listNode.getSubModel(listNode.itemValues.get(position));
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -119,8 +123,8 @@ class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolder> {
void blendSubNode(JSObject subProperties) { void blendSubNode(JSObject subProperties) {
for (int i = 0; i < itemValues.size(); i++) { for (int i = 0; i < listNode.itemValues.size(); i++) {
if (subProperties.getProperty("id").asString().value().equals(itemValues.valueAt(i))) { if (subProperties.getProperty("id").asString().value().equals(listNode.itemValues.valueAt(i))) {
notifyItemChanged(i); notifyItemChanged(i);
} }
} }

View File

@ -15,6 +15,7 @@
*/ */
package pub.doric.shader.list; package pub.doric.shader.list;
import android.util.SparseArray;
import android.view.View; import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
@ -36,6 +37,13 @@ import pub.doric.shader.ViewNode;
@DoricPlugin(name = "List") @DoricPlugin(name = "List")
public class ListNode extends SuperNode<RecyclerView> { public class ListNode extends SuperNode<RecyclerView> {
private final ListAdapter listAdapter; private final ListAdapter listAdapter;
private String renderItemFuncId;
String onLoadMoreFuncId;
int itemCount = 0;
int batchCount = 15;
SparseArray<String> itemValues = new SparseArray<>();
boolean loadMore = false;
String loadMoreViewId;
public ListNode(DoricContext doricContext) { public ListNode(DoricContext doricContext) {
super(doricContext); super(doricContext);
@ -82,19 +90,30 @@ public class ListNode extends SuperNode<RecyclerView> {
protected void blend(RecyclerView view, String name, JSValue prop) { protected void blend(RecyclerView view, String name, JSValue prop) {
switch (name) { switch (name) {
case "itemCount": case "itemCount":
this.listAdapter.itemCount = prop.asNumber().toInt(); this.itemCount = prop.asNumber().toInt();
break; break;
case "renderItem": case "renderItem":
String funcId = prop.asString().value(); String funcId = prop.asString().value();
if (!funcId.equals(this.listAdapter.renderItemFuncId)) { if (!funcId.equals(this.renderItemFuncId)) {
this.listAdapter.renderItemFuncId = funcId; this.renderItemFuncId = funcId;
// If reset renderItem,should reset native cache. // If reset renderItem,should reset native cache.
this.listAdapter.itemValues.clear(); for (int index = 0; index < this.itemValues.size(); index++) {
clearSubModel(); removeSubModel(this.itemValues.valueAt(index));
}
this.itemValues.clear();
} }
break; break;
case "onLoadMore":
this.onLoadMoreFuncId = prop.asString().value();
break;
case "loadMoreView":
this.loadMoreViewId = prop.asString().value();
break;
case "batchCount": case "batchCount":
this.listAdapter.batchCount = prop.asNumber().toInt(); this.batchCount = prop.asNumber().toInt();
break;
case "loadMore":
this.loadMore = prop.asBoolean().value();
break; break;
default: default:
super.blend(view, name, prop); super.blend(view, name, prop);