Flutter - AnimatedBuilder ,第一次加载时出现动画/小部件错误
Posted
技术标签:
【中文标题】Flutter - AnimatedBuilder ,第一次加载时出现动画/小部件错误【英文标题】:Flutter - AnimatedBuilder , animation/widget bugs out when loading in for first time 【发布时间】: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,
),
),
),
),
],
),
),
),
),
)
);
【问题讨论】:
【参考方案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,
),
);
【讨论】:
以上是关于Flutter - AnimatedBuilder ,第一次加载时出现动画/小部件错误的主要内容,如果未能解决你的问题,请参考以下文章
Flutter-PositionedTransition位置变化动画
4-6 动画Animation开发指南-AnimatedWidget与AnimatedBuilder
Xcode 13 和 Flutter 2.5.1 - 致命错误:找不到“Flutter/Flutter.h”文件 #import <Flutter/Flutter.h>
Flutter 致命错误:找不到“Flutter/Flutter.h”文件
[Flutter] flutter项目一直卡在 Running Gradle task 'assembleDebug'...