flowlayout add header and footer:js and android implement

This commit is contained in:
pengfei.zhou
2021-10-11 11:14:55 +08:00
committed by osborn
parent 5224be8f90
commit 5ad4f4b981
12 changed files with 208 additions and 32 deletions

View File

@@ -39,7 +39,9 @@ import pub.doric.shader.ViewNode;
* @CreateDate: 2019-11-12
*/
class FlowAdapter extends RecyclerView.Adapter<FlowAdapter.DoricViewHolder> {
private static final int TYPE_LOAD_MORE = -1;
private static final int TYPE_HEADER = -2;
private static final int TYPE_FOOTER = -3;
private final FlowLayoutNode flowLayoutNode;
String renderItemFuncId;
int itemCount = 0;
@@ -67,7 +69,17 @@ class FlowAdapter extends RecyclerView.Adapter<FlowAdapter.DoricViewHolder> {
holder.flowLayoutItemNode.setId(jsObject.getProperty("id").asString().value());
holder.flowLayoutItemNode.blend(jsObject.getProperty("props").asObject());
}
if (position >= this.itemCount && !TextUtils.isEmpty(this.flowLayoutNode.onLoadMoreFuncId)) {
if ((this.flowLayoutNode.hasHeader() && position == 0)
|| (this.flowLayoutNode.hasFooter() && position == this.getItemCount() - 1)) {
StaggeredGridLayoutManager.LayoutParams layoutParams = new StaggeredGridLayoutManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
holder.itemView.getLayoutParams().height
);
layoutParams.setFullSpan(true);
holder.itemView.setLayoutParams(layoutParams);
} else if (this.flowLayoutNode.loadMore
&& position == this.itemCount + (this.flowLayoutNode.hasHeader() ? 1 : 0)
&& !TextUtils.isEmpty(this.flowLayoutNode.onLoadMoreFuncId)) {
callLoadMore();
StaggeredGridLayoutManager.LayoutParams layoutParams = new StaggeredGridLayoutManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
@@ -80,16 +92,27 @@ class FlowAdapter extends RecyclerView.Adapter<FlowAdapter.DoricViewHolder> {
@Override
public int getItemCount() {
return this.itemCount + (this.flowLayoutNode.loadMore ? 1 : 0);
return this.itemCount
+ (this.flowLayoutNode.loadMore ? 1 : 0)
+ (this.flowLayoutNode.hasHeader() ? 1 : 0)
+ (this.flowLayoutNode.hasFooter() ? 1 : 0);
}
@Override
public int getItemViewType(int position) {
if (position >= itemCount) {
return Integer.MAX_VALUE;
if (this.flowLayoutNode.hasHeader() && position == 0) {
return TYPE_HEADER;
}
if (this.flowLayoutNode.hasFooter() && position == this.getItemCount() - 1) {
return TYPE_FOOTER;
}
if (position >= this.itemCount + (this.flowLayoutNode.hasHeader() ? 1 : 0)) {
return TYPE_LOAD_MORE;
}
JSValue value = getItemModel(position);
if (value.isObject()) {
if (value != null && value.isObject()) {
if (value.asObject().getProperty("identifier").isString()) {
return value.asObject().getProperty("identifier").asString().value().hashCode();
}
@@ -97,10 +120,21 @@ class FlowAdapter extends RecyclerView.Adapter<FlowAdapter.DoricViewHolder> {
return super.getItemViewType(position);
}
private JSValue getItemModel(final int position) {
if (position >= this.itemCount) {
private JSValue getItemModel(int position) {
if (this.flowLayoutNode.hasHeader() && position == 0) {
return this.flowLayoutNode.getSubModel(this.flowLayoutNode.headerViewId);
}
if (this.flowLayoutNode.hasFooter() && position == this.getItemCount() - 1) {
return this.flowLayoutNode.getSubModel(this.flowLayoutNode.footerViewId);
}
if (position >= this.itemCount + (this.flowLayoutNode.hasHeader() ? 1 : 0)) {
return this.flowLayoutNode.getSubModel(this.flowLayoutNode.loadMoreViewId);
}
if (this.flowLayoutNode.hasHeader()) {
position--;
}
String id = itemValues.get(position);
if (TextUtils.isEmpty(id)) {
AsyncResult<JSDecoder> asyncResult = flowLayoutNode.pureCallJSResponse(

View File

@@ -99,6 +99,9 @@ public class FlowLayoutNode extends SuperNode<RecyclerView> implements IDoricScr
private int itemCount = 0;
private boolean scrollable = true;
String headerViewId;
String footerViewId;
public FlowLayoutNode(DoricContext doricContext) {
super(doricContext);
this.flowAdapter = new FlowAdapter(this);
@@ -206,6 +209,12 @@ public class FlowLayoutNode extends SuperNode<RecyclerView> implements IDoricScr
}
this.onScrollEndFuncId = prop.asString().value();
break;
case "header":
this.headerViewId = prop.asString().value();
break;
case "footer":
this.footerViewId = prop.asString().value();
break;
default:
super.blend(view, name, prop);
break;
@@ -316,4 +325,12 @@ public class FlowLayoutNode extends SuperNode<RecyclerView> implements IDoricScr
public void removeScrollChangeListener(DoricScrollChangeListener listener) {
listeners.remove(listener);
}
boolean hasHeader() {
return !TextUtils.isEmpty(this.headerViewId);
}
boolean hasFooter() {
return !TextUtils.isEmpty(this.footerViewId);
}
}