Flutter tween 基本动画在“FutureBuilder”中不起作用
Flutter tween basic animation is not working inside `FutureBuilder`
Flutter tween 基本动画在内部不起作用FutureBuilder
我使用 gridview.builder 创建了一个图片库页面,但出于某种原因,动画在 futurebuilder
中不起作用。我直接在 body 容器内的静态图像上尝试了相同的动画,它完美地工作 fine.Need 以某种方式在 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,
),
),
),
),
),
])
您可以使用 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,
),
),
);
}
}
动画是 运行 但您的构建小部件没有更新,即重建
试试这个代码,如果它能像你预期的那样工作,请告诉我。
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,
),
),
),
),
),
]);
},
);
}
}
Flutter tween 基本动画在内部不起作用FutureBuilder
我使用 gridview.builder 创建了一个图片库页面,但出于某种原因,动画在 futurebuilder
中不起作用。我直接在 body 容器内的静态图像上尝试了相同的动画,它完美地工作 fine.Need 以某种方式在 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,
),
),
),
),
),
])
您可以使用 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,
),
),
);
}
}
动画是 运行 但您的构建小部件没有更新,即重建
试试这个代码,如果它能像你预期的那样工作,请告诉我。
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,
),
),
),
),
),
]);
},
);
}
}