TabBar + Scrollable Positioned List

Bonjour les amis.

J’ai un petit soucis et j’espère que vous pourrez m’aider.
J’ai un projet pour mercredi et je suis bloquer sur une fonctionnalité.

Mon but : J’ai une TabBar et j’ai une liste différente dans chaqu’une et un bouton « Accès rapide à un index de la liste ». J’aimerai donc avoir ces deux listes (qui contiennes beaucoup d’éléments, donc scrollable) ainsi que la possibilité sur la première TabBar, d’être redirigé vers un index précis de ma liste (de préférence avec une animation de scroll).

Mon problème : Lorsque que j’utilise le package scrollable_positioned_list j’ai une erreur quand je switch de Tab. Or avec le widget ListView, ça fonctionne bien mais pas de scroll à un index précis. J’ai trouvé que _controller.animateTo()

Mon erreur :

Le code pour démo :

import 'package:flutter/material.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  int _counter = 0;
  late TabController _tabController;
  ItemScrollController _scrollController = ItemScrollController();

  List<String> liste = [
    "3f5",
    "a4e",
    "zge",
    "az5",
    "61f",
    "a6e",
    "5zfg",
    "re",
    "z89",
    "4fe6",
    "az4rg",
    "6e4f",
    "6zae4",
    "rgz6",
    "4r",
    "3f5",
    "a4e",
    "zge",
    "az5",
    "61f",
    "a6e",
    "5zfg",
    "re",
    "z89",
    "4fe6",
    "az4rg",
    "6e4f",
    "6zae4",
    "rgz6",
    "4r"
  ];

  List<int> list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19];

  @override
  void initState() {
    _tabController = new TabController(length: 2, vsync: this);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        bottom: TabBar(
          controller: _tabController,
          tabs: [
            Tab(icon: Icon(Icons.directions_car)),
            Tab(icon: Icon(Icons.directions_transit)),
          ],
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          Container(
            color: Colors.white,
            child: Column(
              children: <Widget>[
                FlatButton.icon(
                  icon: Icon(Icons.arrow_downward, size: 18),
                  label: Text("Accès rapide à la prochaine étape"),
                  onPressed: () {
                    _scrollController.scrollTo(index: 3, duration: Duration(seconds: 1));
                  },
                ),
                Expanded(
                  child: ScrollablePositionedList.builder(
                      itemScrollController: _scrollController,
                      //controller: _scrollController,
                      //physics: ScrollPhysics(),
                      itemCount: liste.length,
                      itemBuilder: (BuildContext ctxt, int index) {
                        return Text(
                          liste[index],
                          textAlign: TextAlign.center,
                          style: TextStyle(
                            fontSize: 40,
                          ),
                        );
                      }),
                ),
              ],
            ),
          ),
          Container(
            color: Colors.white,
            child: Column(
              children: <Widget>[
                FlatButton.icon(
                  icon: Icon(Icons.arrow_downward, size: 18),
                  label: Text("Accès rapide à la prochaine étape"),
                  onPressed: () {
                    _scrollController.scrollTo(index: 3, duration: Duration(seconds: 1));
                  },
                ),
                Expanded(
                  child: ScrollablePositionedList.builder(
                      itemScrollController: _scrollController,
                      //controller: _scrollController,
                      //physics: ScrollPhysics(),
                      itemCount: list.length,
                      itemBuilder: (BuildContext ctxt, int index) {
                        return Text(
                          list[index].toString(),
                          textAlign: TextAlign.center,
                          style: TextStyle(
                            fontSize: 40,
                          ),
                        );
                      }),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

Bonjour,

Je ne vois pas la création du ‹ Listener › comme dans le Readme de la page du plugin :

Peut-être une piste?
sinon je vois qu’il faudrait peut-être placer le ‹ ItemScrollController() › dans le initState() aussi…

Merci pour ton retour @Mrt1 ,

Je regarde ça demain dès la première heure !
Je te tiens au courant.

Concernant le listener, avant de mettre en place ma TabBar, cela fonctionnait correctement :confused:
Mais je vais regarder ça avec attention demain matin. Je suis sur les dernières retouches, c’est chaud :fire: ^^

Bon courage à toi :slight_smile:

1 « J'aime »

J’essaye, j’essaye mais je trouve pas la solution…

Pourtant j’ai vue plusieurs solutions qui devrait fonctionner.

Ais-je fais une erreur ?

import 'package:flutter/material.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  late TabController _tabController;
  late ItemScrollController itemScrollController;
  late ItemPositionsListener itemPositionListener;

  @override
  void initState() {
    itemScrollController = ItemScrollController();
    itemPositionListener = ItemPositionsListener.create();
    _tabController = new TabController(length: 2, vsync: this);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        bottom: TabBar(
          controller: _tabController,
          tabs: [
            Tab(icon: Icon(Icons.directions_car)),
            Tab(icon: Icon(Icons.directions_transit)),
          ],
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          Container(
            color: Colors.white,
            child: Column(
              children: <Widget>[
                FlatButton.icon(
                  icon: Icon(Icons.arrow_downward, size: 18),
                  label: Text("Accès rapide à la prochaine étape"),
                  onPressed: () {
                    itemScrollController.scrollTo(index: 3, duration: Duration(seconds: 1));
                  },
                ),
                Expanded(
                  child: ScrollablePositionedList.builder(
                      itemScrollController: itemScrollController,
                      //controller: itemScrollController,
                      //physics: ScrollPhysics(),
                      itemCount: 30,
                      itemPositionsListener: itemPositionListener,
                      itemBuilder: (BuildContext ctxt, int index) {
                        return Text(
                          "Test",
                          textAlign: TextAlign.center,
                          style: TextStyle(
                            fontSize: 40,
                          ),
                        );
                      }),
                ),
              ],
            ),
          ),
          Container(
            color: Colors.white,
            child: Column(
              children: <Widget>[
                FlatButton.icon(
                  icon: Icon(Icons.arrow_downward, size: 18),
                  label: Text("Accès rapide à la prochaine étape"),
                  onPressed: () {
                    itemScrollController.scrollTo(index: 3, duration: Duration(seconds: 1));
                  },
                ),
                Expanded(
                  child: ScrollablePositionedList.builder(
                      itemScrollController: itemScrollController,
                      //controller: itemScrollController,
                      //physics: ScrollPhysics(),
                      itemPositionsListener: itemPositionListener,
                      itemCount: 30,
                      itemBuilder: (BuildContext ctxt, int index) {
                        return Text(
                          index.toString(),
                          textAlign: TextAlign.center,
                          style: TextStyle(
                            fontSize: 40,
                          ),
                        );
                      }),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

Solution trouvée !

L’ItemScrollController ne peut s’attacher qu’a une seul ScrollablePositioned. Or lorsqu’on change de page grâce à la TabBar, il essai d’afficher les deux listes.

@Tarobins l’explique ici :
https://githubmemory.com/repo/google/flutter.widgets/issues/231

Merci pour ton aide @Mrt1 :slight_smile: !

2 « J'aime »