Add find visible items for list and flowlayout

This commit is contained in:
pengfei.zhou 2021-10-12 16:33:04 +08:00 committed by osborn
parent 1f511823c5
commit 6cae752456
19 changed files with 172 additions and 138 deletions

View File

@ -32,7 +32,9 @@ import com.github.pengfeizhou.jscore.JSValue;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
@ -328,28 +330,56 @@ public class FlowLayoutNode extends SuperNode<RecyclerView> implements IDoricScr
@DoricMethod
public JSONArray findVisibleItems() {
int[] startPos = staggeredGridLayoutManager.findFirstVisibleItemPositions(null);
int[] endPos = staggeredGridLayoutManager.findLastVisibleItemPositions(null);
int[] firstPositions = staggeredGridLayoutManager.findFirstVisibleItemPositions(null);
int[] lastPositions = staggeredGridLayoutManager.findLastVisibleItemPositions(null);
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < staggeredGridLayoutManager.getSpanCount(); i++) {
jsonArray.put(new JSONBuilder()
.put("first", calibratePosition(startPos[i]))
.put("last", calibratePosition(endPos[i]))
.toJSONObject());
int first = firstPositions[0];
for (int firstPosition : firstPositions) {
first = Math.min(first, firstPosition);
}
int last = lastPositions[0];
for (int lastPosition : lastPositions) {
last = Math.max(last, lastPosition);
}
for (int i = first; i <= last; i++) {
jsonArray.put(i);
}
return jsonArray;
}
@DoricMethod
public JSONArray findCompletelyVisibleItems() {
int[] startPos = staggeredGridLayoutManager.findFirstCompletelyVisibleItemPositions(null);
int[] endPos = staggeredGridLayoutManager.findLastCompletelyVisibleItemPositions(null);
JSONArray jsonArray = new JSONArray();
int[] firstPositions = staggeredGridLayoutManager.findFirstVisibleItemPositions(null);
int[] lastPositions = staggeredGridLayoutManager.findLastVisibleItemPositions(null);
Set<Integer> positions = new HashSet<>();
int first = firstPositions[0];
for (int firstPosition : firstPositions) {
first = Math.min(first, firstPosition);
}
int last = lastPositions[0];
for (int lastPosition : lastPositions) {
last = Math.max(last, lastPosition);
}
for (int i = first; i <= last; i++) {
positions.add(i);
}
int[] firstCompletelyVisibleItemPositions = staggeredGridLayoutManager.findFirstCompletelyVisibleItemPositions(null);
int[] lastCompletelyVisibleItemPositions = staggeredGridLayoutManager.findLastCompletelyVisibleItemPositions(null);
for (int i = 0; i < staggeredGridLayoutManager.getSpanCount(); i++) {
jsonArray.put(new JSONBuilder()
.put("first", calibratePosition(startPos[i]))
.put("last", calibratePosition(endPos[i]))
.toJSONObject());
int firstPosition = firstPositions[i];
int firstCompletelyVisibleItemPosition = firstCompletelyVisibleItemPositions[i];
if (firstCompletelyVisibleItemPosition != firstPosition) {
positions.remove(firstPosition);
}
int lastPosition = lastPositions[i];
int lastCompletelyVisibleItemPosition = lastCompletelyVisibleItemPositions[i];
if (lastCompletelyVisibleItemPosition != lastPosition) {
positions.remove(lastPosition);
}
}
JSONArray jsonArray = new JSONArray();
for (int position : positions) {
jsonArray.put(position);
}
return jsonArray;
}

View File

@ -33,6 +33,7 @@ import com.github.pengfeizhou.jscore.JSONBuilder;
import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.HashSet;
@ -300,25 +301,29 @@ public class ListNode extends SuperNode<RecyclerView> implements IDoricScrollabl
}
@DoricMethod
public JSONObject findVisibleItems() {
public JSONArray findVisibleItems() {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) this.mView.getLayoutManager();
assert linearLayoutManager != null;
int startPos = linearLayoutManager.findFirstVisibleItemPosition();
int endPos = linearLayoutManager.findLastVisibleItemPosition();
return new JSONBuilder()
.put("first", calibratePosition(startPos))
.put("last", calibratePosition(endPos)).toJSONObject();
JSONArray jsonArray = new JSONArray();
for (int i = startPos; i <= endPos; i++) {
jsonArray.put(i);
}
return jsonArray;
}
@DoricMethod
public JSONObject findCompletelyVisibleItems() {
public JSONArray findCompletelyVisibleItems() {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) this.mView.getLayoutManager();
assert linearLayoutManager != null;
int startPos = linearLayoutManager.findFirstCompletelyVisibleItemPosition();
int endPos = linearLayoutManager.findLastCompletelyVisibleItemPosition();
return new JSONBuilder()
.put("first", calibratePosition(startPos))
.put("last", calibratePosition(endPos)).toJSONObject();
JSONArray jsonArray = new JSONArray();
for (int i = startPos; i <= endPos; i++) {
jsonArray.put(i);
}
return jsonArray;
}
private void moveToPosition(int pos, boolean smooth) {

View File

@ -41,6 +41,7 @@ class FlowDemo extends Panel {
}).also(it => {
if (idx == 15) {
it.fullSpan = true
it.identifier = "fullSpan"
}
})
},
@ -62,7 +63,14 @@ class FlowDemo extends Panel {
height: 50,
fullSpan: true,
layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST),
})
}),
onScrollEnd: async () => {
const ret = await flowView.findCompletelyVisibleItems(context)
loge('completelyVisible Items is:', ret)
const ret2 = await flowView.findVisibleItems(context)
loge('visible Items is:', ret2)
}
}).in(rootView)
}

View File

@ -111,6 +111,12 @@ class ListVM extends ViewModel<ListModel, ListVH> {
state.data = state.data.concat(ret.data)
state.offset = state.data.length
})
},
onScrollEnd: async () => {
const ret = await vh.list.findCompletelyVisibleItems(context)
loge('completelyVisible Items is:', ret)
const ret2 = await vh.list.findVisibleItems(context)
loge('visible Items is:', ret2)
}
})
loadData(state.offset).then(ret => {

View File

@ -31,4 +31,11 @@ - (void)initWithSuperNode:(DoricSuperNode *)superNode {
[super initWithSuperNode:superNode];
self.reusable = YES;
}
- (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop {
if ([@"identifier" isEqualToString:name] || [@"fullSpan" isEqualToString:name]) {
} else {
[super blendView:view forPropName:name propValue:prop];
}
}
@end

View File

@ -483,4 +483,37 @@ - (void)addDidScrollBlock:(__nonnull DoricDidScrollBlock)didScrollListener {
- (void)removeDidScrollBlock:(__nonnull DoricDidScrollBlock)didScrollListener {
[self.didScrollBlocks removeObject:didScrollListener];
}
- (NSArray *)findVisibleItems {
return [[self.view.indexPathsForVisibleItems map:^id(NSIndexPath *obj) {
return @(obj.row);
}] sortedArrayUsingComparator:^NSComparisonResult(NSNumber *obj1, NSNumber *obj2) {
if (obj1.unsignedIntegerValue > obj2.unsignedIntegerValue) {
return NSOrderedDescending;
} else if (obj1.unsignedIntegerValue < obj2.unsignedIntegerValue) {
return NSOrderedAscending;
} else {
return NSOrderedSame;
}
}];
}
- (NSArray *)findCompletelyVisibleItems {
NSArray<__kindof UICollectionViewCell *> *items = [self.view.visibleCells filter:^BOOL(__kindof UICollectionViewCell *obj) {
return CGRectContainsRect(self.view.bounds, obj.frame);
}];
return [[items map:^id(__kindof UICollectionViewCell *obj) {
return @([self.view indexPathForCell:obj].row);
}] sortedArrayUsingComparator:^NSComparisonResult(NSNumber *obj1, NSNumber *obj2) {
if (obj1.unsignedIntegerValue > obj2.unsignedIntegerValue) {
return NSOrderedDescending;
} else if (obj1.unsignedIntegerValue < obj2.unsignedIntegerValue) {
return NSOrderedAscending;
} else {
return NSOrderedSame;
}
}];
}
@end

View File

@ -448,4 +448,18 @@ - (void)scrollToItem:(NSDictionary *)params {
}
}
- (NSArray *)findVisibleItems {
return [self.view.indexPathsForVisibleRows map:^id(NSIndexPath *obj) {
return @(obj.row);
}];
}
- (NSArray *)findCompletelyVisibleItems {
NSArray<__kindof UITableViewCell *> *items = [self.view.visibleCells filter:^BOOL(__kindof UITableViewCell *obj) {
return CGRectContainsRect(self.view.bounds, obj.frame);
}];
return [items map:^id(__kindof UITableViewCell *obj) {
return @([self.view indexPathForCell:obj].row);
}];
}
@end

View File

@ -2316,12 +2316,6 @@ var ListItem = /** @class */ (function (_super) {
], ListItem.prototype, "actions", void 0);
return ListItem;
}(Stack));
exports.OtherItems = void 0;
(function (OtherItems) {
OtherItems[OtherItems["LoadMore"] = -10] = "LoadMore";
OtherItems[OtherItems["Header"] = -11] = "Header";
OtherItems[OtherItems["Footer"] = -12] = "Footer";
})(exports.OtherItems || (exports.OtherItems = {}));
var List = /** @class */ (function (_super) {
__extends$c(List, _super);
function List() {
@ -2344,14 +2338,14 @@ var List = /** @class */ (function (_super) {
};
/**
* @param context
* @returns Returns the range of the visible views.
* @returns Returns array of visible view's index.
*/
List.prototype.findVisibleItems = function (context) {
return this.nativeChannel(context, 'findVisibleItems')();
};
/**
* @param context
* @returns Returns the range of the completely visible views.
* @returns Returns array of completely visible view's index.
*/
List.prototype.findCompletelyVisibleItems = function (context) {
return this.nativeChannel(context, 'findCompletelyVisibleItems')();
@ -2956,14 +2950,14 @@ var FlowLayout = /** @class */ (function (_super) {
};
/**
* @param context
* @returns Returns the range of the visible views for each column.
* @returns Returns array of visible view's index.
*/
FlowLayout.prototype.findVisibleItems = function (context) {
return this.nativeChannel(context, 'findVisibleItems')();
};
/**
* @param context
* @returns Returns the range of the completely visible views for each column.
* @returns Returns array of completely visible view's index.
*/
FlowLayout.prototype.findCompletelyVisibleItems = function (context) {
return this.nativeChannel(context, 'findCompletelyVisibleItems')();

View File

@ -1739,12 +1739,6 @@ __decorate$9([
Property,
__metadata$9("design:type", Array)
], ListItem.prototype, "actions", void 0);
exports.OtherItems = void 0;
(function (OtherItems) {
OtherItems[OtherItems["LoadMore"] = -10] = "LoadMore";
OtherItems[OtherItems["Header"] = -11] = "Header";
OtherItems[OtherItems["Footer"] = -12] = "Footer";
})(exports.OtherItems || (exports.OtherItems = {}));
class List extends Superview {
constructor() {
super(...arguments);
@ -1765,14 +1759,14 @@ class List extends Superview {
}
/**
* @param context
* @returns Returns the range of the visible views.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context) {
return this.nativeChannel(context, 'findVisibleItems')();
}
/**
* @param context
* @returns Returns the range of the completely visible views.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context) {
return this.nativeChannel(context, 'findCompletelyVisibleItems')();
@ -2232,14 +2226,14 @@ class FlowLayout extends Superview {
}
/**
* @param context
* @returns Returns the range of the visible views for each column.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context) {
return this.nativeChannel(context, 'findVisibleItems')();
}
/**
* @param context
* @returns Returns the range of the completely visible views for each column.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context) {
return this.nativeChannel(context, 'findCompletelyVisibleItems')();

View File

@ -3260,12 +3260,6 @@ __decorate$9([
Property,
__metadata$9("design:type", Array)
], ListItem.prototype, "actions", void 0);
exports.OtherItems = void 0;
(function (OtherItems) {
OtherItems[OtherItems["LoadMore"] = -10] = "LoadMore";
OtherItems[OtherItems["Header"] = -11] = "Header";
OtherItems[OtherItems["Footer"] = -12] = "Footer";
})(exports.OtherItems || (exports.OtherItems = {}));
class List extends Superview {
constructor() {
super(...arguments);
@ -3286,14 +3280,14 @@ class List extends Superview {
}
/**
* @param context
* @returns Returns the range of the visible views.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context) {
return this.nativeChannel(context, 'findVisibleItems')();
}
/**
* @param context
* @returns Returns the range of the completely visible views.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context) {
return this.nativeChannel(context, 'findCompletelyVisibleItems')();
@ -3753,14 +3747,14 @@ class FlowLayout extends Superview {
}
/**
* @param context
* @returns Returns the range of the visible views for each column.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context) {
return this.nativeChannel(context, 'findVisibleItems')();
}
/**
* @param context
* @returns Returns the range of the completely visible views for each column.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context) {
return this.nativeChannel(context, 'findCompletelyVisibleItems')();

33
doric-js/index.d.ts vendored
View File

@ -703,11 +703,6 @@ declare module 'doric/lib/src/widget/list' {
callback: () => void;
}[];
}
export enum OtherItems {
LoadMore = -10,
Header = -11,
Footer = -12
}
export class List extends Superview {
allSubviews(): ListItem[];
itemCount: number;
@ -735,20 +730,14 @@ declare module 'doric/lib/src/widget/list' {
}): Promise<any>;
/**
* @param context
* @returns Returns the range of the visible views.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context: BridgeContext): Promise<{
first: number;
last: number;
}>;
findVisibleItems(context: BridgeContext): Promise<number[]>;
/**
* @param context
* @returns Returns the range of the completely visible views.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context: BridgeContext): Promise<{
first: number;
last: number;
}>;
findCompletelyVisibleItems(context: BridgeContext): Promise<number[]>;
reset(): void;
toModel(): NativeViewModel;
}
@ -887,20 +876,14 @@ declare module 'doric/lib/src/widget/flowlayout' {
bounces?: boolean;
/**
* @param context
* @returns Returns the range of the visible views for each column.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context: BridgeContext): Promise<{
first: number;
last: number;
}[]>;
findVisibleItems(context: BridgeContext): Promise<number[]>;
/**
* @param context
* @returns Returns the range of the completely visible views for each column.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context: BridgeContext): Promise<{
first: number;
last: number;
}[]>;
findCompletelyVisibleItems(context: BridgeContext): Promise<number[]>;
reset(): void;
toModel(): NativeViewModel;
}

View File

@ -39,20 +39,14 @@ export declare class FlowLayout extends Superview {
bounces?: boolean;
/**
* @param context
* @returns Returns the range of the visible views for each column.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context: BridgeContext): Promise<{
first: number;
last: number;
}[]>;
findVisibleItems(context: BridgeContext): Promise<number[]>;
/**
* @param context
* @returns Returns the range of the completely visible views for each column.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context: BridgeContext): Promise<{
first: number;
last: number;
}[]>;
findCompletelyVisibleItems(context: BridgeContext): Promise<number[]>;
reset(): void;
private getItem;
private renderBunchedItems;

View File

@ -52,14 +52,14 @@ export class FlowLayout extends Superview {
}
/**
* @param context
* @returns Returns the range of the visible views for each column.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context) {
return this.nativeChannel(context, 'findVisibleItems')();
}
/**
* @param context
* @returns Returns the range of the completely visible views for each column.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context) {
return this.nativeChannel(context, 'findCompletelyVisibleItems')();

View File

@ -13,11 +13,6 @@ export declare class ListItem extends Stack {
callback: () => void;
}[];
}
export declare enum OtherItems {
LoadMore = -10,
Header = -11,
Footer = -12
}
export declare class List extends Superview {
private cachedViews;
allSubviews(): ListItem[];
@ -46,20 +41,14 @@ export declare class List extends Superview {
}): Promise<any>;
/**
* @param context
* @returns Returns the range of the visible views.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context: BridgeContext): Promise<{
first: number;
last: number;
}>;
findVisibleItems(context: BridgeContext): Promise<number[]>;
/**
* @param context
* @returns Returns the range of the completely visible views.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context: BridgeContext): Promise<{
first: number;
last: number;
}>;
findCompletelyVisibleItems(context: BridgeContext): Promise<number[]>;
reset(): void;
private getItem;
private renderBunchedItems;

View File

@ -35,12 +35,6 @@ __decorate([
Property,
__metadata("design:type", Array)
], ListItem.prototype, "actions", void 0);
export var OtherItems;
(function (OtherItems) {
OtherItems[OtherItems["LoadMore"] = -10] = "LoadMore";
OtherItems[OtherItems["Header"] = -11] = "Header";
OtherItems[OtherItems["Footer"] = -12] = "Footer";
})(OtherItems || (OtherItems = {}));
export class List extends Superview {
constructor() {
super(...arguments);
@ -61,14 +55,14 @@ export class List extends Superview {
}
/**
* @param context
* @returns Returns the range of the visible views.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context) {
return this.nativeChannel(context, 'findVisibleItems')();
}
/**
* @param context
* @returns Returns the range of the completely visible views.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context) {
return this.nativeChannel(context, 'findCompletelyVisibleItems')();

View File

@ -86,17 +86,18 @@ export class FlowLayout extends Superview {
/**
* @param context
* @returns Returns the range of the visible views for each column.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context: BridgeContext) {
return this.nativeChannel(context, 'findVisibleItems')() as Promise<{ first: number, last: number }[]>
return this.nativeChannel(context, 'findVisibleItems')() as Promise<number[]>
}
/**
* @param context
* @returns Returns the range of the completely visible views for each column.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context: BridgeContext) {
return this.nativeChannel(context, 'findCompletelyVisibleItems')() as Promise<{ first: number, last: number }[]>
return this.nativeChannel(context, 'findCompletelyVisibleItems')() as Promise<number[]>
}

View File

@ -35,12 +35,6 @@ export class ListItem extends Stack {
}[]
}
export enum OtherItems {
LoadMore = -10,
Header = -11,
Footer = -12,
}
export class List extends Superview {
private cachedViews: Map<string, ListItem> = new Map
@ -93,17 +87,17 @@ export class List extends Superview {
}
/**
* @param context
* @returns Returns the range of the visible views.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context: BridgeContext) {
return this.nativeChannel(context, 'findVisibleItems')() as Promise<{ first: number, last: number }>
return this.nativeChannel(context, 'findVisibleItems')() as Promise<number[]>
}
/**
* @param context
* @returns Returns the range of the completely visible views.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context: BridgeContext) {
return this.nativeChannel(context, 'findCompletelyVisibleItems')() as Promise<{ first: number, last: number }>
return this.nativeChannel(context, 'findCompletelyVisibleItems')() as Promise<number[]>
}
reset() {

View File

@ -3314,12 +3314,6 @@ __decorate$9([
Property,
__metadata$9("design:type", Array)
], ListItem.prototype, "actions", void 0);
exports.OtherItems = void 0;
(function (OtherItems) {
OtherItems[OtherItems["LoadMore"] = -10] = "LoadMore";
OtherItems[OtherItems["Header"] = -11] = "Header";
OtherItems[OtherItems["Footer"] = -12] = "Footer";
})(exports.OtherItems || (exports.OtherItems = {}));
class List extends Superview {
constructor() {
super(...arguments);
@ -3340,14 +3334,14 @@ class List extends Superview {
}
/**
* @param context
* @returns Returns the range of the visible views.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context) {
return this.nativeChannel(context, 'findVisibleItems')();
}
/**
* @param context
* @returns Returns the range of the completely visible views.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context) {
return this.nativeChannel(context, 'findCompletelyVisibleItems')();
@ -3807,14 +3801,14 @@ class FlowLayout extends Superview {
}
/**
* @param context
* @returns Returns the range of the visible views for each column.
* @returns Returns array of visible view's index.
*/
findVisibleItems(context) {
return this.nativeChannel(context, 'findVisibleItems')();
}
/**
* @param context
* @returns Returns the range of the completely visible views for each column.
* @returns Returns array of completely visible view's index.
*/
findCompletelyVisibleItems(context) {
return this.nativeChannel(context, 'findCompletelyVisibleItems')();

File diff suppressed because one or more lines are too long