Roberto Henrique
Roberto Henrique

Reputation: 404

Scroll To Index in ListView Flutter

In my application I am listing in an appBar several Containers that have the names of product categories, these categories are being listed in the body with their respective products.

The ListView that is in the appBar has the same indexes of the ListView of the body, so the idea was to press the index 'x' in the appBar and the user would be redirected to the index 'x' in the body.

I tried many solutions, one of then was the package https://pub.dev/packages/scrollable_positioned_list, but it did not works because when calling the function to scroll my list just disappears.

Here's de code:

return Scaffold(
  backgroundColor: Colors.white,
  appBar: PreferredSize(
    preferredSize: Size.fromHeight(120),
    child: Column(
      children: [
        AppBar(...),
        Expanded(
          child: Container(
            color: AppColors.primary,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              itemCount: widget.listaProdutos.length,
              itemBuilder: (context, index) {
                return Padding(
                  padding: EdgeInsets.symmetric(...),
                  child: GestureDetector(
                    child: Container(
                      decoration: BoxDecoration(...),
                      child: Padding(...),
                        child: Center(
                          child: Text(
                            widget.listaProdutos[index].dsGrupo,
                            style: TextStyle(
                              color: Colors.white,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      ),
                    ),
                    onTap: () {
                      SHOULD SCROLL TO INDEX
                    },
                  ),
                );
              },
            )
          ),
        ),
      ],
    ),
  ),
  body: SingleChildScrollView(
    child: Column(
      children: [
        Container(
          child: ListView.builder(
            physics: NeverScrollableScrollPhysics(),
            shrinkWrap: true,
            itemCount: widget.listaProdutos.length,
            itemBuilder: (context, indexGrupo) {
              return Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  Card(...),
                  ListView.builder(..),
                ],
              );
            },
          ),
        ),
      ],
    ),
  ),
);

Upvotes: 1

Views: 3016

Answers (2)

Roberto Henrique
Roberto Henrique

Reputation: 404

Fortunately I was able to resolve the problem. To help members who may have the same doubt I will register here the solution that worked for me. (sorry for the bad English)

Question: Why ScrollablePositionedList wasn't working? (as I mentioned iniatily)

Response: I was using the ScrollablePositionedList within a SingleChildScrollView, and for some reason when using the scrollTo or jumpTo function, the information that was visible simply disappeared. For that reason, I was trying to find a way to get success using a ListView (what came to nothing).

Solution: ... Trying to figure out why the ScrollablePositionedList wasn't working as it should ...

The initial structure was:

body: SingleChildScrollView(
  child: Column(
    children: [
      Container(
        child: ScrollablePositionedList.builder(

Changed for:

body: ScrollablePositionedList.builder(

The only reason for all this confusion is that ScrollablePositionedList's indexing functions for some reason don't work as they should if it's inside a SingleChildScrollView. So, take off SingleChildScrollView and all good.

Upvotes: 0

Md. Yeasin Sheikh
Md. Yeasin Sheikh

Reputation: 63799

You can use PageView with scrollDirection: Axis.vertical,


class TFW extends StatefulWidget {
  const TFW({super.key});

  @override
  State<TFW> createState() => _TFWState();
}

class _TFWState extends State<TFW> {
  final PageController controller = PageController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          bottom: PreferredSize(
        preferredSize: Size.fromHeight(100),
        child: Expanded(
          child: ListView.builder(
            itemCount: 100,
            scrollDirection: Axis.horizontal,
            itemBuilder: (context, index) {
              return InkWell(
                onTap: () {
                  controller.animateToPage(index,
                      duration: Duration(milliseconds: 400),
                      curve: Curves.easeIn);
                },
                child: SizedBox(width: 100, child: Text("$index")),
              );
            },
          ),
        ),
      )),
      body: PageView.builder(
        controller: controller,
        itemCount: 100,
        scrollDirection: Axis.vertical,
        itemBuilder: (context, index) {
          return Container(
            color: index.isEven ? Colors.red : Colors.blue,
            child: Text("$index"),
          );
        },
      ),
    );
  }
}

Upvotes: 2

Related Questions