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