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);
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.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.blend(model.getProperty("props").asObject());
mChildNodes.set(idx, newNode);
mChildNodes.add(idx, newNode);
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);
}
public void setSubModel(String id, JSObject model) {
subNodes.put(id, model);
}
protected abstract void blendSubNode(JSObject subProperties);
protected void blendSubLayoutConfig(ViewNode viewNode, JSObject jsObject) {
@ -127,34 +131,14 @@ public abstract class SuperNode<V extends View> extends ViewNode<V> {
}
private void mixin(JSObject src, JSObject target) {
JSValue srcProps = src.getProperty("props");
JSValue targetProps = target.getProperty("props");
if (srcProps.isObject()) {
if (targetProps.isObject()) {
for (String key : srcProps.asObject().propertySet()) {
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;
}
targetProps.asObject().setProperty(key, jsValue);
}
} else {
target.setProperty("props", srcProps);
JSObject srcProps = src.getProperty("props").asObject();
JSObject targetProps = target.getProperty("props").asObject();
for (String key : srcProps.propertySet()) {
JSValue jsValue = srcProps.getProperty(key);
if ("subviews".equals(key) && jsValue.isArray()) {
continue;
}
targetProps.asObject().setProperty(key, jsValue);
}
}

View File

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

View File

@ -15,6 +15,7 @@
*/
package pub.doric.shader.list;
import android.text.TextUtils;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
@ -24,6 +25,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.github.pengfeizhou.jscore.JSArray;
import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JSNull;
import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue;
@ -37,12 +39,11 @@ import pub.doric.shader.ViewNode;
*/
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolder> {
final ListNode listNode;
private final ListNode listNode;
String renderItemFuncId;
final String renderBunchedItemsFuncId = "renderBunchedItems";
int itemCount = 0;
int batchCount = 15;
SparseArray<JSValue> itemValues = new SparseArray<>();
SparseArray<String> itemValues = new SparseArray<>();
public ListAdapter(ListNode listNode) {
this.listNode = listNode;
@ -82,11 +83,11 @@ public class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolde
return super.getItemViewType(position);
}
private JSValue getItemModel(int position) {
JSValue itemModel = itemValues.get(position);
if (itemModel == null || !itemModel.isObject()) {
private JSValue getItemModel(final int position) {
String id = itemValues.get(position);
if (TextUtils.isEmpty(id)) {
AsyncResult<JSDecoder> asyncResult = listNode.callJSResponse(
renderBunchedItemsFuncId,
"renderBunchedItems",
position,
batchCount);
try {
@ -95,20 +96,34 @@ public class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolde
if (result.isArray()) {
JSArray jsArray = result.asArray();
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) {
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) {
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 {

View File

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

View File

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