Reputation: 157
I have animated pageview and listview that connected to each other. But I have an animation problem that caused by setState(i have tested to removed the setState and the animation works well).
import 'package:flutter/material.dart';
const double _listheight = 80;
class LoyaltyPage extends StatefulWidget {
@override
_LoyaltyPageState createState() => new _LoyaltyPageState();
}
class _LoyaltyPageState extends State<LoyaltyPage> {
PageController controller;
ScrollController listcontroller;
int selected = 0;
List<String> images=[
'https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
'https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
'https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
'https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
];
@override
initState() {
super.initState();
controller = new PageController(
initialPage: selected,
keepPage: false,
viewportFraction: 0.7,
);
listcontroller = new ScrollController();
}
@override
dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.black),
title: Text(
'Loyalty',
style: TextStyle(color: Colors.black),
),
),
body: Column(
children: <Widget>[
Expanded(
flex: 3,
child: new Container(
child: new PageView.builder(
onPageChanged: (value) {
//ADDING THIS SET STATE CAUSE SELECTED COLOR WORKS BUT LAGGY ANIMATION
setState(() {
selected=value;
});
listcontroller.animateTo(value*_listheight,duration: Duration(milliseconds: 500),curve: Curves.ease);
},
itemCount: images.length,
controller: controller,
itemBuilder: (context, index) => builder(index)),
),
),
Expanded(
flex: 6,
child: new Container(
child: new ListView.builder(
controller: listcontroller,
itemCount: images.length,
itemBuilder: (context,index) => _listbuilder(index),
),
),
),
],
),
);
}
builder(int index) {
return new AnimatedBuilder(
animation: controller,
builder: (context, child) {
double value = 1.0;
if (controller.position.haveDimensions) {
value = controller.page - index;
value = (1 - (value.abs() * .4)).clamp(0.0, 1.0);
}
return new Center(
child: new SizedBox(
height: Curves.easeOut.transform(value) * 180,
width: Curves.easeOut.transform(value) * 270,
child: child,
),
);
},
child: new Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(20))),
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
child:Container(
child: Image.network(images[index],fit: BoxFit.fill,)
),
),
);
}
_listbuilder(int index){
return Container(
height: _listheight,
child: Column(
children: <Widget>[
ListTileTheme(
selectedColor: Colors.blueAccent,
child: ListTile(
title: Text(images[index],maxLines: 1,overflow: TextOverflow.ellipsis,),
subtitle: Text('Level : Gold'),
leading: GestureDetector(
onTap: (){
//ADDING THIS SET STATE CAUSE SELECTED COLOR WORKS BUT LAGGY ANIMATION
setState(() {
selected=index;
});
controller.animateToPage(index,duration: Duration(milliseconds: 500),curve: Curves.ease);
},
child: Icon(
Icons.credit_card),
),
trailing: Icon(Icons.navigate_next),
selected: index==selected,//THIS IS THE SELECTED THAT I TRIED TO CHANGE
),
),
Divider(height: 1,color: Colors.black45,),
],
),
);
}
}
I use setState at 2 places where it's on pagechanged and on leading listtile of my app.And here is my app looks like.
the first one is the expected output of my app but it laggy, the second one has smooth animation but the text color doesn't change.
Upvotes: 0
Views: 4567
Reputation: 1424
Try running your application in Release or Profile Mode.
There are performance-issues with animations in debug-mode when only a CircularProgressIndicator() is spinning. This is due to the fact that in Debug Mode, Dart gets compiled JIT instead of AOT. Thus, the Drawing Engine would need to compile 60 times / second while drawing the UI during the animation to run as smoothly as in AOT mode. This would take up a lot of resources as one might guess.
As long as you don't call setState({})
on the AnimationController..addListener()
you should be fine with your specific implementation. Please refer to this article for further details on Animations and setState({})
: https://medium.com/flutter-community/flutter-laggy-animations-how-not-to-setstate-f2dd9873b8fc .
Upvotes: 3