-
-
Notifications
You must be signed in to change notification settings - Fork 50
Scroll only if item is not fully visible #118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Try the code below. final result = await observerController.dispatchOnceObserve(
isDependObserveCallback: false,
isForce: true,
);
final resultMap = result.observeResult?.displayingChildModelMap ?? {};
final displayPercentage = resultMap[x]?.displayPercentage ?? 0;
if (displayPercentage == 1) return;
observeController.animateTo(index: x, ...) |
My observerController is SliverObserverController displayingChildModelMap => innerDisplayingChildModelMap displayPercentage is not available |
final result = await observerController.dispatchOnceObserve(
// sliverContext: _sliverGridCtx,
sliverContext: _sliverListCtx,
isDependObserveCallback: false,
isForce: true,
);
final observeResult = result.observeAllResult[_sliverListCtx];
// if (observeResult is! GridViewObserveModel) {
if (observeResult is! ListViewObserveModel) {
return;
}
final resultMap = observeResult.displayingChildModelMap;
final displayPercentage = resultMap[x]?.displayPercentage ?? 0;
if (displayPercentage == 1) return;
observeController.animateTo(index: x, ...) |
Tried your code but
does not return a result -> endless wait. |
It works fine on my side, please give a reproducible sample |
This is clear :) I guess a standard example will work. My app is "special" (as always) and the app itself is open source, but the configuration is not trivial. Maybe you have an idea with my code: TableWrapper - StatefulWidget TableWidget gets the controller in constructor
and the method _scrollToSelected contains your code:
A context problem? |
Yes, it's the context! I had to cache the BuildContext like in your example, e.g. https://github.com/fluttercandies/flutter_scrollview_observer/blob/main/example/lib/features/listview/listview_ctx_demo/listview_ctx_demo_page.dart I will try it again with right context! |
Everything is fine with your code - works. One additional question: If the item is not fully visible, you scroll until it's fully visible and if possible, you scroll it to top of the list. Is it possible to scroll just as much until the item is fully visible? A short video to demonstrate what's happening: scroll_to_last.movIf I select the last record, it's not fully visible, and after selection the list scrolls until the item is the first shown item. It would be nice to scroll only until the item is fully visible but not until it's the first visible in the list. |
... or scroll the item to the middle of the list? |
Scroll to the edgefinal result = await observerController.dispatchOnceObserve(
isDependObserveCallback: false,
isForce: true,
);
final observeResult = result.observeResult;
final resultMap = observeResult?.displayingChildModelMap ?? {};
final targetResult = resultMap[index];
final displayPercentage = targetResult?.displayPercentage ?? 0;
if (displayPercentage == 1) return;
bool isAtTopItem = false;
if (targetResult != null) {
isAtTopItem = targetResult.leadingMarginToViewport <= 0;
} else {
final displayingChildModelList =
observeResult?.displayingChildModelList ?? [];
if (displayingChildModelList.isNotEmpty) {
final firstItem = displayingChildModelList.first;
isAtTopItem = firstItem.index > index;
}
}
observerController.jumpTo(
index: index,
alignment: isAtTopItem ? 0 : 1,
isFixedHeight: true,
offset: (targetOffset) {
if (isAtTopItem) return 0;
var _obj = ObserverUtils.findRenderObject(
observerController.sliverContexts.first,
);
if (_obj == null || _obj is! RenderSliver) return 0;
return _obj.geometry?.paintExtent ?? 0;
},
); Scroll to the middlefinal result = await observerController.dispatchOnceObserve(
sliverContext: _sliverListCtx,
isDependObserveCallback: false,
isForce: true,
);
final observeResult = result.observeAllResult[_sliverListCtx];
if (observeResult is! ListViewObserveModel) {
return;
}
final resultMap = observeResult.displayingChildModelMap;
final displayPercentage = resultMap[x]?.displayPercentage ?? 0;
if (displayPercentage == 1) return;
observerController.jumpTo(
index: index,
alignment: 0.5, // <------ 1
// Optional, If the size of your item is fixed, it is recommended to set it to true.
isFixedHeight: true,
offset: (targetOffset) {
if (isAtTopItem) return 0;
var _obj = ObserverUtils.findRenderObject(
observerController.sliverContexts.first,
);
if (_obj == null || _obj is! RenderSliver) return 0;
return (_obj.geometry?.paintExtent ?? 0) * 0.5; // <------ 2
},
); |
…tioned_list -> scrollview_observer) (see fluttercandies/flutter_scrollview_observer#118)
Verified and works as expected. The "Scroll to the middle" code should be without |
Platforms
iOS
Description
I have a CustomScrollView with SliverList.
observeController.animateTo(index: x, ...) works without problems.
Is it possible to find out if index: x is fully shown and don't scroll in this case?
It could be possible that index: x is not fully shown, but a small part. In this case, scroll to the index?
I tried to use onObserve but it won't be called initialy and observerController.dispatchOnceObserve(...) didn't help.
My code
No response
Try do it
No response
The text was updated successfully, but these errors were encountered: