Flutter 颤振-AnimatedBuilder,动画/小部件在首次加载时出错

Flutter 颤振-AnimatedBuilder,动画/小部件在首次加载时出错,flutter,flutter-layout,flutter-animation,flutter-web,Flutter,Flutter Layout,Flutter Animation,Flutter Web,当我第一次加载构建器时,我的所有卡片在跳到正确的大小和比例之前都是相同大小的,有人知道我如何调整这些卡片,使它们从一开始就处于正确的大小吗 奇怪的是,当我用一个装满图像的容器替换我的Padding&Card小部件时,它似乎产生了正确的大小,但我需要它们成为我以后布局的卡片 (我还计划将其全部放入一个widget类中,而不是将所有这些代码放在我的main中,而只是返回一个CustomScroller。) 请检查以下GIF: 如果您能帮助修复初始加载,我们将不胜感激!:) 导入“包装:颤振/材料

当我第一次加载构建器时,我的所有卡片在跳到正确的大小和比例之前都是相同大小的,有人知道我如何调整这些卡片,使它们从一开始就处于正确的大小吗

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

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

请检查以下GIF:

如果您能帮助修复初始加载,我们将不胜感激!:)

导入“包装:颤振/材料.省道”;
导入“package:blink/widget/customScroller.dart”;
void main()=>runApp(新的MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“颤振演示”,
主题:新主题数据(
主样本:颜色。蓝色,
),
主页:新MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>new_MyHomePageState();
}
类_MyHomePageState扩展状态{
页面控制器;
列表图像=[
"https://iso.500px.com/wp-content/uploads/2014/07/big-one.jpg",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRXRfe-GZBFRQZV8UDHMCSHQGAJ2JD5SGSR7COYWP_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“
];
@凌驾
void initState(){
//TODO:实现initState
pageController=pageController(初始页:1,视口分数:0.77);
}
@凌驾
小部件构建(构建上下文){
归还新脚手架(
正文:PageView.builder(
控制器:页面控制器,
itemCount:images.length,
itemBuilder:(上下文、位置){
返回自定义滚动条(位置);
}),);
}
customScroller(int索引){
返回动画生成器(
动画:页面控制器,
生成器:(上下文,小部件){
双val=1;
if(页面控制器.位置.尺寸){
val=pageController.page-索引;
val=1-(val.abs()*0.3).clamp(0.0,1.0);}
返回中心(
孩子:大小盒子(
高度:Curves.easeInOut.transform(val)*300,
宽度:曲线.easeInOut.transform(val)*400,
孩子:小部件,
),
);
},
//子:容器(
//保证金:所有(10),
//子项:Image.network(图像[索引],适合:BoxFit.cover),
//      ),
//当我使用上面的代码作为子代码而不是填充卡片时,它似乎正确地生成了
孩子:填充(
填充:从LTRB(0,15,0,15)开始的边缘设置,
子:容器(
孩子:卡片(
颜色:颜色。白色70,
立面图:9,
形状:圆形矩形边框(
边界半径:边界半径。圆形(20.0),
),
clipBehavior:Clip.antiAlias,
子:容器(
颜色:颜色,白色,
填充:边缘设置。全部(5),
孩子:排(
儿童:[
扩大(
弹性:2,
子:容器(
高度:双无限,
孩子:ClipRRect(
borderRadius:仅限borderRadius(
左上:半径。圆形(20.0),
右上角:半径。圆形(0.0),
右下角:半径。圆形(0.0),
左下角:半径。圆形(20.0)),
孩子:新图像网络(
图像[索引],
适合:BoxFit.cover,
),
),
),
),
],
),
),
),
),
)
);
}
}

您缺少的是,仅当存在一些动画时,AnimatedBuilder构建方法才会运行。不是一开始。这就是为什么当你滚动而不是之前滚动时,大小会改变

您的子窗口小部件没有使用transformer窗口小部件(或大小框)包装,因此它在所有索引中都保持不变(一开始,构建器还没有运行)。在我的示例中,我还用一个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,
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
void main()=>runApp(新的MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“颤振演示”,
主题:新主题数据(
主样本:颜色。蓝色,
),
主页:新MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>new_MyHomePageState();
}
类_MyHomePageState扩展状态{
页面控制器;
列表图像=[
"https://iso.500px.com/wp-content/uploads/2014/07/big-one.jpg",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRXRfe-GZBFRQZV8UDHMCSHQGAJ2JD5SGSR7COYWP_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=1
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,
      ),
    );
  }
}