【问题标题】:Flutter - AnimatedBuilder , animation/widget bugs out when loading in for first timeFlutter - AnimatedBuilder ,第一次加载时出现动画/小部件错误
【发布时间】:2020-05-13 07:37:45
【问题描述】:

当我第一次加载构建器时,在跳转到正确的尺寸和比例之前,我所有的卡片都是相同的尺寸,有谁知道我可以如何调整它以使它们的尺寸从出发?

奇怪的是,当我用一个装满图像的容器替换我的 Padding & Card 小部件时,它似乎以正确的大小生成,但是我需要它们作为我以后布局的卡片。

(我还计划将其全部放入一个小部件类中,而不是将所有这些代码放入我的 main 中,而只是返回一个 CustomScroller。)

请检查以下 Gif:

Gif Of Animation Glitch Gif of Animation working fine when just container is used

任何修复初始加载的帮助将不胜感激! :)

import 'package:flutter/material.dart';
import 'package:blink/widget/customScroller.dart';


void main() => runApp(new MyApp());

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

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  PageController pageController;

  List<String> images = [
    "https://iso.500px.com/wp-content/uploads/2014/07/big-one.jpg",
    "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRXRfe-GzBFRQzv8udHMCshqQGAj2JD5SGsR7CoyWP_HqFapJCYSA&s",
    "https://ichef.bbci.co.uk/wwfeatures/live/976_549/images/live/p0/7w/b9/p07wb9xk.jpg",
    "https://images.unsplash.com/photo-1501785888041-af3ef285b470?ixlib=rb-1.2.1&w=1000&q=80"
  ];

  @override
  void initState() {
    // TODO: implement initState
    pageController = PageController(initialPage: 1, viewportFraction: 0.77);
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: PageView.builder(
          controller: pageController,
            itemCount: images.length,
            itemBuilder: (context,position){
            return customScroller(position);
            }),);
  }

  customScroller(int index) {
    return AnimatedBuilder(
      animation: pageController,
      builder: (context, widget) {
        double val = 1;

        if(pageController.position.haveDimensions){
          val = pageController.page - index;
        val = 1 - (val.abs()*0.3).clamp(0.0,1.0);}

        return Center(
          child: SizedBox(
            height: Curves.easeInOut.transform(val) *300,
              width: Curves.easeInOut.transform(val) *400,
            child: widget,
          ),
        );
      },
//      child: Container(
//        margin: EdgeInsets.all(10),
//        child: Image.network(images[index],fit:BoxFit.cover),
//      ),
// When I use the above code as the child instead of the padding with the card in it seems to spawn correctly
        child: Padding(
          padding: EdgeInsets.fromLTRB(0, 15, 0, 15),
          child: Container(
            child: Card(
              color: Colors.white70,
              elevation: 9,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(20.0),
              ),
              clipBehavior: Clip.antiAlias,
              child: Container(
                color: Colors.white,
                padding: EdgeInsets.all(5),
                child: Row(
                  children: <Widget>[
                    Expanded(
                      flex: 2,
                      child: Container(
                        height: double.infinity,
                        child: ClipRRect(
                          borderRadius: BorderRadius.only(
                              topLeft: Radius.circular(20.0),
                              topRight: Radius.circular(0.0),
                              bottomRight: Radius.circular(0.0),
                              bottomLeft: Radius.circular(20.0)),
                          child: new Image.network(
                            images[index],
                            fit: BoxFit.cover,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        )

    );
  }
}

【问题讨论】:

    标签: flutter flutter-layout flutter-animation flutter-web


    【解决方案1】:

    您缺少的是 AnimatedBuilder 构建方法仅在有一些动画时运行。不是一开始。所以这就是为什么如果你滚动而不是之前大小会改变的原因。

    您的子小部件未使用转换器小部件(或大小框)包装,因此所有索引都保持相同(在开始时 - 构建器尚未运行)。在我的示例中,我还用 SizedBox 包裹了孩子,并给了 val 一些初始值。

    工作示例:

    import 'package:flutter/material.dart';
    
    void main() => runApp(new MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      PageController pageController;
    
      List<String> images = [
        "https://iso.500px.com/wp-content/uploads/2014/07/big-one.jpg",
        "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRXRfe-GzBFRQzv8udHMCshqQGAj2JD5SGsR7CoyWP_HqFapJCYSA&s",
        "https://ichef.bbci.co.uk/wwfeatures/live/976_549/images/live/p0/7w/b9/p07wb9xk.jpg",
        "https://images.unsplash.com/photo-1501785888041-af3ef285b470?ixlib=rb-1.2.1&w=1000&q=80"
      ];
    
      @override
      void initState() {
        // TODO: implement initState
        pageController = PageController(initialPage: 1, viewportFraction: 0.77);
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          body: PageView.builder(
              controller: pageController,
              itemCount: images.length,
              itemBuilder: (context, position) {
                return customScroller(position);
              }),
        );
      }
    
      customScroller(int index) {
        Widget child = Padding(
          padding: EdgeInsets.fromLTRB(0, 15, 0, 15),
          child: Container(
            child: Card(
              color: Colors.white70,
              elevation: 9,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(20.0),
              ),
              clipBehavior: Clip.antiAlias,
              child: Container(
                color: Colors.white,
                padding: EdgeInsets.all(5),
                child: Row(
                  children: <Widget>[
                    Expanded(
                      flex: 2,
                      child: Container(
                        height: double.infinity,
                        child: ClipRRect(
                          borderRadius: BorderRadius.only(
                              topLeft: Radius.circular(20.0),
                              topRight: Radius.circular(0.0),
                              bottomRight: Radius.circular(0.0),
                              bottomLeft: Radius.circular(20.0)),
                          child: new Image.network(
                            images[index],
                            fit: BoxFit.cover,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
        double val = (index == 1)?1:0.7;
    
        return AnimatedBuilder(
            animation: pageController,
            builder: (context, widget) {
              if (pageController.position.haveDimensions) {
                val = pageController.page - index;
                val = 1 - (val.abs() * 0.3).clamp(0.0, 1.0);
              }
              print("val: $val; index: $index");
              return _getTransformedSizedBox(val, widget);
            },
    //      child: Container(
    //        margin: EdgeInsets.all(10),
    //        child: Image.network(images[index],fit:BoxFit.cover),
    //      ),
    // When I use the above code as the child instead of the padding with the card in it seems to spawn correctly
            child: _getTransformedSizedBox(val, child));
      }
    
      _getTransformedSizedBox(double val, Widget widget) {
        return Center(
          child: SizedBox(
            height: Curves.easeInOut.transform(val) * 300,
            width: Curves.easeInOut.transform(val) * 400,
            child: widget,
          ),
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-07-16
      • 2020-04-21
      • 2021-07-30
      • 1970-01-01
      • 1970-01-01
      • 2016-05-14
      • 1970-01-01
      • 2021-01-23
      • 1970-01-01
      相关资源
      最近更新 更多