listview use supernode

This commit is contained in:
pengfei.zhou 2019-11-14 21:00:33 +08:00
parent e3d07dc3ef
commit 401d0e57a0
7 changed files with 43 additions and 41 deletions

View File

@ -50,7 +50,7 @@ public class MainActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
doricContext = DoricContext.create(this, DoricUtils.readAssetFile("demo/Snake.js"), "test"); doricContext = DoricContext.create(this, DoricUtils.readAssetFile("demo/ListDemo.js"), "test");
doricContext.init(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); doricContext.init(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
doricContext.getRootNode().setRootView((FrameLayout) findViewById(R.id.root)); doricContext.getRootNode().setRootView((FrameLayout) findViewById(R.id.root));

View File

@ -95,7 +95,7 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
newNode.init(this); newNode.init(this);
newNode.blend(model.getProperty("props").asObject()); newNode.blend(model.getProperty("props").asObject());
mChildNodes.set(idx, newNode); mChildNodes.add(idx, newNode);
mView.addView(newNode.getDoricLayer(), idx, newNode.getLayoutParams()); mView.addView(newNode.getDoricLayer(), idx, newNode.getLayoutParams());
} }
} }

View File

@ -74,6 +74,10 @@ public abstract class SuperNode<V extends View> extends ViewNode<V> {
return subNodes.get(id); return subNodes.get(id);
} }
public void setSubModel(String id, JSObject model) {
subNodes.put(id, model);
}
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) {
@ -127,35 +131,15 @@ public abstract class SuperNode<V extends View> extends ViewNode<V> {
} }
private void mixin(JSObject src, JSObject target) { private void mixin(JSObject src, JSObject target) {
JSValue srcProps = src.getProperty("props"); JSObject srcProps = src.getProperty("props").asObject();
JSValue targetProps = target.getProperty("props"); JSObject targetProps = target.getProperty("props").asObject();
if (srcProps.isObject()) { for (String key : srcProps.propertySet()) {
if (targetProps.isObject()) { JSValue jsValue = srcProps.getProperty(key);
for (String key : srcProps.asObject().propertySet()) { if ("subviews".equals(key) && jsValue.isArray()) {
JSValue jsValue = srcProps.asObject().getProperty(key);
if ("children".equals(key) && jsValue.isArray()) {
JSValue targetChildren = targetProps.asObject().getProperty("children");
if (targetChildren.isArray() && targetChildren.asArray().size() == jsValue.asArray().size()) {
for (int i = 0; i < jsValue.asArray().size(); i++) {
JSValue childSrc = jsValue.asArray().get(i);
JSValue childTarget = targetChildren.asArray().get(i);
if (childSrc.isObject()) {
if (childTarget.isObject()) {
mixin(childSrc.asObject(), childTarget.asObject());
} else {
targetChildren.asArray().put(i, childSrc);
}
}
}
}
continue; continue;
} }
targetProps.asObject().setProperty(key, jsValue); targetProps.asObject().setProperty(key, jsValue);
} }
} else {
target.setProperty("props", srcProps);
}
}
} }
} }

View File

@ -55,6 +55,7 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
this.mSuperNode = superNode; this.mSuperNode = superNode;
this.mLayoutParams = superNode.generateDefaultLayoutParams(); this.mLayoutParams = superNode.generateDefaultLayoutParams();
this.doricLayer = new DoricLayer(getContext()); this.doricLayer = new DoricLayer(getContext());
this.doricLayer.setLayoutParams(mLayoutParams);
this.mView = build(); this.mView = build();
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(mLayoutParams.width, mLayoutParams.height); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(mLayoutParams.width, mLayoutParams.height);
doricLayer.addView(mView, params); doricLayer.addView(mView, params);

View File

@ -15,6 +15,7 @@
*/ */
package pub.doric.shader.list; package pub.doric.shader.list;
import android.text.TextUtils;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -24,6 +25,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.github.pengfeizhou.jscore.JSArray; import com.github.pengfeizhou.jscore.JSArray;
import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JSNull;
import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue; import com.github.pengfeizhou.jscore.JSValue;
@ -37,12 +39,11 @@ import pub.doric.shader.ViewNode;
*/ */
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolder> { public class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolder> {
final ListNode listNode; private final ListNode listNode;
String renderItemFuncId; String renderItemFuncId;
final String renderBunchedItemsFuncId = "renderBunchedItems";
int itemCount = 0; int itemCount = 0;
int batchCount = 15; int batchCount = 15;
SparseArray<JSValue> itemValues = new SparseArray<>(); SparseArray<String> itemValues = new SparseArray<>();
public ListAdapter(ListNode listNode) { public ListAdapter(ListNode listNode) {
this.listNode = listNode; this.listNode = listNode;
@ -82,11 +83,11 @@ public class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolde
return super.getItemViewType(position); return super.getItemViewType(position);
} }
private JSValue getItemModel(int position) { private JSValue getItemModel(final int position) {
JSValue itemModel = itemValues.get(position); String id = itemValues.get(position);
if (itemModel == null || !itemModel.isObject()) { if (TextUtils.isEmpty(id)) {
AsyncResult<JSDecoder> asyncResult = listNode.callJSResponse( AsyncResult<JSDecoder> asyncResult = listNode.callJSResponse(
renderBunchedItemsFuncId, "renderBunchedItems",
position, position,
batchCount); batchCount);
try { try {
@ -95,20 +96,34 @@ public class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolde
if (result.isArray()) { if (result.isArray()) {
JSArray jsArray = result.asArray(); JSArray jsArray = result.asArray();
for (int i = 0; i < jsArray.size(); i++) { for (int i = 0; i < jsArray.size(); i++) {
itemValues.put(i + position, jsArray.get(i)); JSObject itemModel = jsArray.get(i).asObject();
String itemId = itemModel.getProperty("id").asString().value();
itemValues.put(i + position, itemId);
listNode.setSubModel(itemId, itemModel);
} }
return itemValues.get(position); return listNode.getSubModel(itemValues.get(position));
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return new JSNull();
} else {
JSObject childModel = listNode.getSubModel(id);
if (childModel == null) {
return new JSNull();
} else {
return childModel;
}
} }
return itemModel;
} }
void blendSubNode(JSObject subProperties) { void blendSubNode(JSObject subProperties) {
for (int i = 0; i < itemValues.size(); i++) {
if (subProperties.getProperty("id").asString().value().equals(itemValues.valueAt(i))) {
notifyItemChanged(i);
}
}
} }
static class DoricViewHolder extends RecyclerView.ViewHolder { static class DoricViewHolder extends RecyclerView.ViewHolder {

View File

@ -80,6 +80,8 @@ public class ListNode extends SuperNode<RecyclerView> {
case "batchCount": case "batchCount":
this.listAdapter.batchCount = 15; this.listAdapter.batchCount = 15;
break; break;
case "subviews":
break;
default: default:
super.blend(view, name, prop); super.blend(view, name, prop);
break; break;

View File

@ -70,7 +70,7 @@ export class List extends Superview implements IList {
private renderBunchedItems(start: number, length: number) { private renderBunchedItems(start: number, length: number) {
return new Array(Math.min(length, this.itemCount - start)).fill(0).map((_, idx) => { return new Array(Math.min(length, this.itemCount - start)).fill(0).map((_, idx) => {
const listItem = this.getItem(start + idx) const listItem = this.getItem(start + idx)
return listItem.viewId return listItem.toModel()
}) })
} }
} }