web-dev-qa-db-fra.com

Comment réparer mon AnimatedSwitcher qui change mais n'anime pas

J'essaie de créer une section d'actualités dans mon application. Dans cette page qui va afficher les nouvelles, je veux pouvoir cliquer n'importe où sur la page et obtenir les nouvelles qui sont les prochaines dans ma liste. Jusqu'à présent, aucun problème avec cela, mais je voulais qu'il ait une belle animation, j'ai donc essayé d'implémenter AnimatedSwitcher, mais je ne peux pas comprendre pourquoi il n'y a pas d'animation.

J'ai essayé de changer la hiérarchie de mon code. Placer le détecteur de gestes à l'intérieur du commutateur animé et inversement. Laisser le récipient principal à l'extérieur ou à l'intérieur de celui-ci aussi. J'ai essayé un générateur d'animation qui le mettrait à l'échelle au cas où ce ne serait pas assez évident, mais rien. J'ai essayé de changer la durée aussi mais ce n'était pas ça.

class ShowNews extends StatefulWidget {
  @override
  _ShowNewsState createState() => _ShowNewsState();
}

class _ShowNewsState extends State<ShowNews> {
  List<News> _news = [
    News(title: 'OYÉ OYÉ', desc: 'bla bla bla bla bla'),
    News(title: 'another one', desc: 'plus de bout d\'histoire'),
    News(title: 'boum', desc: 'attention à l\'accident'),
    News(title: 'Lorem ipsum', desc: 'Lorem ipsum in doloris'),
  ];

  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          if (_currentIndex < _news.length - 1) {
            _currentIndex++;
          } else {
            _currentIndex = 0;
          }
        });
      },
      child: Container(
        height: 160,
        padding: EdgeInsets.all(20.0),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.only(
            topLeft: Radius.circular(20.0),
            topRight: Radius.circular(20.0),
          ),
        ),
        child: AnimatedSwitcher(
          duration: Duration(seconds: 5),
          child: ColumnArticle(_news, _currentIndex),
        ),
      ),
    );
  }
}

Tout fonctionne bien, mais l'animation.

Edit: j'ai essayé d'ajouter une clé pour la rendre différente mais toujours pas d'animation.

class ColumnArticle extends StatelessWidget {
  final List<News> _news;
  final int _currentIndex;

  ColumnArticle(this._news, this._currentIndex);

  @override
  Widget build(BuildContext context) {
    return Column(
      key: ValueKey<int>(_currentIndex),
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        Text(
          _news[_currentIndex].title,
          textAlign: TextAlign.left,
          style: TextStyle(
            fontSize: 20.0,
          ),
        ),
        SizedBox(
          height: 10.0,
        ),
        Text(
          _news[_currentIndex].desc,
          style: TextStyle(
            fontSize: 14.0,
          ),
        ),
      ],
    );
  }
}
6
Marylène Beaudin

Votre problème pourrait être le type de widgets comme décrit ici .

Si le "nouveau" enfant est du même type de widget et de la même clé que le "vieux" enfant, mais avec des paramètres différents, alors AnimatedSwitcher ne fera pas de transition entre eux, car pour autant que le framework est concerné, ce sont le même widget et le widget existant peut être mis à jour avec les nouveaux paramètres. Pour forcer la transition à se produire, définissez une clé sur chaque widget enfant que vous souhaitez considérer comme unique (généralement une ValueKey sur les données du widget qui distingue cet enfant des autres).

Vous pouvez définir des clés individuelles pour vos widgets News afin de les rendre uniques . Comme dans cet exemple:

Column(
  children: <Widget>[
     AnimatedSwitcher(
         duration: const Duration(milliseconds: 500),

         child: Text(
             '$_count',
             // This key causes the AnimatedSwitcher to interpret this as a "new"
             // child each time the count changes, so that it will begin its animation
             // when the count changes.
             key: ValueKey<int>(_count),
         ),
     ),
     RaisedButton(
          child: const Text('Increment'),
          onPressed: () {
            setState(() {
              _count += 1;
            });
          },
     ),
])
1
easeccy