user1506104
user1506104

Reputation: 7086

Auto scroll to one of SliverList items when a Tab is pressed

I have a stateful widget with tabs at the top and has a list below it. The list is subdivided into different categories. Each category is listed into each tab. What I want to do is when an item is pressed in the tab, I want its corresponding category in the list to scroll to view.

Here is the relevant code for reference:

SliverPersistentHeader(
  pinned: true,
  delegate: _SliverAppBarTabDelegate(
    child: Container(
      child: TabBar(
        isScrollable: true,
        labelColor: Colors.black,
        tabs: createTabList(),
        controller: tabBarController,
      ),
    ),
  ),
),
SliverList(
  delegate: SliverChildBuilderDelegate(
    (context, index) {
      return Padding(
        padding: const EdgeInsets.only(top: kSpacerRegular),
        child: RestaurantMenuCard(menuCard: menuCards[index]),
      );
    },
    childCount: menuCards.length,
  ),
),

I searched all day looking for a solution but could not find one. I also tried this package but does not seem to work in my case.

Here is my 'widget tree' for more context:

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: CustomScrollView(
      slivers: <Widget>[
        SliverAppBar(),
        SliverPersistentHeader(),
        SliverList(),
      ],
    ),
  );
}

A screen capture for more context

enter image description here

Upvotes: 3

Views: 5329

Answers (1)

user1506104
user1506104

Reputation: 7086

I solved the issue with the help of this answer. I replaced SliverList with SliverToBoxAdapter. The child is the list of my RestaurantMenuCard in a Column. Thus, the resulting widget tree is:

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: CustomScrollView(
      slivers: <Widget>[
        SliverAppBar(),
        SliverPersistentHeader(),
        SliverToBoxAdapter(
          Column(
            RestaurantMenuCard(),
            RestaurantMenuCard(),
            ...
          ),
        ),
      ],
    ),
  );
}

The magic happens when I added a global key to each instance of the RestaurantMenuCard as discussed in the linked answer.

Then finally, I trigger the Scrollable.ensureVisible(context) in onTap function of my TabBar.

Upvotes: 11

Related Questions