feat:List add scrollToItem method
This commit is contained in:
parent
2541a13d74
commit
5f4942a8ff
@ -84,16 +84,22 @@ class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolder> {
|
||||
return super.getItemViewType(position);
|
||||
}
|
||||
|
||||
private JSValue getItemModel(final int position) {
|
||||
private JSValue getItemModel(int position) {
|
||||
if (position >= this.listNode.itemCount) {
|
||||
return this.listNode.getSubModel(this.listNode.loadMoreViewId);
|
||||
}
|
||||
String id = listNode.itemValues.get(position);
|
||||
if (TextUtils.isEmpty(id)) {
|
||||
int batchCount = listNode.batchCount;
|
||||
int start = position;
|
||||
while (start > 0 && TextUtils.isEmpty(listNode.itemValues.get(start - 1))) {
|
||||
start--;
|
||||
batchCount++;
|
||||
}
|
||||
AsyncResult<JSDecoder> asyncResult = listNode.callJSResponse(
|
||||
"renderBunchedItems",
|
||||
position,
|
||||
listNode.batchCount);
|
||||
start,
|
||||
batchCount);
|
||||
try {
|
||||
JSDecoder jsDecoder = asyncResult.synchronous().get();
|
||||
JSValue result = jsDecoder.decode();
|
||||
@ -102,7 +108,7 @@ class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolder> {
|
||||
for (int i = 0; i < jsArray.size(); i++) {
|
||||
JSObject itemModel = jsArray.get(i).asObject();
|
||||
String itemId = itemModel.getProperty("id").asString().value();
|
||||
listNode.itemValues.put(i + position, itemId);
|
||||
listNode.itemValues.put(i + start, itemId);
|
||||
listNode.setSubModel(itemId, itemModel);
|
||||
}
|
||||
return listNode.getSubModel(listNode.itemValues.get(position));
|
||||
|
@ -24,6 +24,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.github.pengfeizhou.jscore.JSNumber;
|
||||
import com.github.pengfeizhou.jscore.JSONBuilder;
|
||||
import com.github.pengfeizhou.jscore.JSObject;
|
||||
import com.github.pengfeizhou.jscore.JSValue;
|
||||
@ -36,6 +37,7 @@ import pub.doric.DoricContext;
|
||||
import pub.doric.DoricScrollChangeListener;
|
||||
import pub.doric.IDoricScrollable;
|
||||
import pub.doric.async.AsyncResult;
|
||||
import pub.doric.extension.bridge.DoricMethod;
|
||||
import pub.doric.extension.bridge.DoricPlugin;
|
||||
import pub.doric.shader.SuperNode;
|
||||
import pub.doric.shader.ViewNode;
|
||||
@ -142,7 +144,7 @@ public class ListNode extends SuperNode<RecyclerView> implements IDoricScrollabl
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void blend(RecyclerView view, String name, JSValue prop) {
|
||||
protected void blend(RecyclerView view, String name, final JSValue prop) {
|
||||
switch (name) {
|
||||
case "itemCount":
|
||||
if (!prop.isNumber()) {
|
||||
@ -188,6 +190,17 @@ public class ListNode extends SuperNode<RecyclerView> implements IDoricScrollabl
|
||||
}
|
||||
this.onScrollEndFuncId = prop.asString().value();
|
||||
break;
|
||||
case "scrolledPosition":
|
||||
if (!prop.isNumber()) {
|
||||
return;
|
||||
}
|
||||
view.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
moveToPosition(prop.asNumber().toInt(), false);
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
super.blend(view, name, prop);
|
||||
break;
|
||||
@ -227,4 +240,49 @@ public class ListNode extends SuperNode<RecyclerView> implements IDoricScrollabl
|
||||
public void removeScrollChangeListener(DoricScrollChangeListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@DoricMethod
|
||||
public void scrollToItem(JSObject params) {
|
||||
boolean animated = false;
|
||||
if (params.getProperty("animated").isBoolean()) {
|
||||
animated = params.getProperty("animated").asBoolean().value();
|
||||
}
|
||||
JSNumber pos = params.getProperty("pos").asNumber();
|
||||
moveToPosition(pos.toInt(), animated);
|
||||
}
|
||||
|
||||
private void moveToPosition(int pos, boolean smooth) {
|
||||
if (mView.getLayoutManager() == null) {
|
||||
return;
|
||||
}
|
||||
if (!(getView().getLayoutManager() instanceof LinearLayoutManager)) {
|
||||
defaultScrollTo(pos, smooth);
|
||||
return;
|
||||
}
|
||||
LinearLayoutManager layoutManager = (LinearLayoutManager) mView.getLayoutManager();
|
||||
int firstItem = layoutManager.findFirstVisibleItemPosition();
|
||||
int lastItem = layoutManager.findLastVisibleItemPosition();
|
||||
if (pos <= firstItem) {
|
||||
defaultScrollTo(pos, smooth);
|
||||
} else if (pos <= lastItem) {
|
||||
// int top = getInnerView().getChildAt(pos - firstItem).getTop();
|
||||
// if (smooth) {
|
||||
// getInnerView().smoothScrollBy(0, top);
|
||||
// } else {
|
||||
// getInnerView().scrollBy(0, top);
|
||||
// }
|
||||
} else {
|
||||
defaultScrollTo(pos, smooth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void defaultScrollTo(int pos, boolean b) {
|
||||
if (b) {
|
||||
mView.smoothScrollToPosition(pos);
|
||||
} else {
|
||||
mView.scrollToPosition(pos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -107,6 +107,10 @@ - (void)blendView:(UITableView *)view forPropName:(NSString *)name propValue:(id
|
||||
self.onScrollFuncId = prop;
|
||||
} else if ([@"onScrollEnd" isEqualToString:name]) {
|
||||
self.onScrollEndFuncId = prop;
|
||||
} else if ([@"scrolledPosition" isEqualToString:name]) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[view scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[prop unsignedIntegerValue] inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
|
||||
});
|
||||
} else {
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
@ -301,4 +305,10 @@ - (void)removeDidScrollBlock:(__nonnull DoricDidScrollBlock)didScrollListener {
|
||||
[self.didScrollBlocks removeObject:didScrollListener];
|
||||
}
|
||||
|
||||
- (void)scrollToItem:(NSDictionary *)params {
|
||||
BOOL animated = [params[@"animated"] boolValue];
|
||||
NSUInteger scrolledPosition = [params[@"pos"] unsignedIntegerValue];
|
||||
[self.view scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:scrolledPosition inSection:0] atScrollPosition:UITableViewScrollPositionNone animated:animated];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -1889,6 +1889,9 @@ var List = /** @class */ (function (_super) {
|
||||
return this.cachedViews.values();
|
||||
}
|
||||
};
|
||||
List.prototype.scrollToItem = function (context, pos, animated) {
|
||||
return this.nativeChannel(context, 'scrollToItem')({ pos: pos, animated: animated });
|
||||
};
|
||||
List.prototype.reset = function () {
|
||||
this.cachedViews.clear();
|
||||
this.itemCount = 0;
|
||||
@ -1953,6 +1956,10 @@ var List = /** @class */ (function (_super) {
|
||||
Property,
|
||||
__metadata$5("design:type", Function)
|
||||
], List.prototype, "onScrollEnd", void 0);
|
||||
__decorate$5([
|
||||
Property,
|
||||
__metadata$5("design:type", Number)
|
||||
], List.prototype, "scrolledPosition", void 0);
|
||||
return List;
|
||||
}(Superview));
|
||||
function list(config) {
|
||||
|
@ -1395,6 +1395,9 @@ class List extends Superview {
|
||||
return this.cachedViews.values();
|
||||
}
|
||||
}
|
||||
scrollToItem(context, pos, animated) {
|
||||
return this.nativeChannel(context, 'scrollToItem')({ pos, animated });
|
||||
}
|
||||
reset() {
|
||||
this.cachedViews.clear();
|
||||
this.itemCount = 0;
|
||||
@ -1459,6 +1462,10 @@ __decorate$5([
|
||||
Property,
|
||||
__metadata$5("design:type", Function)
|
||||
], List.prototype, "onScrollEnd", void 0);
|
||||
__decorate$5([
|
||||
Property,
|
||||
__metadata$5("design:type", Number)
|
||||
], List.prototype, "scrolledPosition", void 0);
|
||||
function list(config) {
|
||||
const ret = new List;
|
||||
for (let key in config) {
|
||||
|
@ -2854,6 +2854,9 @@ class List extends Superview {
|
||||
return this.cachedViews.values();
|
||||
}
|
||||
}
|
||||
scrollToItem(context, pos, animated) {
|
||||
return this.nativeChannel(context, 'scrollToItem')({ pos, animated });
|
||||
}
|
||||
reset() {
|
||||
this.cachedViews.clear();
|
||||
this.itemCount = 0;
|
||||
@ -2918,6 +2921,10 @@ __decorate$5([
|
||||
Property,
|
||||
__metadata$5("design:type", Function)
|
||||
], List.prototype, "onScrollEnd", void 0);
|
||||
__decorate$5([
|
||||
Property,
|
||||
__metadata$5("design:type", Number)
|
||||
], List.prototype, "scrolledPosition", void 0);
|
||||
function list(config) {
|
||||
const ret = new List;
|
||||
for (let key in config) {
|
||||
|
3
doric-js/index.d.ts
vendored
3
doric-js/index.d.ts
vendored
@ -499,6 +499,7 @@ declare module 'doric/lib/src/widget/image' {
|
||||
declare module 'doric/lib/src/widget/list' {
|
||||
import { View, Superview, NativeViewModel } from "doric/lib/src/ui/view";
|
||||
import { Stack } from "doric/lib/src/widget/layouts";
|
||||
import { BridgeContext } from "doric/lib/src/runtime/global";
|
||||
export class ListItem extends Stack {
|
||||
/**
|
||||
* Set to reuse native view
|
||||
@ -521,6 +522,8 @@ declare module 'doric/lib/src/widget/list' {
|
||||
x: number;
|
||||
y: number;
|
||||
}) => void;
|
||||
scrolledPosition?: number;
|
||||
scrollToItem(context: BridgeContext, pos: number, animated?: boolean): Promise<any>;
|
||||
reset(): void;
|
||||
isDirty(): boolean;
|
||||
toModel(): NativeViewModel;
|
||||
|
3
doric-js/lib/src/widget/list.d.ts
vendored
3
doric-js/lib/src/widget/list.d.ts
vendored
@ -1,5 +1,6 @@
|
||||
import { View, Superview, NativeViewModel } from "../ui/view";
|
||||
import { Stack } from "./layouts";
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
export declare class ListItem extends Stack {
|
||||
/**
|
||||
* Set to reuse native view
|
||||
@ -24,6 +25,8 @@ export declare class List extends Superview {
|
||||
x: number;
|
||||
y: number;
|
||||
}) => void;
|
||||
scrolledPosition?: number;
|
||||
scrollToItem(context: BridgeContext, pos: number, animated?: boolean): Promise<any>;
|
||||
reset(): void;
|
||||
private getItem;
|
||||
isDirty(): boolean;
|
||||
|
@ -47,6 +47,9 @@ export class List extends Superview {
|
||||
return this.cachedViews.values();
|
||||
}
|
||||
}
|
||||
scrollToItem(context, pos, animated) {
|
||||
return this.nativeChannel(context, 'scrollToItem')({ pos, animated });
|
||||
}
|
||||
reset() {
|
||||
this.cachedViews.clear();
|
||||
this.itemCount = 0;
|
||||
@ -111,6 +114,10 @@ __decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], List.prototype, "onScrollEnd", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], List.prototype, "scrolledPosition", void 0);
|
||||
export function list(config) {
|
||||
const ret = new List;
|
||||
for (let key in config) {
|
||||
|
@ -17,6 +17,7 @@
|
||||
import { View, Property, Superview, NativeViewModel } from "../ui/view";
|
||||
import { Stack } from "./layouts";
|
||||
import { layoutConfig } from "../util/layoutconfig";
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
|
||||
|
||||
export class ListItem extends Stack {
|
||||
@ -63,6 +64,13 @@ export class List extends Superview {
|
||||
@Property
|
||||
onScrollEnd?: (offset: { x: number, y: number }) => void
|
||||
|
||||
@Property
|
||||
scrolledPosition?: number
|
||||
|
||||
scrollToItem(context: BridgeContext, pos: number, animated?: boolean) {
|
||||
return this.nativeChannel(context, 'scrollToItem')({ pos, animated }) as Promise<any>
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.cachedViews.clear()
|
||||
this.itemCount = 0
|
||||
|
7
doric-web/dist/index.js
vendored
7
doric-web/dist/index.js
vendored
@ -2912,6 +2912,9 @@ class List extends Superview {
|
||||
return this.cachedViews.values();
|
||||
}
|
||||
}
|
||||
scrollToItem(context, pos, animated) {
|
||||
return this.nativeChannel(context, 'scrollToItem')({ pos, animated });
|
||||
}
|
||||
reset() {
|
||||
this.cachedViews.clear();
|
||||
this.itemCount = 0;
|
||||
@ -2976,6 +2979,10 @@ __decorate$5([
|
||||
Property,
|
||||
__metadata$5("design:type", Function)
|
||||
], List.prototype, "onScrollEnd", void 0);
|
||||
__decorate$5([
|
||||
Property,
|
||||
__metadata$5("design:type", Number)
|
||||
], List.prototype, "scrolledPosition", void 0);
|
||||
function list(config) {
|
||||
const ret = new List;
|
||||
for (let key in config) {
|
||||
|
2
doric-web/dist/index.js.map
vendored
2
doric-web/dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user