feat:add onLoadMore for Android
This commit is contained in:
parent
6ea333e482
commit
6045a08360
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Reference in New Issue
Block a user