convert listview to animatedlistview - flutter

I have created basic todo app Everything is going well but while deleting or converting to completed(clicked on checkbox) it removes instantly.. I want animated so that It took time and user can see its checked or deleted
I have done all code but now don't know how to replace and where part should be corrected to convert into AnimatedList...
I want to have ur suggestion,
for how to convert to animatedList and is there any simple way instead animatedList bcz I have to do many changes in converting list view to animated list
class TodoListWidget extends StatelessWidget {
const TodoListWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final provider = Provider.of<TodoProvider>(context);
final todos = provider.todos;
return todos.length == 0
? Center(
child: Text('No Todos'),
)
: ListView.separated(
//physics: BouncingScrollPhysics(),
padding: EdgeInsets.all(10),
separatorBuilder: (context, index) {
return Container(
height: 9,
);
},
itemCount: todos.length,
itemBuilder: (context, index) {
final todo = todos[index];
return TodoWidget(todo: todo);
},
);
}
}
here is my class todowidget
class TodoWidget extends StatelessWidget {
final Todo todo;
TodoWidget({required this.todo});
#override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Container(
color: todo.color,
padding: EdgeInsets.all(20),
child: Row(
children: [
todo.isdone==false?Checkbox(
activeColor: Colors.white,
checkColor: Colors.red,
value: todo.isdone,
onChanged: (value) {
final result= Provider.of<TodoProvider>(context,listen: false).toogletodo(todo);
}):IconButton(onPressed: (){
final result= Provider.of<TodoProvider>(context,listen: false).toogletodo(todo);
}, icon: Icon(Icons.refresh)),
SizedBox(
width: 20,
),
GestureDetector(
onTap: todo.isdone?null:(){
showDialog(
barrierDismissible: false,
context: context,
builder: (ctx)=> AddTodoDialogWidget(
title: todo.title,
description: todo.description,
isedit:true,
id: todo.id,
));
},
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(todo.title,style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16, color: Colors.black)),
SizedBox(height: 6,),
if (todo.description.isNotEmpty)
Container(
child: Text(
todo.description,
style: TextStyle(fontSize: 12, color: Colors.black),
),
),
],
),
),
),
Spacer(),
IconButton(
onPressed: () {
Provider.of<TodoProvider>(context,listen: false).deletetodo(todo);
},
icon: Icon(Icons.delete,color: Colors.red,)),
],
),
),
);
}
}

Related

flutter putting data from api in expansion tile

Hew guys , i got a small question .
im making a drawer that should have a titles and a neste titles so i use an expansion tile.
so the titles are displayed but when i press the arrow to open the nested titles it gives me an error.
i used future builder in the nested titles i think this is the problem the error gives me this
The following TypeErrorImpl was thrown building FutureBuilder<List<dynamic>>(dirty, state: _FutureBuilderState<List<dynamic>>#aeb31):
Unexpected null value.
this is my drawer
Drawer Image
this is my drawer code
import 'package:MyCima/Screens/drawer_title_page.dart';
import 'package:MyCima/models/drawer_shows_data_model.dart';
import 'package:MyCima/services/services.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../constants.dart';
class FilmsDrawer extends StatefulWidget {
const FilmsDrawer({Key? key}) : super(key: key);
#override
_FilmsDrawerState createState() => _FilmsDrawerState();
}
class _FilmsDrawerState extends State<FilmsDrawer> {
final ServicesClass _services = ServicesClass();
late DrawerShowsDataModel _showsModelClass;
late Future drawerListData;
List nestedListNames = [];
#override
void initState() {
drawerListData = getDrawerList();
super.initState();
}
Future<List> getDrawerList() async {
return await _services.getFilms('menus');
}
#override
Widget build(BuildContext context) {
return Drawer(
elevation: 150,
semanticLabel: 'More Shows',
backgroundColor: PRIMARY,
child: Padding(
padding: const EdgeInsets.only(top: 24),
child: FutureBuilder(
future: drawerListData,
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.active:
case ConnectionState.waiting:
return const Center(
child: CircularProgressIndicator(),
);
case ConnectionState.done:
return Column(
children: [
Expanded(
flex: 5,
child: Column(
children: [
Expanded(
flex: 9,
child: Text(
'MyCima',
style: GoogleFonts.bevan(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
const Expanded(
flex: 1,
child: Divider(
color: Colors.white,
indent: 64,
endIndent: 64,
),
),
],
),
),
Expanded(
flex: 95,
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
_showsModelClass = DrawerShowsDataModel.fromJson(
snapshot.data[index]);
if (_showsModelClass.listChildren.length > 0) {
return ExpansionTile(
title: Text(
_showsModelClass.name,
style: const TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
children: [
getNestedTitles(index),
],
);
} else {
return Container(
alignment: Alignment.centerLeft,
padding: const EdgeInsets.all(8),
child: TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const DrawerTitlePage()));
},
child: Text(
'${_showsModelClass.name}',
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
);
}
}),
),
],
);
case ConnectionState.none:
return const Center(child: Text('No Connection'));
}
},
),
),
);
}
getNestedTitles(int index){
return FutureBuilder(
future: getDrawerList(),
builder: (BuildContext context, AsyncSnapshot<List<dynamic>> snapshot) {
return ListView.builder(
itemCount: snapshot.data![index]['children'].length,
itemBuilder: (BuildContext context, int index) {
_showsModelClass = DrawerShowsDataModel.fromNestedJson(snapshot.data![index]['children'][index]);
return TextButton(
onPressed: () {},
child: Text(
'${_showsModelClass.name}',
),
);
},
);
},
);
}
}
i found the answer
we need to make a list of widgets and add widgets on it then use it in the expansion
List<Widget> list = [];
List<Widget> getNestedTitles(int index) {
List<Widget> list = [];
drawerListData.then((value) {
for (var x in value[index]['children']) {
list.add(Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const DrawerTitlePage()));
},
child: Text('${x['name']}',
style: const TextStyle(
color: Colors.white,
),),
),
));
}
});
return list;
}

The class 'SimpleFoldingCell' doesn't have a default constructor

https://github.com/flutter-devs/flutter_folding_cell_demo/blob/master/lib/demo_screen.dart
I'm trying to follow the code in the link above.
But in the SimpleFoldingCell part, an error named 'The class 'SimpleFoldingCell' doesn't have a default constructor.' occurs.
Could
Is there a way to resolve this error in Dart?
class Notific extends StatefulWidget{
#override
_State createState() => _State();
}
class _State extends State<Notific>{
late List<TechnologyModel> _technologyList;
#override
void initState() {
super.initState();
_technologyList = [
TechnologyModel(title: "Application Development",),
TechnologyModel(title: "Research & Development",),
TechnologyModel(title: "Big Data & Analytics",),
TechnologyModel(title: "Support Services",),
TechnologyModel(title: "QA & Software Testing",),
];
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.pink[200],
title: Text("Folding Cell Demo",
style: TextStyle(color: Colors.white),),
),
body: Container(
child: ListView.builder(
itemCount: _technologyList.length,
itemBuilder: (context, index) {
return SimpleFoldingCell(
frontWidget: _buildFrontWidget(index),
innerTopWidget: _buildInnerWidget(index),
innerBottomWidget: _buildInnerBottomWidget(),
cellSize: Size(MediaQuery.of(context).size.width, 125),
padding: EdgeInsets.all(15),
animationDuration: Duration(milliseconds: 200),
borderRadius: 10,
onOpen: () => print('$index cell opened'),
onClose: () => print('$index cell closed'),
);
},
),
),
);
}
Widget _buildFrontWidget(int index) {
return Builder(
builder: (BuildContext context) {
return Container(
color: Colors.cyan[100],
alignment: Alignment.bottomCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Aeologic Technology",
style: TextStyle(
fontSize:20.0,
color: Colors.black,
),
),
SizedBox(height: 10,),
FlatButton(
onPressed: () {
final foldingCellState = context
.findAncestorStateOfType<SimpleFoldingCellState>();
foldingCellState?.toggleFold();
},
child: Text(
"OPEN",
),
textColor: Colors.white,
color: Colors.indigoAccent[100],
splashColor: Colors.white.withOpacity(0.5),
),
],
),
);
},
);
}
Widget _buildInnerBottomWidget() {
return Builder(
builder: (context) {
return Container(
color: Colors.blueGrey[50],
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(bottom: 10),
child: FlatButton(
onPressed: () {
final foldingCellState = context
.findAncestorStateOfType<SimpleFoldingCellState>();
foldingCellState?.toggleFold();
},
child: Text(
"Close",
),
textColor: Colors.white,
color: Colors.redAccent[100],
splashColor: Colors.white.withOpacity(0.5),
),
),
);
}
);
}
Widget _buildInnerWidget(int index) {
return Builder(
builder: (context) {
return Container(
color: Colors.pink[100],
padding: EdgeInsets.only(top: 10),
child: Align(
alignment: Alignment.center,
child: Text(
_technologyList[index].title,
style: TextStyle(
fontSize:20.0,
color: Colors.black,
),
),
),
);
},
);
}
}
class TechnologyModel {
String title;
TechnologyModel({
required this.title,
});
}
For some reason they've created only a named constructor.
return SimpleFoldingCell.create(
frontWidget: _buildFrontWidget(index),
innerWidget: _buildInnerWidget(index),
// innerTopWidget: _buildInnerWidget(index),
// innerBottomWidget: _buildInnerBottomWidget(),
cellSize: Size(MediaQuery.of(context).size.width, 125),
padding: EdgeInsets.all(15),
animationDuration: Duration(milliseconds: 200),
borderRadius: 10,
onOpen: () => print('$index cell opened'),
onClose: () => print('$index cell closed'),
);
It looks like the demo you're looking at is a bit outdated, since some of those properties don't exist anymore (see commented code).

how to get the id from statefull widget to stateless widget in flutter?

I need to get the id from quizCatId in the category() class to QuizTile() can someone tell me how to solve the issue...
my need is to call subcategory data from firestore which has an quizid and quizcatid and there I have my quizdata so I need to pass both the id to the quizdata to get data from the firestore
class Category extends StatefulWidget {
String quizCatId;
Category(this.quizCatId);
#override
_CategoryState createState() => _CategoryState();
}
class _CategoryState extends State<Category> {
Stream quizStream;
DatabaseService databaseService = new DatabaseService();
Widget quizList() {
return Container(
child: Column(
children: [
StreamBuilder(
stream: quizStream,
builder: (context, snapshot) {
return snapshot.data == null
? Container()
: ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
return QuizTile(
noOfQuestions: snapshot.data.documents.length,
imageUrl:
snapshot.data.documents[index].data['quizImgUrl'],
title:
snapshot.data.documents[index].data['quizTitle'],
desc: snapshot.data.documents[index].data['quizDesc'],
quizid: snapshot.data.documents[index].data["quizId"],
);
});
},
),
],
),
);
}
#override
void initState() {
databaseService.getCatData(widget.quizCatId).then((value) {
quizStream = value;
setState(() {});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
centerTitle: true,
title: appBar(context),
brightness: Brightness.light,
elevation: 0.0,
backgroundColor: Colors.transparent,
//brightness: Brightness.li,
),
body: SingleChildScrollView(child: quizList()),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => CreateCategoryQuiz()));
},
),
);
}
}
class QuizTile extends StatelessWidget {
final String imageUrl, title, quizid, desc, quizcatId;
final int noOfQuestions;
QuizTile({
#required this.title,
#required this.imageUrl,
#required this.desc,
#required this.quizid,
#required this.noOfQuestions,
#required this.quizcatId,
});
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PlayQuiz(quizid, quizcatId)));
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 14),
height: 150,
margin: EdgeInsets.only(bottom: 8),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Stack(
children: [
Image.network(
imageUrl,
fit: BoxFit.cover,
width: MediaQuery.of(context).size.width,
),
Container(
color: Colors.black26,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
title,
style: TextStyle(
fontSize: 18,
color: Colors.white,
fontWeight: FontWeight.w500),
),
SizedBox(
height: 4,
),
Text(
desc,
style: TextStyle(
fontSize: 13,
color: Colors.white,
fontWeight: FontWeight.w500),
)
],
),
),
)
],
),
),
),
);
}
}
Hey you have acces to statefulWidget properties form state class by windget property.
All you have to do is ad new parameter in QuizTile constructor and call them
QuizTile(
noOfQuestions: snapshot.data.documents.length,
imageUrl:
snapshot.data.documents[index].data['quizImgUrl'],
title:
snapshot.data.documents[index].data['quizTitle'],
desc: snapshot.data.documents[index].data['quizDesc'],
quizid: snapshot.data.documents[index].data["quizId"],
quizCatId: widget.quizCatId
);

I want to generate card by onPressed method in my flutter app . Can anyone show me a roadmap for that...?

I have made the listview.builder in my page. In that i have designed my card . Now i want to generate card in the Listveiw.buider one by one by clicking a onpressed method in a floating action button. Which method/function should i write in that onpressed ? and how to generate card in that and what should i change in itemCount and itemBuilder. I need that roadmap. Thanks.
ListView.builder(
itemCount: 5,
itemBuilder: (context, index) {
return Dismissible(
key:Key(null),
direction: DismissDirection.startToEnd,
onDismissed: (direction) {},
confirmDismiss: (direction) {
return showDialog(
context: context, builder: (_) => DeleteCard());
},
background: Container(
color: Colors.red,
padding: EdgeInsets.only(left: 16),
child: Icon(
Icons.delete,
color: Colors.white,
),
alignment: Alignment.centerLeft,
),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0)),
color: Colors.white70,
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
width: 120,
padding: EdgeInsets.all(10.0),
child: Text(
"Project ",
style: TextStyle(
fontSize: 11, fontWeight: FontWeight.bold),
),
),
Container(
padding: EdgeInsets.all(10.0),
child: ProjectName(),
),
],
),
// item add start
Container(
padding: EdgeInsets.all(10.0),
child: TextFormField(
decoration: InputDecoration(
hintText: "Item name" ,hintStyle: TextStyle(fontSize: 12),
),
),
),
Container(
padding: EdgeInsets.all(10.0),
child: TextFormField(
decoration: InputDecoration(
hintText: "Amount",hintStyle: TextStyle(fontSize: 12),
),
keyboardType: TextInputType.number,
),
),
],
),
),
);
}
),
This is something you are looking for I think. Just replace the ListTile with your own Card
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
var listLength = 1;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter App :)"),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
setState(() {
listLength++;
});
}),
body: Container(
child: ListView.builder(
itemCount: listLength,
itemBuilder: (context, index) {
return ListTile(
leading: Text("$index"),
title: Text("List Tile as Widget"),
);
})),
);
}
}
I have solved it by using a var which initial value in 0 then make a function in set state and increment the variable. Then I called the function in my floating action button and in listview.builder item count I set the var name. I hope it will help others it's a easy solution to generate card by using onpressed.

Problem with List builder repeat the data when adding or removing item in the list

I'm new to flutter. When I adding new item or removing an item from the list, the list builder does update the list, but the problem is that the list builder also displaying the previous item list and showing new updated item list. So what I want to do is keeping the new updated item list instead of old item list.
class AlarmPage extends StatefulWidget {
final String title;
AlarmPage({Key key, this.title}) : super(key: key);
#override
_AlarmPageState createState() => _AlarmPageState();
}
class _AlarmPageState extends State<AlarmPage> {
String alarmName;
// Test Function
void _addAlarm() {
setState(() {
Navigator.push(
context, MaterialPageRoute(builder: (context) => AddAlarm()));
});
}
#override
void initState() {
super.initState();
Provider.of<AlarmsProvider>(context, listen: false).getLocalStorage();
}
#override
Widget build(BuildContext context) {
List<Widget> allWidgetsAlarms = List<Widget>();
return Consumer<AlarmsProvider>(builder: (context, alarmProviderItem, _) {
List<String> localAlarms = alarmProviderItem.alarms;
if (localAlarms != null) {
localAlarms.forEach((item) {
allWidgetsAlarms.add(
Stack(
children: <Widget>[
InkWell(
child: Container(
color: Color(0xff212121),
padding: EdgeInsets.all(10),
child: Column(
children: <Widget>[
// Alarm Name & Title
Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(width: 2),
)),
child: Row(
children: <Widget>[
Icon(Icons.alarm, color: Colors.yellow),
SizedBox(width: 20.0),
Text('$item',
style: TextStyle(
color: Color(0xffC1C1C1),
fontSize: 15.0,
fontWeight: FontWeight.w900)),
SizedBox(height: 5),
],
),
),
SizedBox(height: 10),
// Alarm Time & Toggle Switch
Container(
child: Row(
children: <Widget>[
Text(
'Time',
style: TextStyle(
fontSize: 30, color: Colors.white),
),
SizedBox(width: 20),
Text(
'AM / PM',
style: TextStyle(
fontSize: 20, color: Color(0xffB5B5B5)),
),
SizedBox(width: 150),
Icon(Icons.switch_camera, color: Colors.yellow),
],
),
),
// Alarm Repeat
Container(
child: Row(children: <Widget>[
Text(
'Repeat',
style: TextStyle(
fontSize: 11, color: Color(0xff616161)),
),
Container(
child: DaySelector(
value: null,
onChange: (value) {},
color: Colors.yellow[400],
mode: DaySelector.modeFull,
),
),
]),
),
],
),
),
onLongPress: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddAlarm(item: item)));
},
),
SizedBox(height: 180),
],
),
);
print(item);
});
}
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title: Text('Azy Alarm'),
centerTitle: true,
),
body: Container(
decoration: BoxDecoration(
image: const DecorationImage(
fit: BoxFit.cover,
image: AssetImage('assets/images/background_image(dark).png')),
),
// child: ListView(children: allWidgetsAlarms),
child: ListView.builder(
itemCount: allWidgetsAlarms.length,
padding: const EdgeInsets.all(8.0),
itemBuilder: (BuildContext context, int index) {
return allWidgetsAlarms[index];
}),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: Colors.blue,
elevation: 0,
onPressed: _addAlarm,
),
);
});
}
}
So I think your issue is this line: allWidgetsAlarms.add( You construct allWidgetsAlarms in your builder, but the builder is not called again every time you Consumer rebuilds, hence it is just appending the new contents to the end of the list. To fix this, keep your original initialization of allWidgetsAlarms just at the top of the builder in your Consumer, add the following line:
allWidgetsAlarms = List<Widget>();
This will resert allWidgetsAlarms. Hope it helps!