eclipsesource / eclipsesource/tabris-js
CollectionView "scroll" event deltas sometimes cannot be used to reliably track scroll offset
- Dominant language
- JavaScript
- Stars
- 1.4k
- Forks
- 171
- PR merge metrics
- No merged PRs in 30d
Description
### Problem description
CollectionView does not have an API like ScrollView's [`offsetY`](https://docs.tabris.com/latest/api/ScrollView.html#offsety). The only option to track the scroll offset is to manually sum `deltaY` provided by the scroll event. However, on Android, in some cases `deltaY` might not reflect the reality. The delta sum gets inaccurate particularly when calling `CollectionView#reveal()`. Maybe some `scroll` events are not getting triggered in this scenario.
### Expected behavior
Fix `deltaY` so that it can be used to track the CollectionView scroll offset in conjunction with `reveal()` and/or provide an API like ScrollView's `offsetY` in addition.
### Environment
- Tabris.js version: nightly, 2.9.0
- OS: Android 9
### Code snippet
Scroll to the bottom of the list manually and scroll to the top manually. The offset calculated by using the deltas will be almost 0 as expected.
Scroll to the bottom of the list manually and tap on the "scroll to top" button. The offset will be off by a small margin. Repeat this a few times and the error of the sum will increase.
```js
import {$, CollectionView, contentView, TextView, Composite, Button} from 'tabris';
/** @param {tabris.Attributes=} attributes */
const SectionCell = attributes =>
;
/** @param {tabris.Attributes=} attributes */
const ItemCell = attributes =>
;
const items = createItems();
contentView.append(
<$>
items[index].type}
cellHeight={(_, type) => type === 'section' ? 48 : 32}
createCell={type => type === 'section' ? SectionCell() : ItemCell()}
updateCell={(cell, index) => cell.text = items[index].name}
onScroll={handleScroll}/>
);
function scrollToTop() {
tabris.contentView.find(tabris.CollectionView).first().reveal(0);
}
let offset = 0;
/** @param {tabris.CollectionViewScrollEvent>} ev */
function handleScroll({deltaY}) {
offset += deltaY;
contentView.find('#tracker').first(TextView).text = offset.toString();
}
function createItems() {
let itemCount = 1;
/** @type {Array<{name: string, type: 'section' | 'item'}>} */
const result = [];
for (let j = 1; j <= 10; j++) {
result.push({name: 'Section ' + itemCount++, type: 'section'});
for (let i = 0; i < 5; i++) {
result.push({name: 'Item ' + itemCount++, type: 'item'});
}
}
return result;
}
```
Contributor guide
Assessment
This issue has not been assessed yet.