Skip to content

Commit 2a17115

Browse files
author
farfromrefug
committed
fix!: itemOverlap is now a function returning [top,right,bottom,left]
BREAKING CHANGE: `itemOverlap` is now a function returning [top,right,bottom,left]. So you need to change your code. This allows per item overlap.
1 parent ec36aed commit 2a17115

File tree

8 files changed

+108
-105
lines changed

8 files changed

+108
-105
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@
5656
]
5757
},
5858
"dependencies": {
59+
"@nativescript-community/arraybuffers": "^1.1.5",
5960
"@nativescript-community/class-mixins": "^1.0.0",
6061
"@nativescript-community/plugin-seed-tools": "file:tools",
6162
"@nativescript-community/template-snippet": "file:demo-snippets",
62-
"@nativescript-community/ui-drawer": "^0.1.27"
63+
"@nativescript-community/ui-drawer": "^0.1.28"
6364
},
6465
"ntl": {
6566
"descriptions": {

packages/collectionview/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,8 @@
5656
"url": "https://github.com/nativescript-community/ui-collectionview"
5757
},
5858
"license": "Apache-2.0",
59-
"readmeFilename": "README.md"
59+
"readmeFilename": "README.md",
60+
"dependencies": {
61+
"@nativescript-community/arraybuffers": "^1.1.5"
62+
}
6063
}

packages/collectionview/platforms/android/java/com/nativescript/collectionview/OverlapDecoration.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,22 @@
55

66
public class OverlapDecoration extends RecyclerView.ItemDecoration {
77

8-
public int top = 0;
9-
public int right = 0;
10-
public int bottom = 0;
11-
public int left = 0;
8+
public OverlapDecorationListener listener;
9+
10+
public interface OverlapDecorationListener {
11+
public java.nio.FloatBuffer getItemOverlap(int position);
12+
}
13+
14+
public OverlapDecoration(OverlapDecorationListener listener) {
15+
super();
16+
this.listener = listener;
17+
}
1218

1319
@Override
1420
public void getItemOffsets (Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
15-
final int itemPosition = parent.getChildAdapterPosition(view);
1621
int position = parent.getChildAdapterPosition(view);
1722
boolean isLast = position == state.getItemCount()-1;
18-
if (itemPosition == 0) {
19-
return; }
20-
outRect.set(left, top, right, bottom);
23+
java.nio.FloatBuffer buffer = listener.getItemOverlap(position);
24+
outRect.set((int)buffer.get(3), (int)buffer.get(0), (int)buffer.get(1), (int)buffer.get(2));
2125
}
2226
}

src/collectionview/index-common.ts

Lines changed: 10 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ export abstract class CollectionViewBase extends View implements CollectionViewD
124124
public verticalSpacing: CoreTypes.LengthType;
125125
public horizontalSpacing: CoreTypes.LengthType;
126126

127-
public itemOverlap: CoreTypes.LengthType[];
127+
spanSize: (item, index: number) => number;
128+
itemOverlap: (item, index: number) => [number, number, number, number];
128129
public _innerWidth: number = 0;
129130
public _innerHeight: number = 0;
130131
public _effectiveRowHeight: number;
@@ -464,11 +465,14 @@ export abstract class CollectionViewBase extends View implements CollectionViewD
464465
}
465466
this.refresh();
466467
}
467-
spanSize: (item, index: number) => number;
468468
onSpanSizeChanged = (oldValue, newValue) => {
469469
this.spanSize = newValue;
470470
this.refresh();
471471
};
472+
onItemOverlapChanged = (oldValue, newValue) => {
473+
this.itemOverlap = newValue;
474+
this.refresh();
475+
};
472476
_isDataDirty = false;
473477
onLoaded() {
474478
super.onLoaded();
@@ -731,59 +735,11 @@ export const autoReloadItemOnLayoutProperty = new Property<CollectionViewBase, b
731735
});
732736
autoReloadItemOnLayoutProperty.register(CollectionViewBase);
733737

734-
function parseThickness(value: string): any {
735-
if (typeof value === 'string') {
736-
const arr = value.split(/[ ,]+/);
737-
738-
let top: string;
739-
let right: string;
740-
let bottom: string;
741-
let left: string;
742-
743-
if (arr.length === 1) {
744-
top = arr[0];
745-
right = arr[0];
746-
bottom = arr[0];
747-
left = arr[0];
748-
} else if (arr.length === 2) {
749-
top = arr[0];
750-
bottom = arr[0];
751-
right = arr[1];
752-
left = arr[1];
753-
} else if (arr.length === 3) {
754-
top = arr[0];
755-
right = arr[1];
756-
left = arr[1];
757-
bottom = arr[2];
758-
} else if (arr.length === 4) {
759-
top = arr[0];
760-
right = arr[1];
761-
bottom = arr[2];
762-
left = arr[3];
763-
} else {
764-
throw new Error('Expected 1, 2, 3 or 4 parameters. Actual: ' + value);
765-
}
766-
767-
return {
768-
top,
769-
right,
770-
bottom,
771-
left
772-
};
773-
} else {
774-
return value;
775-
}
776-
}
777-
export const itemOverlapProperty = new Property<CollectionViewBase, CoreTypes.LengthType[]>({
738+
export const itemOverlapProperty = new Property<CollectionViewBase, Function>({
778739
name: 'itemOverlap',
779-
valueConverter: (value) => {
780-
if (typeof value === 'string' && value !== 'auto') {
781-
const thickness = parseThickness(value);
782-
783-
return [Length.parse(thickness.top), Length.parse(thickness.right), Length.parse(thickness.bottom), Length.parse(thickness.left)];
784-
} else {
785-
return [value, value, value, value];
786-
}
740+
defaultValue: undefined,
741+
valueChanged(target, oldValue, newValue) {
742+
target.onItemOverlapChanged(oldValue, newValue);
787743
}
788744
});
789745
itemOverlapProperty.register(CollectionViewBase);

src/collectionview/index.android.ts

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
scrollBarIndicatorVisibleProperty
3030
} from '.';
3131
import { CLog, CLogTypes, CollectionViewBase, ListViewViewTypes, isScrollEnabledProperty, orientationProperty } from './index-common';
32+
import { TypedArray, createArrayBuffer } from '@nativescript-community/arraybuffers';
3233

3334
export * from './index-common';
3435

@@ -337,11 +338,11 @@ export class CollectionView extends CollectionViewBase {
337338
// super.onUnloaded();
338339
// this.detachScrollListenerIfNecessary();
339340
// }
340-
341-
_getSpanSize: (item, index) => number;
342341
public getViewForItemAtIndex(index: number): View {
343342
return this.enumerateViewHolders<View>((v) => (v.getAdapterPosition() === index ? v.view : undefined));
344343
}
344+
345+
_getSpanSize: (item, index) => number;
345346
//@ts-ignore
346347
set spanSize(inter: (item, index) => number) {
347348
if (!(typeof inter === 'function')) {
@@ -370,6 +371,42 @@ export class CollectionView extends CollectionViewBase {
370371
return this._getSpanSize;
371372
}
372373

374+
decorator: com.nativescript.collectionview.OverlapDecoration;
375+
decoratorBuffer: TypedArray;
376+
decoratorListener: com.nativescript.collectionview.OverlapDecoration.OverlapDecorationListener;
377+
378+
nativeGetItemOverlap(position: number) {
379+
const item = this.getItemAtIndex(position);
380+
const result = this.itemOverlap(item, position);
381+
382+
this.decoratorBuffer[0] = Length.toDevicePixels(result[0], 0);
383+
this.decoratorBuffer[1] = Length.toDevicePixels(result[1], 0);
384+
this.decoratorBuffer[2] = Length.toDevicePixels(result[2], 0);
385+
this.decoratorBuffer[3] = Length.toDevicePixels(result[3], 0);
386+
return this.decoratorBuffer;
387+
}
388+
389+
[itemOverlapProperty.setNative](value) {
390+
if (typeof value === 'function') {
391+
if (!this.decorator) {
392+
this.decoratorListener = new com.nativescript.collectionview.OverlapDecoration.OverlapDecorationListener({
393+
getItemOverlap: this.nativeGetItemOverlap.bind(this)
394+
});
395+
this.decorator = new com.nativescript.collectionview.OverlapDecoration(this.decoratorListener);
396+
this.nativeViewProtected.addItemDecoration(this.decorator);
397+
}
398+
if (!this.decoratorBuffer) {
399+
this.decoratorBuffer = createArrayBuffer(4, false, true);
400+
}
401+
} else {
402+
if (this.decorator) {
403+
this.nativeViewProtected.removeItemDecoration(this.decorator);
404+
this.decorator = null;
405+
}
406+
this.decoratorListener = null;
407+
}
408+
}
409+
373410
private attachScrollListenerIfNecessary() {
374411
const nativeView = this.nativeViewProtected;
375412
if (this._scrollOrLoadMoreChangeCount > 0 && nativeView && !nativeView.scrollListener) {
@@ -560,25 +597,6 @@ export class CollectionView extends CollectionViewBase {
560597
[paddingLeftProperty.setNative](value: CoreTypes.LengthType) {
561598
this._setPadding({ left: this.effectivePaddingLeft });
562599
}
563-
decorator: com.nativescript.collectionview.OverlapDecoration;
564-
[itemOverlapProperty.setNative](value: CoreTypes.LengthType[]) {
565-
if (!value) {
566-
if (this.decorator) {
567-
this.nativeViewProtected.removeItemDecoration(this.decorator);
568-
this.decorator = null;
569-
}
570-
} else {
571-
if (!this.decorator) {
572-
this.decorator = new com.nativescript.collectionview.OverlapDecoration();
573-
this.nativeViewProtected.addItemDecoration(this.decorator);
574-
}
575-
this.decorator.top = Length.toDevicePixels(value[0], 0);
576-
this.decorator.right = Length.toDevicePixels(value[1], 0);
577-
this.decorator.bottom = Length.toDevicePixels(value[2], 0);
578-
this.decorator.left = Length.toDevicePixels(value[3], 0);
579-
}
580-
}
581-
582600
public [orientationProperty.getDefault](): Orientation {
583601
return 'vertical';
584602
}

src/collectionview/index.ios.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ export class CollectionView extends CollectionViewBase {
690690
return this.getRowIndexPath(view).at(-1) ?? -1;
691691
}
692692

693-
private getRowIndexPath(view: UICollectionView){
693+
private getRowIndexPath(view: UICollectionView) {
694694
return Array.from<NSIndexPath>(view.indexPathsForVisibleItems)
695695
.map((e) => e.row)
696696
.sort((a, b) => a - b);
@@ -1238,14 +1238,13 @@ class UICollectionViewFlowLayoutImpl extends UICollectionViewFlowLayout {
12381238
const attributesArray = super.layoutAttributesForElementsInRect(rect);
12391239
const owner = this._owner?.get();
12401240
if (owner?.itemOverlap) {
1241-
const itemOverlap = owner.itemOverlap;
12421241
for (let index = 0; index < attributesArray.count; index++) {
12431242
const attributes = attributesArray.objectAtIndex(index);
12441243
if (attributes.representedElementCategory === UICollectionElementCategory.Cell) {
1245-
const xPosition =
1246-
attributes.center.x + Utils.layout.toDeviceIndependentPixels(Length.toDevicePixels(itemOverlap[1], 0) + Length.toDevicePixels(itemOverlap[2], 0)) * attributes.indexPath.row;
1247-
const yPosition =
1248-
attributes.center.y + Utils.layout.toDeviceIndependentPixels(Length.toDevicePixels(itemOverlap[0], 0) + Length.toDevicePixels(itemOverlap[2], 0)) * attributes.indexPath.row;
1244+
const row = attributes.indexPath.row;
1245+
const itemOverlap = owner.itemOverlap(owner.getItemAtIndex(row), row);
1246+
const xPosition = attributes.center.x + Utils.layout.toDeviceIndependentPixels(Length.toDevicePixels(itemOverlap[1], 0) + Length.toDevicePixels(itemOverlap[2], 0)) * row;
1247+
const yPosition = attributes.center.y + Utils.layout.toDeviceIndependentPixels(Length.toDevicePixels(itemOverlap[0], 0) + Length.toDevicePixels(itemOverlap[2], 0)) * row;
12491248
attributes.center = CGPointMake(xPosition, yPosition);
12501249
}
12511250
}

src/collectionview/typings/android.d.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,13 @@ declare namespace com {
8080

8181
export class SmoothScroller extends androidx.recyclerview.widget.LinearSmoothScroller {}
8282
export class OverlapDecoration extends androidx.recyclerview.widget.RecyclerView.ItemDecoration {
83-
public top: number;
84-
public right: number;
85-
public bottom: number;
86-
public left: number;
83+
constructor(listener: OverlapDecorationListener);
84+
}
85+
export namespace OverlapDecoration {
86+
export class OverlapDecorationListener {
87+
constructor(implementation: { getItemOverlap(position: number): java.nio.FloatBuffer });
88+
getItemOverlap(position: number): java.nio.FloatBuffer;
89+
}
8790
}
8891
}
8992
}

0 commit comments

Comments
 (0)