Failed assertion: line 4021 pos 12: 'name != null': is not true - android

Hello programmers I have the following problem
Failed assertion: line 4021 pos 12: 'name != null': is not true.
when I use onTap(){_con.goToPage} Clicking on the image takes the user to another page
I need help please, this error has stalled my process
I show the two Dart files involved in the error
class RolesPage extends StatefulWidget {
const RolesPage({Key key}) : super(key: key);
#override
_RolesPageState createState() => _RolesPageState();
}
class _RolesPageState extends State<RolesPage> {
RolesController _con = new RolesController();
#override
void initState() {
// TODO: implement initState
super.initState();
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
_con.init(context, refresh);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("select a role"),
),
body: Container(
margin: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.14),
child: ListView(
children: _con.user != null ? _con.user.roles.map((Rol rol){
return _cardRol(rol);
}).toList() : []
),
),
);
}
Widget _cardRol(Rol rol){
return GestureDetector(
onTap: (){
_con.goToPage(rol.route);
},
child: Column(
children: [
Container(
height: 100,
child: FadeInImage(
image: rol.image != null
? NetworkImage(rol.image)
: AssetImage('assets/img/enchufe.jpg'),
fit: BoxFit.contain,
fadeInDuration: Duration(milliseconds: 50),
placeholder: AssetImage('assets/img/enchufe.jpg'),
),
),
SizedBox(height: 15),
Text(
rol.name ?? '',
style: TextStyle(
fontSize: 16,
color: Colors.black
),
),
SizedBox(height: 25),
],
),
);
}
void refresh(){
setState(() {
});
}
}
class RolesController {
BuildContext context;
Function refresh;
User user;
SharedPref sharedPref = new SharedPref();
Future init(BuildContext context, Function refresh) async{
this.context = context;
this.refresh = refresh;
user = User.fromJson(await sharedPref.read('user'));
refresh();
}
void goToPage(String route) {
Navigator.pushNamedAndRemoveUntil( context, route, (route) => false);
}
}
using the debug mode I realized that the route arrives null

Related

How can I change the text color inside the chat bubble?

While I am typing the message it encodes it into white but when I have sent it, it turns to black which is the same with the response that I have been receiving. Kindly help me how will i change it to white.
import 'package:dialog_flowtter/dialog_flowtter.dart';
import 'package:flutter/material.dart';
import 'Messages.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'QuickTropa',
theme: ThemeData(
primaryColor: Color(0XFFf7c59f),
),
home: Home(),
);
}
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
late DialogFlowtter dialogFlowtter;
final TextEditingController _controller = TextEditingController();
List<Map<String, dynamic>> messages = [];
#override
void initState() {
DialogFlowtter.fromFile().then((instance) => dialogFlowtter = instance);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('QuickTropa'),
backgroundColor: Color(0XFF087830),
),
body: Container(
child: Column(
children: [
Expanded(child:
MessagesScreen(
messages:
messages)),
Container(
padding: EdgeInsets.symmetric(
horizontal: 14,
vertical: 8
),
color: Color(0XFF087830),
child: Row(
children: [
Expanded(child:
TextField(
controller: _controller,
style: TextStyle(color: Colors.white),
)),
IconButton(
onPressed: () {
sendMessage(_controller.text);
_controller.clear();
},
color: Colors.white ,
icon: Icon(Icons.send))
],
),
)
],
),
),
);
}
sendMessage(String text) async {
if (text.isEmpty) {
print('Message is empty');
} else {
setState(() {
addMessage(Message(
text: DialogText(text: [text])), true);
});
DetectIntentResponse response = await dialogFlowtter.detectIntent(
queryInput: QueryInput(text: TextInput(text: text)));
if (response.message == null) return;
setState(() {
addMessage(response.message!);
});
}
}
addMessage(Message message, [bool isUserMessage = false]) {
messages.add({
'message': message,
'isUserMessage': isUserMessage
});
}
}
import 'package:dialog_flowtter/dialog_flowtter.dart';
import 'package:flutter/material.dart';
class MessagesScreen extends StatefulWidget {
final List messages;
const MessagesScreen({Key? key, required this.messages}) : super(key: key);
#override
State<MessagesScreen> createState() => _MessagesScreenState();
}
class _MessagesState extends State<MessagesScreen> {
#override
Widget build(BuildContext context) {
return const Placeholder();
}
}
class _MessagesScreenState extends State<MessagesScreen> {
#override
Widget build(BuildContext context) {
var w = MediaQuery.of(context).size.width;
return ListView.separated(
itemBuilder: (context, index) {
return Container(
margin: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: widget.messages[index]['isUserMessage']
? MainAxisAlignment.end
: MainAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.symmetric(vertical: 14, horizontal: 14),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(
20,
),
topRight: Radius.circular(20),
bottomRight: Radius.circular(
widget.messages[index]['isUserMessage'] ? 0 : 20),
topLeft: Radius.circular(
widget.messages[index]['isUserMessage'] ? 20 : 0),
),
color: widget.messages[index]['isUserMessage']
? Color(0XFF087830)
: Color(0XFF087830).withOpacity(0.8)),
constraints: BoxConstraints(maxWidth: w * 2 / 3),
child:
Text(widget.messages[index]['message'].text.text[0])),
],
),
);
},
separatorBuilder: (_, i) => Padding(padding: EdgeInsets.only(top: 10)),
itemCount: widget.messages.length);
}
}
I tried putting Color:Colors.white isnide the box decoration but of course it wouldn't let me. I can't think anymore where to put it.
Try this
Text(widget.messages[index]['message'].text.text[0],
style:TextStyle(color:Colors.white,)
)

How to Create a List of Categories using Containers

so i wanted to create a list of categories (Day-Week-Month) and i achieved it just fine using a
listView.builder but it isn't centered on the horizontal axis so i had the idea to do it with containers.
https://im3.ezgif.com/tmp/ezgif-3-aba2cbc290ae.gif
so using only containers as the gif shows when i press it stays active even if i press on another one
which is something i dont want obviously.
https://im3.ezgif.com/tmp/ezgif-3-e1e304256aaf.gif
my code :
class DWM extends StatefulWidget {
#override
_DWMState createState() => _DWMState();
}
class _DWMState extends State<DWM> {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TextDWM(
text: "Day",
),
TextDWM(
text: "Week",
),
TextDWM(
text: "Month",
),
],
),
);
}
}
class TextDWM extends StatefulWidget {
final String text;
bool isActive;
TextDWM({this.text,this.isActive = false});
#override
_TextDWMState createState() => _TextDWMState();
}
class _TextDWMState extends State<TextDWM> {
#override
Widget build(BuildContext context) {
return Column(
children: [
GestureDetector(
onTap: (){
setState(() {
widget.isActive = true;
});
},
child: Text(
widget.text,
style: TextStyle(
color: widget.isActive ? Colors.white : Colors.grey,
),
),
),
SizedBox(height: 5,),
Container(
height: 2,
width: 40,
color: widget.isActive ? Colors.deepOrange : Colors.transparent,
)
],
);
}
}
Please check out the code below to learn one of the ways this could be done. However it is advisable to use something like Inherited widget or Provider to pass data down the widget tree.
import 'package:flutter/material.dart';
final Color darkBlue = const Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
home: MyApp()));
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Flutter Demo"),
),
body: DWM(),
);
}
}
class DWM extends StatefulWidget {
#override
_DWMState createState() => _DWMState();
}
class _DWMState extends State<DWM> {
final List<String> _items = ["Day", "Week", "Month"];
List<bool> _active = []; //[true,false,false];
#override
void initState() {
super.initState();
_active = List.filled(_items.length, false);
}
void setActive(int active) {
setState(() {
_active = List.filled(_items.length, false);
_active[active] = true;
});
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: List.generate(
_items.length,
(index) => TextDWM(
text: _items[index],
isActive: _active[index],
setActive: () => setActive(index),
),
),
),
);
}
}
class TextDWM extends StatelessWidget {
final String text;
final bool isActive;
final Function setActive;
const TextDWM({this.text, this.isActive, this.setActive});
#override
Widget build(BuildContext context) {
return Column(
children: [
GestureDetector(
onTap: () {
setActive();
},
child: Text(
text,
style: TextStyle(
color: isActive ? Colors.white : Colors.grey,
),
),
),
const SizedBox(
height: 5,
),
Container(
height: 2,
width: 40,
color: isActive ? Colors.deepOrange : Colors.transparent,
)
],
);
}
}

I need to go from first screen to second screen

I need to move from one screen to another. I made the transition from one class to another, but the main information of the second screen is indicated in the void main. How can I make the transition from one window to another without errors? So i need to transition from void main to void second. I'm sorry that my post has a lot of code, but help me please. Thanks in advance.
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
enum GenderList {male, female}
class MyForm extends StatefulWidget {
#override
State<StatefulWidget> createState() => Registr();
}
class Registr extends State {
final _formKey = GlobalKey<FormState>();
GenderList _gender;
bool _agreement = false;
Widget build(BuildContext context) {
return Container(padding: EdgeInsets.all(10.0), child: new Form(key: _formKey, child: new Column(children: <Widget>[
new Text('Имя пользователя:', style: TextStyle(fontSize: 20.0),),
new TextFormField(validator: (value){
if (value.isEmpty) return 'Пожалуйста введите свое имя';
}),
new SizedBox(height: 20.0),
new Text('Контактный E-mail:', style: TextStyle(fontSize: 20.0),),
new TextFormField(validator: (value){
if (value.isEmpty) return 'Пожалуйста введите свой Email';
String p = "[a-zA-Z0-9+.\_\%-+]{1,256}#[a-zA-Z0-9][a-zA-Z0-9-]{0,64}(.[a-zA-Z0-9][a-zA-Z0-9-]{0,25})+";
RegExp regExp = new RegExp(p);
if (regExp.hasMatch(value)) return null;
return 'Это не E-mail';
}),
new SizedBox(height: 20.0),
new Text('Ваш пол:', style: TextStyle(fontSize: 20.0),),
Row(children: [Expanded(child:RadioListTile(
title: const Text('Мужской'),
value: GenderList.male,
groupValue: _gender,
onChanged: (GenderList value) {setState(() { _gender = value;});},
),
),
Expanded(child: RadioListTile(title: const Text('Женский'),
value: GenderList.female,
groupValue: _gender,
onChanged: (GenderList value ){setState(() {_gender=value;
});}))
],
),
Column(children: <Widget>[(SizedBox(height: 95.0)),
Align(alignment:Alignment.bottomCenter ,
child: CheckboxListTile(
value: _agreement,
title: new Text('Я ознакомлен'+(_gender==null?'(а)':_gender==GenderList.male?'':'а')+' с документом "Согласие на обработку персональных данных" и даю согласие на обработку моих персональных данных в соответствии с требованиями "Федерального закона О персональных данных № 152-ФЗ".'),
onChanged: (bool value) => setState(() => _agreement = value),
),
),
SizedBox(height: 20.0),
RaisedButton(onPressed: (){
if(_formKey.currentState.validate()) {
Color color = Colors.red;
String text;
if (_gender == null) text = 'Выберите свой пол';
else if (_agreement == false) text = 'Необходимо принять условия соглашения';
else {text = 'Форма успешно заполнена'; color = Colors.green;}
Scaffold.of(context).showSnackBar(SnackBar(content: Text(text), backgroundColor: color,));
Navigator.push(context, MaterialPageRoute(builder: (context) => MainScreen()));
}
}, child: Text('Проверить'), color: Colors.blue, textColor: Colors.white,),],)
],)));
}
}
class NewsBoxFavourit extends StatefulWidget {
#override
State<StatefulWidget> createState() => MyFormState();
}
class MyFormState extends State {
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
}
}
class NewsBox extends StatelessWidget {
String _imageurl;
NewsBox( {String imageurl,}) {
_imageurl = imageurl;
}
#override
Widget build(BuildContext context) {
if (_imageurl != null && _imageurl != '') return new Container(
color: Colors.black12,
height: 138.0,
child: Row(children: [
Image.network(_imageurl, width: 200.0, height: 150.0, fit: BoxFit.cover,),
Expanded(child: Container(padding: EdgeInsets.all(5.0), child: Column(children: [
Text('Дата'),
TextFormField(),
Text('Бег'),
TextFormField()
]
))
),
])
);
}
}
class NewsBoxFavourit2 extends StatefulWidget {
#override
State<StatefulWidget> createState() => MyFormState2();
}
class MyFormState2 extends State {
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
}
}
class NewsBox2 extends StatelessWidget {
String _imageurl2;
NewsBox2( {String imageurl2,}) {
_imageurl2 = imageurl2;
}
#override
Widget build(BuildContext context) {
Align(alignment: Alignment.topCenter,);
if (_imageurl2 != null && _imageurl2 != '') return new Container(
color: Colors.black12,
height: 200.0,
child: Row(children: [
Image.network(_imageurl2, width: 200.0, height: 150.0, fit: BoxFit.cover,),
Expanded(child: Container(padding: EdgeInsets.all(5.0), child: Column(children: [
Text('Дата'),
TextFormField(),
Text('Отжимания'),
TextFormField()
]
))
),
])
);
}
}
class NewsBoxFavourit3 extends StatefulWidget {
#override
State<StatefulWidget> createState() => MyFormState3();
}
class MyFormState3 extends State {
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
}
}
class NewsBox3 extends StatelessWidget {
String _imageurl3;
NewsBox3( {String imageurl3,}) {
_imageurl3 = imageurl3;
}
#override
Widget build(BuildContext context) {
if (_imageurl3 != null && _imageurl3 != '') return new Container(
color: Colors.black12,
height: 200.0,
child: Row(children: [
Image.network(_imageurl3, width: 200.0, height: 150.0, fit: BoxFit.cover,),
Expanded(child: Container(padding: EdgeInsets.all(5.0), child: Column(children: [
Text('Дата'),
TextFormField(),
Text('Пресс'),
TextFormField()
]
))
),
])
);
}
}
class NewsBoxFavourit4 extends StatefulWidget {
#override
State<StatefulWidget> createState() => MyFormState4();
}
class MyFormState4 extends State {
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
}
}
class NewsBox4 extends StatelessWidget {
String _imageurl4;
NewsBox4( {String imageurl4,}) {
_imageurl4 = imageurl4;
}
#override
Widget build(BuildContext context) {
if (_imageurl4 != null && _imageurl4 != '') return new Container(
color: Colors.black12,
height: 138.0,
child: Row(children: [
Image.network(_imageurl4, width: 200.0, height: 150.0, fit: BoxFit.cover,),
Expanded(child: Container(padding: EdgeInsets.all(5.0), child: Column(children: [
Text('Дата'),
TextFormField(),
Text('Приседания'),
TextFormField()
]
))
),
])
);
}
}
class MyFormState5 extends State {
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
}
}
class NewsBox5 extends StatelessWidget {
String _imageurl5;
NewsBox5( {String imageurl5,}) {
_imageurl5 = imageurl5;
}
#override
Widget build(BuildContext context) {
Alignment.bottomCenter;
if (_imageurl5 != null && _imageurl5 != '') return new Container(
color: Colors.black12,
height: 138.0,
child: Row(children: [
Image.network(_imageurl5, width: 200.0, height: 150.0, fit: BoxFit.cover,),
Expanded(child: Container(padding: EdgeInsets.all(30.0), child: Column(children: [
Text('Дата'),
TextFormField(),
Text('Прыжки'),
TextFormField()
]
))
),
])
);
}
}
class MainScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {return SizedBox(width: 100 , height: 80,
child:
RaisedButton(onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => SecondScreen()));
}, child: Text('Сформировать результаты')))
;
}
}
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {return SizedBox(width: 200 , height: 100,
child:
Scaffold(
appBar: AppBar(title: Text('Результаты')),
body: Center(child: RaisedButton(onPressed: (){
Navigator.pop(context);
}, child: Text('Назад'))),
));
}
}
void main() => runApp(MaterialApp(debugShowCheckedModeBanner: false,
home: Scaffold(appBar: PreferredSize(preferredSize: Size.fromHeight(30.0),
child: AppBar(centerTitle:true, title: Text('Форма ввода'),),),
body: MyForm(),),),);
void second() => runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(),
body:
ListView(children: [
NewsBox(
imageurl: 'https://img.rl0.ru/0e5dfa5a89802f6ae40eea1312ee89c0/c615x400i/https/news.rambler.ru/img/2019/01/25160023.223341.8124.jpeg'),
NewsBox2(imageurl2: 'https://avatars.mds.yandex.net/get-zen_doc/1873797/pub_5e3d7968f58c3b19c8d9605e_5e40115dc0c2cd2f40ec8403/scale_1200'),
NewsBox3(imageurl3: 'https://www.bodybuilding.com/images/2018/april/the-best-ab-workout-for-a-six-pack-header.jpg'),
NewsBox4(imageurl4: 'http://vlzsport.ru/wp-content/uploads/prisedanie.png'),
NewsBox4(imageurl4: 'http://vlzsport.ru/wp-content/uploads/prisedanie.png'),
MainScreen()
],) ,
drawer: Drawer(child: ListView(
children: <Widget>[SizedBox(height: 0,),
Align(alignment: Alignment.bottomLeft,),
DrawerHeader(child: new Text("Меню"),
decoration: BoxDecoration (
color: Colors.blueAccent), ),
SizedBox(height: 10,),
Align(alignment: Alignment.topLeft,),
ListTile(
title: Text("Программа"),
trailing: Icon(Icons.arrow_forward_ios),
),
ListTile(
title: Text("Настройки"),
trailing: Icon(Icons.arrow_back_ios),
),
ListTile(title: Text('Результаты'),
trailing: Icon(Icons.arrow_back_ios,),
),
],
),),
)
)
);
You should have runApp() only once , to return a widget that will be the entry point for your app. After that you can go from one screen to another using Navigator.push() .
Please refer to this link that explains everything in detail :
https://flutter.dev/docs/cookbook/navigation/navigation-basics
I didn't actually went through your code because it is too bloated with irrelevant content. However, to pass data between one screen to another and vice-versa you just need to:
final bar = await Navigator.pushNamed(MyScreen2, arguments: foo);
Now on the MyScreen2 you can get your data on didChangeDependencies for example as such:
final data = ModalRoute.of(context).settings.arguments;
If you want to pass back data from MyScreen2 to the previous one when the route is popped, just do Navigator.pop(context, data); and that data will be assigned to the bar property above.

how to call the method in provider inside the build method in flutter?

i have a method in the class which extends changeNotifier which gets the data from API. now I want to call this method whenever page is opened in the build method but when I call that method it is repeatedly called because of the notifyListeners method. I want to know how to call method only once.
ReportProvider.dart
class ReportProvider extends ChangeNotifier
{
static DateFormat dateFormat = new DateFormat('dd-MM-yyyy');
static DateFormat actualDateFormat = new DateFormat("yyyy-MM-dd");
String _toDate = dateFormat.format(new DateTime.now());
String _actualToDate = actualDateFormat.format(new DateTime.now());
String _actualFromDate = actualDateFormat.format(new DateTime.now().subtract(new Duration(days: 7)));
String _fromDate = dateFormat.format(new DateTime.now().subtract(new Duration(days: 7)));
bool _progressStatuc = false;
bool _chartVisible = true;
bool _errorVisible = false;
String _errorMessage;
String get errorMessage => _errorMessage;
bool get errorVisible => _errorVisible;
bool get chartVisible => _chartVisible;
bool get progressStatus => _progressStatuc;
String get toDate => _toDate;
String get fromDate => _fromDate;
List<PieData> _data = new List();
List<PieData> get data => _data;
Future<void> getReportData() async
{
Map<String,dynamic> sessiondata = await new Utilities().getSessionData();
int shopid = sessiondata['shopid'];
Map<String,String> reportData = new Map();
reportData['shopid'] = shopid.toString();
reportData["fromdate"] = _actualFromDate;
reportData["todate"] = _actualToDate;
String token = await new Utilities().getToken();
Map userHeader = {"token": token};
print(reportData.toString());
if(await new Utilities().checkInternet())
{
try
{
http.Response response = await http.post(EndPointUrl.report,body: reportData,headers: userHeader);
String message = json.decode(response.body)['message'];
List<ReportData> data = json.decode(response.body)['data'];
data.forEach((reportData){
_data.add(new PieData(reportData.menuname,reportData.itemcount));
});
notifyListeners();
}
catch(error)
{
_errorMessage = "Server error";
notifyListeners();
}
}
else
{
_progressStatuc = false;
_chartVisible = false;
_errorVisible = true;
_errorMessage = "No Internet Connection";
notifyListeners();
}
}
}
Report.dart
class Report extends StatefulWidget
{
#override
State<StatefulWidget> createState() {
return ReportState();
}
}
class ReportState extends State<Report>
{
#override
Widget build(BuildContext context) {
final reportProvider = Provider.of<ReportProvider>(context);
reportProvider.getReportData();
//yprint(reportProvider.data.toString());
if(reportProvider.errorMessage != null && reportProvider.errorMessage.contains("Internet"))
{
showDialog(
context: context,
builder: (BuildContext context){
return AlertDialog(
title: Text("Error"),
content: Text("${reportProvider.errorMessage}"),
actions: <Widget>[
FlatButton(
child: Text("ok"),
onPressed: (){
Navigator.pop(context);
},
)
],
);
});
}
return Stack(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(8, MediaQuery.of(context).size.height*0.05,0, 0),
child: Text(
"Report",
style: TextStyle(fontSize: 28,color: Colors.black),
),
),
Row(
children: <Widget>[
Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.fromLTRB(8, 8, 0, 0),
child: GestureDetector(
onTap: (){
reportProvider.selectDate(context, "fromdate");
},
child: Text(
"${reportProvider.fromDate}",
style: TextStyle(color: Colors.black,fontSize: 16),
),
),
),
),
Expanded(
flex: 1,
child: Text(
"To",
style: TextStyle(fontSize: 16,color: Colors.grey),
),
),
Expanded(
flex: 3,
child: GestureDetector(
onTap: (){
reportProvider.selectDate(context, "todate");
},
child: Text(
"${reportProvider.toDate}",
style: TextStyle(color: Colors.black,fontSize: 16),
),
),
),
Expanded(
flex: 1,
child: GestureDetector(
onTap: (){},
child: Icon(
Icons.check,
color: Theme.of(context).accentColor,
),
),
)
],
),
// Visibility(
// visible: reportProvider.chartVisible,
// child: charts.PieChart<PieData>(
// ),
// ),
Expanded(
child: Visibility(
visible: reportProvider.errorVisible,
child: Container(
alignment: Alignment.center,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SvgPicture.asset('assets/images/undraw_report.svg',width: MediaQuery.of(context).size.width,height: MediaQuery.of(context).size.height*0.40),
Text(
"No Reports are available",
style: TextStyle(color: Colors.black,fontSize: 20),
)
],
),
),
),
)
],
),
],
);
}
}
As per the documentation, build() method is going to be called every time something changes. If you want calls to be triggered just once, you could use initState() method and add some helpers methods to update the UI. An example can be found here: https://flutter.dev/docs/get-started/flutter-for/android-devs#what-is-the-equivalent-of-runonuithread-in-flutter
Example for async loading from the previous link, special attention to loadData method:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(SampleApp());
}
class SampleApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sample App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SampleAppPage(),
);
}
}
class SampleAppPage extends StatefulWidget {
SampleAppPage({Key key}) : super(key: key);
#override
_SampleAppPageState createState() => _SampleAppPageState();
}
class _SampleAppPageState extends State<SampleAppPage> {
List widgets = [];
#override
void initState() {
super.initState();
loadData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Sample App"),
),
body: ListView.builder(
itemCount: widgets.length,
itemBuilder: (BuildContext context, int position) {
return getRow(position);
},
),
);
}
Widget getRow(int i) {
return Padding(
padding: EdgeInsets.all(10.0),
child: Text("Row ${widgets[i]["title"]}"),
);
}
Future<void> loadData() async {
String dataURL = "https://jsonplaceholder.typicode.com/posts";
http.Response response = await http.get(dataURL);
setState(() {
widgets = json.decode(response.body);
});
}
}

Flutter call setState() to update UI in another class

I am trying to call a setState when a button is pressed so the ui can show the new list but even using functions i cant use setState or it will give me the error saying im calling setState inside a constructor.
This is my code for the statlessWidget:
class _MessageCard extends StatelessWidget {
final Mensagem message;
final int messageLenght;
final List<Mensagem> messageList;
var i;
_MessageCard(
{#required this.message,
#required this.messageLenght,
#required this.messageList});
#override
Widget build(BuildContext context) {
return Center(
child: Container(
width: 600,
child: InkWell(
child: Container(
width: 900,
color: Colors.grey[200],
child: Padding(
padding: const EdgeInsets.fromLTRB(12, 0, 12, 0),
child: Center(
child: Container(
width: 600,
child: Column(
children: <Widget>[
ListTile(
leading: CircleAvatar(
child: Icon(
Icons.notifications,
color: Colors.red[400],
),
backgroundColor: Colors.grey[200],
),
title: Text(
(this.message.vDescricao ?? '').trim(),
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
),
subtitle: Text(
(this.message.vData ?? '').trim() +
' ' +
(this.message.vHora ?? '').trim(),
style: TextStyle(
color: Colors.red[400],
fontSize: 13,
),
),
trailing: FlatButton(
child: Text(
Translations.of(context)
.trans('finishmessageshort'),
),
onPressed: () => _showDeleteAlertMessage(
this.message.vNumero, context)),
),
Divider(
color: Colors.black54,
),
],
),
),
),
),
),
),
));
}
Future _showDeleteAlertMessage(String id, BuildContext context) {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text(
Translations.of(context).trans('finishmessage') + '?',
),
actions: <Widget>[
FlatButton(
child: new Text(
Translations.of(context).trans('closealert'),
),
onPressed: () {
Navigator.of(context).pop();
}),
FlatButton(
child: new Text(("Ok")),
onPressed: () =>
{_deleteMessage(id), Navigator.of(context).pop()},
)
],
);
});
}
_deleteMessage(String id) async {
for (i = 0; i < this.messageLenght; i++) {
if (this.messageList[0].vNumero == this.message.vNumero) {
this.messageList.removeAt(i);
_HomePageState().mensagemRepo.confirmMessage(this.message.vNumero);
await _HomePageState()._getMessages();
return this.messageList;
}
}
}
}
And this is my _getMessages()
_getMessages() async {
setState(() {
_loading = true;
_errorMsg = '';
});
try {
_messages = await mensagemRepo.getMessages();
print('loaded messages: ${_messages?.length}');
} catch (e) {
_errorMsg = e.toString();
}
setState(() {
_loading = false;
});
}
How can i make it so i can use this setState?
Thank you for your time and attention
Edit: Now updates List but not UI, because im not able to set HomePage state from MessageCard
You can only use setState in a StatefulWidget.
class MessageCard extends StatefulWidget {
#override
_MessageCardState createState() => _MessageCardState();
}
class _MessageCardState extends State<MessageCard> {
#override
Widget build(BuildContext context) {
// your build method here
}
}
Well, you can't set value for something that doesn't exist. Stateless by name itself makes it clear that it can't hold any state. Changing the widget to a stateful widget would work.
Stateless widget can not change the state once its rendered. To use setState and re-render the widget StatefulWidget is used.
Just change your MessageCard from Stateless Widget to StatefulWidget
class MessageCard extends StatefulWidget {
final Mensagem message;
final int messageLenght;
final List<Mensagem> messageList;
var i;
MessageCard(
{#required this.message,
#required this.messageLenght,
#required this.messageList});
#override
_MessageCardState createState() => _MessageCardState();
}
class _MessageCardState extends State<MessageCard> {
#override
Widget build(BuildContext context) {
// your build method here
}
}
Also, now "to use your MessageCard properties" like message, messageLenght, messageList, in _MessageCardState you have to use a property like widget.message, widget.messageList and widget.messageLenght respectively.
can this work to refresh the ui?
_getMessages() async {
_HomePageState()._messages = await mensagemRepo.getMessages();
print('loaded messages: ${_messages?.length}');
setState(() {
_HomePageState()._messagesList();
});
}
The code for _messagesList() is:
SliverChildBuilderDelegate _messagesList() {
int count() {
if (_errorMsg != '')
return 1;
else
return _messages == null ? 0 : _messages.length;
}
return SliverChildBuilderDelegate(
(BuildContext context, int index) {
print("i: $index");
if (_errorMsg != '') {
return Padding(
padding: EdgeInsets.all(20),
child: ErrorMessage(
error: _errorMsg,
),
);
} else {
return _MessageCard(
message: this._messages[index],
messageLength: this._messages.length,
messageList: this._messages);
}
},
childCount: count(),
);
}
I managed to make it work, by making both classes into one and calling a function to draw the messagecards, thank you all for your help and attention

Categories

Resources