Closed emvaized closed 4 years ago
I don't want callback header offset every frame.You can get such information:
ExpandableListHeaderController.stickySectionIndex
ExpandableListHeaderController.switchingSectionIndex
Maybe example_animable_header can give you some tips. ^_^
@tp7309 Thanks :) I'm currently using this approach to create a shadow below header only when it's pinned on top:
Card(
elevation:
stickyController.stickySectionIndex == sectionIndex
? 3
: 0,
)
But it works with some issues -- for example, when there's padding on top of the list, header of the first card always has shadow, even when it's not pinned. Maybe I'm just missing something?
Padding on top of the list? Could you give me an example?
For example (approximation of my use case):
CustomScrollView(
slivers: [
/// First child of my CustomScrollView, which can be considered as a 'padding'
SliverToBoxAdapter(
child: Container(height: 100, width: 100)
),
ExpandableListView(
controller: stickyController,
builder: SliverExpandableChildDelegate<String, ExampleSection>(
headerBuilder: (context, section, index) => Text("Header #$index"),
itemBuilder: (context, section, item, index) {
int sectionIndex = sectionList.indexOf(section);
return Card(
elevation:
stickyController.stickySectionIndex == sectionIndex
? 3
: 0, /// <-- when list is scrolled to top, first header never reach this value
child: Text(item),
);
}
))
]
);
@tp7309 Previously I used flutter_sticky_headers, and with implementation below there were no problems:
...
return Card(
elevation: stickiness < 0.0 ? 3 : 0,
child: Text(item)
)
That's why I suggested to implement some analog of stickiness
parameter, with values of -1.0
(completely off-screen), 0.0
('sticked') and 1.0
(not sticked, floating).
@emvaized Thanks for your feedback! Built-in animation are planned to be added in this weekend! For your feature, you can try the following code:
class _ExampleSliverState extends State<ExampleSliver> {
var sectionList = MockData.getExampleSections();
int _stickySectionIndex = -1;
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: CustomScrollView(slivers: [
/// First child of my CustomScrollView, which can be considered as a 'padding'
SliverToBoxAdapter(child: Container(height: 100, width: 100)),
SliverExpandableList(
builder: SliverExpandableChildDelegate<String, ExampleSection>(
sectionList: sectionList,
headerController: _getHeaderController(),
headerBuilder: (context, section, index) {
int sectionIndex = sectionList.indexOf(section);
return Card(
elevation: _stickySectionIndex == sectionIndex ? 10 : 0,
child: Text("Header #$index"),
);
},
itemBuilder: (context, section, item, index) {
int sectionIndex = sectionList.indexOf(section);
return Card(
elevation: _stickySectionIndex == sectionIndex ? 10 : 0,
child: Text(item),
);
}))
]),
),
);
}
_getHeaderController() {
var controller = ExpandableListHeaderController();
//when changing sticky header, listener will be called.
controller.addListener(() {
/// if you want call itemBuilder when changing sticky header, call setState() manually.
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted || _stickySectionIndex == controller.stickySectionIndex) {
return;
}
// print(controller);
setState(() {
_stickySectionIndex = controller.stickySectionIndex;
});
});
/// if you only want call headerBuilder when changing sticky header, no need to call setState().
/// just change some value in headerBuilder.
});
return controller;
}
}
@tp7309 Previously I used flutter_sticky_headers, and with implementation below there were no problems:
... return Card( elevation: stickiness < 0.0 ? 3 : 0, child: Text(item) )
That's why I suggested to implement some analog of
stickiness
parameter, with values of-1.0
(completely off-screen),0.0
('sticked') and1.0
(not sticked, floating).
It will trigger widget rebuild high frequency, so if you need rebuild item widget, call setState() manually is another option.
@tp7309 Very nice! Will be glad to try out these animations.
About subject: Please let me illustrate my issue with this GIF (with your solution already implemented):
The issue I mentioned above can be seen in the end of this GIF, and your solution created another issue, that can be seen in the beginning of GIF (previous header keeps at elevation == 0
despite being over content).
There has a bug, when scroll out SliverExpandableList, stickySectionIndex are not updated, I'm trying to fix it.
@tp7309 Oh, I see now. Glad you're working on it! I'll be waiting for updates.
@emvaized Hi, I have updated the library, you can try to use 0.2.0-beta. In order to use it more conveniently, some API changed, so you may need read the lastest REMDME. fixed animable header example
@tp7309 I see. A lot of changes :) Seems like bug is fixed now. Great, thanks a lot for your work!
@emvaized Thank you for you feedback:)
Please implement more intuitive behavior, for all 3 states of header: like
-1.0
for header being off-screen,0.0
for pinned, and1.0
for not-pinned (floating) header, as it is implemented here.