颤振补间基本动画在“FutureBuilder”中不起作用
Posted
技术标签:
【中文标题】颤振补间基本动画在“FutureBuilder”中不起作用【英文标题】:Flutter tween basic animation is not working inside `FutureBuilder` 【发布时间】:2019-05-01 03:34:07 【问题描述】:Flutter tween 基本动画在 FutureBuilder
内部不起作用
我使用 gridview.builder 创建了一个图片库页面,但由于某种原因,动画在 futurebuilder
中不起作用。我直接在 body 容器内的静态图像上尝试了相同的动画,效果非常好。需要一些方法来为 futurebuilder 中的网络图像设置动画。
class _GalleryGridState extends State<GalleryGrid>
with TickerProviderStateMixin
AnimationController _controller;
Animation _squeezeOutAnimation, transformationAnim;
List<GalleryModel> lists = List();
Future<List<GalleryModel>> fetchPost() async
final response =
await http.get("https://jsonplaceholder.typicode.com/photos");
if (response.statusCode == 200)
var datas = json.decode(response.body);
lists = (datas as List)
.map((data) => new GalleryModel.fromJson(data))
.toList();
return lists;
else
throw Exception("Failed to load photos");
@override
void initState()
super.initState();
_controller =
AnimationController(duration: Duration(seconds: 3), vsync: this);
transformationAnim = BorderRadiusTween(
begin: BorderRadius.circular(150.0),
end: BorderRadius.circular(0.0))
.animate(CurvedAnimation(parent: _controller, curve: Curves.ease));
_squeezeOutAnimation = Tween<double>(begin: 150.0, end: 1000.0)
.animate(CurvedAnimation(parent: _controller, curve: Curves.ease));
@override
void dispose()
super.dispose();
_controller.dispose();
@override
Widget build(BuildContext context)
return FutureBuilder(
future: fetchPost(),
builder: (context, data)
switch (data.connectionState)
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
default:
return GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount: lists.length,
itemBuilder: (BuildContext context, int index)
return Stack(
children: <Widget>[
Container(
child: Card(
shape: BeveledRectangleBorder(
borderRadius: transformationAnim.value),
elevation: 10.0,
child: GestureDetector(
onTap: ()
_controller.forward();
,
child: Container(
width: _squeezeOutAnimation.value,
height: _squeezeOutAnimation.value,
child: Image.network(
lists[index].thumbnailUrl,
fit: BoxFit.fill,
width: _squeezeOutAnimation.value,
),
),
),
),
),
])
【问题讨论】:
【参考方案1】:动画正在运行,但您的构建小部件没有更新,即重建
试试这个代码,如果它按预期工作,请告诉我。
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
void main() => runApp(GalleryGrid());
class GalleryGrid extends StatefulWidget
@override
_GalleryGridState createState() => _GalleryGridState();
class GalleryModel
final String thumbnailUrl;
GalleryModel(this.thumbnailUrl);
factory GalleryModel.fromJson(Map<String, dynamic> data)
return GalleryModel(data['thumbnailUrl']);
class _GalleryGridState extends State<GalleryGrid>
List<GalleryModel> lists = List();
Future<List<GalleryModel>> fetchPost() async
final response =
await http.get("https://jsonplaceholder.typicode.com/photos");
if (response.statusCode == 200)
var datas = json.decode(response.body);
lists = (datas as List)
.map((data) => new GalleryModel.fromJson(data))
.toList();
return lists;
else
throw Exception("Failed to load photos");
@override
Widget build(BuildContext context)
return MaterialApp(
home: Scaffold(
body: FutureBuilder(
future: fetchPost(),
builder: (context, data)
switch (data.connectionState)
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
default:
return new GridWidget(lists: lists);
,
),
),
);
//),
//);
class GridWidget extends StatefulWidget
const GridWidget(
Key key,
@required this.lists,
) ;
final List<GalleryModel> lists;
@override
GridWidgetState createState()
return new GridWidgetState();
class GridWidgetState extends State<GridWidget> with TickerProviderStateMixin
AnimationController _controller;
Animation _squeezeOutAnimation, transformationAnim;
@override
void initState()
super.initState();
_controller =
AnimationController(duration: Duration(seconds: 3), vsync: this);
transformationAnim = BorderRadiusTween(
begin: BorderRadius.circular(150.0),
end: BorderRadius.circular(0.0))
.animate(CurvedAnimation(parent: _controller, curve: Curves.ease))
..addListener(()
setState(() );
);
_squeezeOutAnimation = Tween<double>(begin: 150.0, end: 1000.0)
.animate(CurvedAnimation(parent: _controller, curve: Curves.ease));
@override
void dispose()
super.dispose();
_controller.dispose();
@override
Widget build(BuildContext context)
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemCount: widget.lists.length,
itemBuilder: (BuildContext context, int index)
return Stack(children: <Widget>[
Container(
child: Card(
shape: BeveledRectangleBorder(
borderRadius: transformationAnim.value),
elevation: 10.0,
child: GestureDetector(
onTap: ()
print('Card $index is pressed');
_controller.reset();
_controller.forward();
,
child: Container(
width: _squeezeOutAnimation.value,
height: _squeezeOutAnimation.value,
child: Image.network(
widget.lists[index].thumbnailUrl,
fit: BoxFit.fill,
width: _squeezeOutAnimation.value,
),
),
),
),
),
]);
,
);
【讨论】:
thanx 兄弟它的工作,bt 现在的问题是所有的图像都在一次动画,我希望点击的项目只有动画,使用当前动画是否可以实现。 @rahul.sharma 我想是的,如果你设法将一张卡片提取到它自己的小部件中并将动画相关代码放在那里,我认为它可以工作。试一试,让我知道是否我可以提供更多帮助。 是的,我也在想同样的逻辑,谢谢,我会试一试【参考方案2】:您可以使用Hero 小部件,它使用标签为您完成了很多工作:
class HomePage extends StatefulWidget
@override
State<StatefulWidget> createState() => new _HomePageState();
class _HomePageState extends State<HomePage>
List<Image> images;
@override
void initState()
images = new List<Image>();
images.add(Image.asset("assets/blue.png"));
images.add(Image.asset("assets/red.png"));
images.add(Image.asset("assets/green.png"));
images.add(Image.asset("assets/yellow.png"));
images.add(Image.asset("assets/pink.png"));
images.add(Image.asset("assets/cyan.png"));
// get images
super.initState();
@override
Widget build(BuildContext context)
return Material(
child: GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount: images.length,
itemBuilder: (context, index)
String tag = "Image" + index.toString();
return Hero(
tag: tag,
child: Material(
child: InkWell(
child: GridTile(child: images[index]),
onTap: ()
Navigator.push(context, MaterialPageRoute(builder: (context)
return Scaffold(
appBar: AppBar(title: Text(tag)),
body: ImagePage(image: images[index], imageTag: tag));
));
,
)));
,
));
class ImagePage extends StatefulWidget
final Image image;
final String imageTag;
ImagePage(this.image, this.imageTag);
@override
State<StatefulWidget> createState() => new _ImagePageState();
class _ImagePageState extends State<ImagePage>
@override
Widget build(BuildContext context)
return Hero(
tag: widget.imageTag,
child: Material(
child: Center(
child: widget.image,
),
),
);
【讨论】:
欣赏它,但我的目标是仅在同一屏幕上弹出点击的图像,帮助我实现它 我尝试在没有futurebuilder的情况下为图像制作动画,效果很好,所以futurebuilder导致动画出现问题。以上是关于颤振补间基本动画在“FutureBuilder”中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
在 FutureBuilder 中使用 Uint8List 的颤振给出错误