feat:refact render child in groupNode
This commit is contained in:
parent
74d31edc26
commit
d2f4302e42
@ -16,6 +16,7 @@
|
||||
package pub.doric.plugin;
|
||||
|
||||
import pub.doric.DoricContext;
|
||||
import pub.doric.async.AsyncResult;
|
||||
import pub.doric.extension.bridge.DoricMethod;
|
||||
import pub.doric.extension.bridge.DoricPlugin;
|
||||
import pub.doric.utils.DoricLog;
|
||||
@ -49,7 +50,23 @@ public class ShaderPlugin extends DoricJavaPlugin {
|
||||
rootNode.render(jsObject.getProperty("props").asObject());
|
||||
return null;
|
||||
}
|
||||
}, ThreadMode.UI);
|
||||
}, ThreadMode.UI).setCallback(new AsyncResult.Callback<Object>() {
|
||||
@Override
|
||||
public void onResult(Object result) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable t) {
|
||||
t.printStackTrace();
|
||||
DoricLog.e("Shader.render:error%s", t.getLocalizedMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
DoricLog.e("Shader.render:error%s", e.getLocalizedMessage());
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package pub.doric.shader;
|
||||
|
||||
import android.util.SparseArray;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import pub.doric.DoricContext;
|
||||
@ -25,9 +24,6 @@ import com.github.pengfeizhou.jscore.JSObject;
|
||||
import com.github.pengfeizhou.jscore.JSValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: com.github.penfeizhou.doric.widget
|
||||
@ -35,8 +31,8 @@ import java.util.Map;
|
||||
* @CreateDate: 2019-07-20
|
||||
*/
|
||||
public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
|
||||
private Map<String, ViewNode> mChildrenNode = new HashMap<>();
|
||||
private SparseArray<ViewNode> mIndexInfo = new SparseArray<>();
|
||||
private ArrayList<ViewNode> mChildNodes = new ArrayList<>();
|
||||
private ArrayList<String> mChildViewIds = new ArrayList<>();
|
||||
|
||||
public GroupNode(DoricContext doricContext) {
|
||||
super(doricContext);
|
||||
@ -45,80 +41,90 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
|
||||
@Override
|
||||
protected void blend(F view, ViewGroup.LayoutParams layoutParams, String name, JSValue prop) {
|
||||
if ("children".equals(name)) {
|
||||
JSArray jsArray = prop.asArray();
|
||||
int i;
|
||||
List<ViewNode> tobeRemoved = new ArrayList<>();
|
||||
for (i = 0; i < jsArray.size(); i++) {
|
||||
JSValue jsValue = jsArray.get(i);
|
||||
if (!jsValue.isObject()) {
|
||||
continue;
|
||||
JSArray ids = prop.asArray();
|
||||
mChildViewIds.clear();
|
||||
for (int i = 0; i < ids.size(); i++) {
|
||||
mChildViewIds.add(ids.get(i).asString().value());
|
||||
}
|
||||
JSObject childObj = jsValue.asObject();
|
||||
String type = childObj.getProperty("type").asString().value();
|
||||
String id = childObj.getProperty("id").asString().value();
|
||||
ViewNode child = mChildrenNode.get(id);
|
||||
if (child == null) {
|
||||
child = ViewNode.create(getDoricContext(), type);
|
||||
child.index = i;
|
||||
child.mSuperNode = this;
|
||||
child.mId = id;
|
||||
mChildrenNode.put(id, child);
|
||||
} else {
|
||||
if (i != child.index) {
|
||||
mIndexInfo.remove(i);
|
||||
child.index = i;
|
||||
mView.removeView(child.getDoricLayer());
|
||||
}
|
||||
tobeRemoved.remove(child);
|
||||
}
|
||||
|
||||
ViewNode node = mIndexInfo.get(i);
|
||||
|
||||
if (node != null && node != child) {
|
||||
mView.removeViewAt(i);
|
||||
mIndexInfo.remove(i);
|
||||
tobeRemoved.add(node);
|
||||
}
|
||||
|
||||
ViewGroup.LayoutParams params = child.getLayoutParams();
|
||||
if (params == null) {
|
||||
params = generateDefaultLayoutParams();
|
||||
}
|
||||
child.blend(childObj.getProperty("props").asObject(), params);
|
||||
if (mIndexInfo.get(i) == null) {
|
||||
mView.addView(child.getDoricLayer(), i, child.getLayoutParams());
|
||||
mIndexInfo.put(i, child);
|
||||
}
|
||||
}
|
||||
int count = mView.getChildCount();
|
||||
while (i < count) {
|
||||
ViewNode node = mIndexInfo.get(i);
|
||||
if (node != null) {
|
||||
mChildrenNode.remove(node.getId());
|
||||
mIndexInfo.remove(i);
|
||||
tobeRemoved.remove(node);
|
||||
mView.removeView(node.getDoricLayer());
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
for (ViewNode node : tobeRemoved) {
|
||||
mChildrenNode.remove(node.getId());
|
||||
}
|
||||
} else if ("subviews".equals(name)) {
|
||||
// Currently do nothing,because its subview always contained in props.children
|
||||
// super.blend(view, layoutParams, name, prop);
|
||||
} else {
|
||||
super.blend(view, layoutParams, name, prop);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void blend(JSObject jsObject, ViewGroup.LayoutParams layoutParams) {
|
||||
super.blend(jsObject, layoutParams);
|
||||
configChildNode();
|
||||
}
|
||||
|
||||
private void configChildNode() {
|
||||
for (int idx = 0; idx < mChildViewIds.size(); idx++) {
|
||||
String id = mChildViewIds.get(idx);
|
||||
JSObject model = getSubModel(id);
|
||||
String type = model.getProperty("type").asString().value();
|
||||
if (idx < mChildNodes.size()) {
|
||||
ViewNode oldNode = mChildNodes.get(idx);
|
||||
if (id.equals(oldNode.getId())) {
|
||||
//The same,skip
|
||||
} else {
|
||||
//Find in remaining nodes
|
||||
int position = -1;
|
||||
for (int start = idx + 1; start < mChildNodes.size(); start++) {
|
||||
ViewNode node = mChildNodes.get(start);
|
||||
if (id.equals(node.getId())) {
|
||||
//Found
|
||||
position = start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (position >= 0) {
|
||||
//Found swap idx,position
|
||||
ViewNode reused = mChildNodes.remove(position);
|
||||
ViewNode abandoned = mChildNodes.remove(idx);
|
||||
mChildNodes.set(idx, reused);
|
||||
mChildNodes.set(position, abandoned);
|
||||
//View swap index
|
||||
mView.removeView(reused.getDoricLayer());
|
||||
mView.addView(reused.getDoricLayer(), idx);
|
||||
mView.removeView(abandoned.getDoricLayer());
|
||||
mView.addView(abandoned.getDoricLayer(), position);
|
||||
} else {
|
||||
//Not found,insert
|
||||
ViewNode newNode = ViewNode.create(getDoricContext(), type);
|
||||
newNode.setSuperNode(this);
|
||||
newNode.setId(id);
|
||||
ViewGroup.LayoutParams params = generateDefaultLayoutParams();
|
||||
newNode.blend(model.getProperty("props").asObject(), params);
|
||||
|
||||
mChildNodes.set(idx, newNode);
|
||||
mView.addView(newNode.getDoricLayer(), idx, newNode.getLayoutParams());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Insert
|
||||
ViewNode newNode = ViewNode.create(getDoricContext(), type);
|
||||
newNode.setSuperNode(this);
|
||||
newNode.setId(id);
|
||||
ViewGroup.LayoutParams params = generateDefaultLayoutParams();
|
||||
newNode.blend(model.getProperty("props").asObject(), params);
|
||||
mChildNodes.add(newNode);
|
||||
mView.addView(newNode.getDoricLayer(), idx, newNode.getLayoutParams());
|
||||
}
|
||||
}
|
||||
int size = mChildNodes.size();
|
||||
for (int idx = mChildViewIds.size(); idx < size; idx++) {
|
||||
ViewNode viewNode = mChildNodes.remove(mChildViewIds.size());
|
||||
mView.removeView(viewNode.getDoricLayer());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void blendSubNode(JSObject subProp) {
|
||||
String subNodeId = subProp.getProperty("id").asString().value();
|
||||
for (ViewNode node : mChildrenNode.values()) {
|
||||
for (ViewNode node : mChildNodes) {
|
||||
if (subNodeId.equals(node.getId())) {
|
||||
node.blend(subProp, node.getLayoutParams());
|
||||
node.blend(subProp.getProperty("props").asObject(), node.getLayoutParams());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,9 @@ import com.github.pengfeizhou.jscore.JSArray;
|
||||
import com.github.pengfeizhou.jscore.JSObject;
|
||||
import com.github.pengfeizhou.jscore.JSValue;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import pub.doric.DoricContext;
|
||||
import pub.doric.utils.DoricUtils;
|
||||
|
||||
@ -31,6 +34,8 @@ import pub.doric.utils.DoricUtils;
|
||||
* @CreateDate: 2019-11-13
|
||||
*/
|
||||
public abstract class SuperNode<V extends View> extends ViewNode<V> {
|
||||
private Map<String, JSObject> subNodes = new HashMap<>();
|
||||
|
||||
public SuperNode(DoricContext doricContext) {
|
||||
super(doricContext);
|
||||
}
|
||||
@ -42,16 +47,33 @@ public abstract class SuperNode<V extends View> extends ViewNode<V> {
|
||||
@Override
|
||||
protected void blend(V view, ViewGroup.LayoutParams layoutParams, String name, JSValue prop) {
|
||||
if (name.equals("subviews")) {
|
||||
if (prop.isArray()) {
|
||||
JSArray subviews = prop.asArray();
|
||||
for (int i = 0; i < subviews.size(); i++) {
|
||||
JSObject subProp = subviews.get(i).asObject();
|
||||
blendSubNode(subProp);
|
||||
JSObject subNode = subviews.get(i).asObject();
|
||||
mixinSubNode(subNode);
|
||||
blendSubNode(subNode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
super.blend(view, layoutParams, name, prop);
|
||||
}
|
||||
}
|
||||
|
||||
private void mixinSubNode(JSObject subNode) {
|
||||
String id = subNode.getProperty("id").asString().value();
|
||||
JSObject targetNode = subNodes.get(id);
|
||||
if (targetNode == null) {
|
||||
subNodes.put(id, subNode);
|
||||
} else {
|
||||
mixin(subNode, targetNode);
|
||||
}
|
||||
}
|
||||
|
||||
public JSObject getSubModel(String id) {
|
||||
return subNodes.get(id);
|
||||
}
|
||||
|
||||
protected abstract void blendSubNode(JSObject subProperties);
|
||||
|
||||
protected void blendSubLayoutConfig(ViewNode viewNode, JSObject jsObject) {
|
||||
@ -70,7 +92,6 @@ public abstract class SuperNode<V extends View> extends ViewNode<V> {
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
if (heightSpec.isNumber()) {
|
||||
@ -104,4 +125,37 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,9 +27,6 @@ import com.github.pengfeizhou.jscore.JSDecoder;
|
||||
import com.github.pengfeizhou.jscore.JSObject;
|
||||
import com.github.pengfeizhou.jscore.JSValue;
|
||||
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import pub.doric.async.AsyncResult;
|
||||
import pub.doric.shader.ViewNode;
|
||||
|
||||
@ -111,53 +108,8 @@ public class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolde
|
||||
|
||||
|
||||
void blendSubNode(JSObject subProperties) {
|
||||
String subNodeId = subProperties.getProperty("id").asString().value();
|
||||
for (int i = 0; i < itemValues.size(); i++) {
|
||||
JSValue jsValue = itemValues.valueAt(i);
|
||||
if (jsValue.isObject()) {
|
||||
JSObject jsObject = jsValue.asObject();
|
||||
if (subNodeId.equals(jsObject.getProperty("id").asString().value())) {
|
||||
mixin(subProperties, jsObject);
|
||||
int position = itemValues.keyAt(i);
|
||||
notifyItemChanged(position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class DoricViewHolder extends RecyclerView.ViewHolder {
|
||||
ListItemNode listItemNode;
|
||||
|
@ -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.toModel()
|
||||
return listItem.viewId
|
||||
})
|
||||
}
|
||||
}
|
@ -303,7 +303,7 @@ export abstract class Group extends Superview {
|
||||
set: (target, index, value) => {
|
||||
const ret = Reflect.set(target, index, value)
|
||||
// Let getDirty return true
|
||||
this.dirtyProps.children = []
|
||||
this.dirtyProps.children = this.children.map(e => e.viewId)
|
||||
return ret
|
||||
}
|
||||
})
|
||||
@ -315,17 +315,5 @@ export abstract class Group extends Superview {
|
||||
addChild(view: View) {
|
||||
this.children.push(view)
|
||||
}
|
||||
|
||||
toModel() {
|
||||
this.dirtyProps.children = this.children.map(e => {
|
||||
if (e.isDirty()) {
|
||||
return e.toModel()
|
||||
} else {
|
||||
//Dont need return model
|
||||
return undefined
|
||||
}
|
||||
})
|
||||
return this.nativeViewModel
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user