Text position problems with UserAccountsDrawerHeader in the Drawer in flutter - flutter

I am using a userAccountsDrawerHeader in the Drawer with a photo, username and email but I get a location or text positioning problem.
The text it shows is from the database using a future builder and it gives me a problem.
But when I test the properties of userAccountsDrawerHeader(accountName,accountEmail) using a Text widget with no data from the database, the text is located correctly, no problem there.
How can I solve that?
Your help would be greatly appreciated.
code and image::
UserAccountsDrawerHeader(
accountName:NombreCabeceraDrawer(),
accountEmail:CorreoCabeceraDrawer(),
),
class CorreoCabeceraDrawerextends StatefulWidget{return correocabeceradrawer ();}
class correocabeceradrawer extends State<CorreoCabeceraDrawer>{
Widget CorreoCabeceraDrawer(){
return Container(
child: Text(correousuario), ); }
#override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: futureServices,
builder:(context, AsyncSnapshot snapshot) {
List listainfocabeceradrawer = snapshot.data;
if(snapshot.hasData ) {
return Center(
child: Container(
child: ListView.builder(
itemCount: listainfocabeceradrawer.length,
itemBuilder: (context,i){
correousuario = listainfocabeceradrawer[i].CorreoUsuario;
return Container(
child: CorreoCabeceraDrawer(),
); }), ),);
}else if(snapshot.hasError){
return Text("${snapshot.error}");
} return Center(
child: CircularProgressIndicator()
);
}
),
);
throw UnimplementedError();
}}
enter image description here
enter image description here
enter image description here

if we think simple is this code work with your code?
UserAccountsDrawerHeader(
accountName:NombreCabeceraDrawer(),
accountEmail:CorreoCabeceraDrawer(),
),
class CorreoCabeceraDrawerextends StatefulWidget{return correocabeceradrawer ();}
class correocabeceradrawer extends State<CorreoCabeceraDrawer>{
Widget CorreoCabeceraDrawer(){
return Container(margin:EdgeInsets.only(top:40),
child: Text(correousuario), ); }
#override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: futureServices,
builder:(context, AsyncSnapshot snapshot) {
List listainfocabeceradrawer = snapshot.data;
if(snapshot.hasData ) {
return Center(
child: Container(
child: ListView.builder(
itemCount: listainfocabeceradrawer.length,
itemBuilder: (context,i){
correousuario = listainfocabeceradrawer[i].CorreoUsuario;
return Container(
child: CorreoCabeceraDrawer(),
); }), ),);
}else if(snapshot.hasError){
return Text("${snapshot.error}");
} return Center(
child: CircularProgressIndicator()
);
}
),
);
throw UnimplementedError();
}}

Related

Flutter how to user setState()

One of my routes shows current data which is stored in firestore database. I am calling the function to retrieve the data from firestore in the initState method. The page will show all the data which are retrieved from firestore. It works fine i.e, when the user navigates to this page (quotesPage) it shows the data. But while navigating, for some fraction of seconds it shows error that the local variable which stores the retrieved data is null. It happens for only that fraction of seconds after which it receives the data and shows the data. So when the user navigates to that page, I want to show a progress indicator untill it receive the data. here is my code,
Map<String, dynamic> userInfo = {};
Future<void> getQoutes() async {
var data = await FirebaseFirestore.instance.collection('user').doc(auth.currentUser!.uid).get();
setState(() {
userInfo = data.data() as Map<String, dynamic>;
});
}
#override
void initState() {
getQoutes();
super.initState();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Some Quotes',
),
backgroundColor: Colors.deepOrange,
),
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: ListView.builder(
itemCount: 3,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Card_fun(userInfo['quotes'][index]);
}
)
)
],
),
)
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await popUpForm();
},
),
);
I am calling the function getQuotes() from initState() which will store the data to Map variable userInfo. So how to show a progress indicator untill the variable 'userInfo' gets data ?
Can anyone help ?
This is the updated code
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Some Quotes',
),
backgroundColor: Colors.deepOrange,
),
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
FutureBuilder<void>(
future: getQoutes(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.done:
if(snapshot.hasError) {
return Text('Error : ${snapshot.error}');
}
return Expanded(
child: ListView.builder(
itemCount: 3,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Card_fun(userInfo['quotes'][index]);
}
)
);
default:
return const CircularProgressIndicator();
}
},
)
],
),
)
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await popUpForm();
},
),
);
You should try with Future builder or stream builder and here is the example with Future builder
FutureBuilder<String>(
future: getQoutes(), // async work
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting: return CircularProgressIndicator();
default:
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
else
return Expanded(
child: ListView.builder(
itemCount: 3,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Card_fun(userInfo['quotes'][index]);
}
)
);
}
},
)
For more read this article
another approach that might be worth looking at is using a addPostFrameCallback method called from your initState in which you can await the necessary condition and take appropriate action and trigger a setState.

How to extract snapshot data and save as a global variable in flutter

I don't know whether this is a dumb question or not. Pardon me if it is.
I created a streamBuilder and now I want to extract it's AsyncSnapshot and save as a global variable. Currently I only have access to that snapshot is, inside the streamBuilder widget. But I want that snapshot data to update some widgets outside that streamBuilder widget. I have added a comment to below code:
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder(
stream: _crudStorage.all(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.active:
case ConnectionState.waiting:
if (snapshot.data == null) {
return const Center(
child: CircularProgressIndicator(),
);
}
final tasksList = snapshot.data as List<Task>; //I want to extract this
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
tasksList.isEmpty
? const RiveBird()
: Expanded(
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: tasksList.length + 1,
itemBuilder: (context, index) {
if (index == tasksList.length) {
return const SizedBox(
height: 85.0,
width: double.infinity,
);
}
final task = tasksList[index];
return Dismissible();
},
),
),
],
);
default:
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}

flutter listview builder inside a listview builder

I don't have much experience with flutter.
I would like to use the language_tool library (https://pub.dev/packages/language_tool) for Dart and Flutter.
To show the data obtained from the tool() function, I created a FutureBuilder with a ListView.builder inside, which returns a Column.
I would like there to be 2 children inside the column:
1- a Text with mistake.issueDescription as text (for each "mistake")
2- another ListView that returns the elements of the List mistake.replacements for each "mistake"
Anyone know how I can fix it?
Below I put the code I created, which works fine until I put the Listview builder inside the first ListView builder.
import 'package:flutter/material.dart';
import 'package:language_tool/language_tool.dart';
void main() => runApp(mainApp());
class mainApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: Chat(),
);
}
}
class Chat extends StatefulWidget {
const Chat({Key? key}) : super(key: key);
#override
_ChatState createState() => _ChatState();
}
class _ChatState extends State<Chat> {
String text = 'Henlo i am Gabriele';
Future<List<WritingMistake>> tool(String text) async {
var tool = LanguageTool();
var result = tool.check(text);
var correction = await result;
List<WritingMistake> mistakes = [];
for (var m in correction) {
WritingMistake mistake = WritingMistake(
message: m.message,
offset: m.offset,
length: m.length,
issueType: m.issueType,
issueDescription: m.issueDescription,
replacements: m.replacements,
);
mistakes.add(mistake);
}
print(mistakes.length);
print(mistakes);
return mistakes;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
Container(
color: Colors.red,
height: 150.0,
width: double.infinity,
child: Center(
child: Text(text, style: const TextStyle(fontSize: 20.0))),
),
FutureBuilder(
future: tool(text),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return const Center(
child: Text('Loading...'),
);
} else {
return SizedBox(
height: 200.0,
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder:
(BuildContext context, int mistakeIdIndex) {
return Column(
children: [
Text(snapshot
.data[mistakeIdIndex].issueDescription),
// this is where the problems begin
ListView.builder(
itemCount: snapshot.data[mistakeIdIndex]
.replacements.length,
scrollDirection: Axis.horizontal,
itemBuilder:
(BuildContext context, int index) {
return Text(snapshot.data[mistakeIdIndex]
.replacements[index]);
}),
],
);
}),
);
}
}),
],
),
),
);
}
}
I hope I was clear and that someone can help me.
Thank you :)
You cannot give a listview-builder as a child for a column try changing the Column widget to a ListView and set its shrinkWrap property to true.
ListView(
children: [
Container(
color: Colors.red,
height: 150.0,
width: double.infinity,
child: Center(
child: Text(text, style: const TextStyle(fontSize: 20.0))),
),
FutureBuilder(
future: tool(text),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return const Center(
child: Text('Loading...'),
);
} else {
return SizedBox(
height: 200.0,
child: ListView.builder(
shrinkWrap:true,
itemCount: snapshot.data.length,
itemBuilder:
(BuildContext context, int mistakeIdIndex) {
return ListView(
shrinkWrap:true,
children: [
Text(snapshot
.data[mistakeIdIndex].issueDescription),
// this is where the problems begin
ListView.builder(
shrinkWrap:true,
itemCount: snapshot.data[mistakeIdIndex]
.replacements.length,
scrollDirection: Axis.horizontal,
itemBuilder:
(BuildContext context, int index) {
return Text(snapshot.data[mistakeIdIndex]
.replacements[index]);
}),
],
);
}),
);
}
}),
],
),
),

problems when displaying information in a ListView.builder

I am trying to show some information brought from firebase in web flutter but I have problems implementing FutureBuilder, since it does not show the information, the widget is not rendering anything the page is completely blank, attached I send the complete code of the page that is presenting the problem since I have followed all the tutorials that I have found but I can not make it show the data, in the same way I also attach the Json that returns the complement that I am using to obtain the data from firebase, I hope for the collaboration, thank you very much
Complete Code
class DriverPages extends StatefulWidget {
static final routeName = 'DriverPage';
DriverPages({Key key}) : super(key: key);
#override
_DriverPagesState createState() => _DriverPagesState();
}
DatabaseRef driverRef =
FirebaseDatabaseWeb.instance.reference().child('drivers');
class _DriverPagesState extends State<DriverPages> {
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
List prueba;
Future<List> driverItem() async {
DatabaseSnapshot snapshot = await driverRef.once();
Map<String, dynamic> json = snapshot.value;
return json.values.toList();
}
Widget driverList() {
return FutureBuilder<List>(
future: driverItem(),
builder: (contetx, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
final value = snapshot.data[index];
return ListTile(
title: Text(value['fullname']),
subtitle: Text(value['email']),
);
},
);
}
},
);
}
#override
Widget build(BuildContext context) {
if (userSnapshot != null) {
return Scaffold(
key: scaffoldKey,
drawer: Container(
width: 320,
color: Colors.white,
child: Drawer(
child: PatimovilMenu(),
),
),
body: Container(
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.symmetric(
vertical: 25,
horizontal: 30,
),
child: Column(
children: <Widget>[
PatimovilHeader(
onPressed: () {
scaffoldKey.currentState.openDrawer();
},
titlePage: 'Driver Manager',
),
Container(
width: MediaQuery.of(context).size.width,
height: (MediaQuery.of(context).size.height) - 260,
alignment: Alignment.center,
child: Center(
child: driverList(),
),
),
PatimovilFooder(),
],
),
),
);
} else {
Navigator.pushNamedAndRemoveUntil(
context,
LoginPage.routeName,
(route) => false,
);
}
}
}
This is the Json that returns the dependency I am using
{VOVQv28SU2c0GgXJKcSp8UFchPz2:
{email: bibiana206#gmail.com, fullname: bibiana, identification: e8104970, phone: 2095770, status: Waiting,
vehicle_details:
{car_brand: Ferrari, car_color: rojo, car_model: cretta, car_plate: az12}
},
dBncphEFOZbzGEt5qn44sD9BYVK2:
{email: bolivia20192019#gmail.com, fullname: Gustavo Barrios, identification: 14326048, phone: 60697350, status: Active,
vehicle_details:
{car_brand: Renault, car_color: Gris, car_model: Duster, car_plate: AY6787,}
}
}
I can't get the data to show me, it doesn't render anything
You should check the current state of the future as there are four connection states:
ConnectionState.none
ConnectionState.waiting
ConnectionState.active
ConnectionState.done
You were returning a widget only when snapshot.hasData which will occur only when the connection state is done & there are no errors.
In all other cases, your method driverList will be returning nothing.
So, update your method as follows:
Widget driverList() {
return FutureBuilder<List>(
future: driverItem(),
builder: (contetx, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Center(child: Text('Something went wrong'));
}
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
final value = snapshot.data[index];
return ListTile(
title: Text(value['fullname']),
subtitle: Text(value['email']),
);
},
);
}
}
return Center(child: CircularProgressIndicator());
},
);
}

How to fix 'Methode called on null in a streambuilder'

I'm trying to fetch data from firestore but I keep getting methode called on null error
I want it to keep showing circular progress indicator in case of an error or slow connection
class FirstTabPage extends StatelessWidget {
final CustomCard customCard = CustomCard();
#override
Widget build(BuildContext context) {
return
Padding(
padding: const EdgeInsets.all(8.0),
child: StreamBuilder(
stream: Firestore.instance.document('data/Sqprices').snapshots(),
builder: (context, snapshot){
if(!snapshot.hasData){
return Center(child: CircularProgressIndicator(backgroundColor: Colors.black,),);
} else {
return ListView(
children: <Widget>[
CustomCard(
image: Image.asset('images/elag.png',width: 40,height: 40,),
currencyName: 'EUR',
buyPrice: '${snapshot.data['price1']}',
sellPrice: '${snapshot.data['price2']}',
),
CustomCard(
image: Image.asset('images/ulag.png',width: 40,height: 40,),
currencyName: 'USD',
buyPrice: '${snapshot.data['price3']}',
sellPrice: '${snapshot.data['price4']}',
),
CustomCard(
image: Image.asset('images/klag.png',width: 40,height: 40,),
currencyName: 'GBP',
buyPrice: '${snapshot.data['price5']}',
sellPrice: '${snapshot.data['price6']}',
),
],
);
}
}
),
);
}
}
When there is internet acces the progress indicator shows for 2 seconds and then the data get displayed , but in slow internet acces it crashes saying the
the methode [] was called on null
Try with this,
builder: (context, AsyncSnapshot snapshot){
......
.....
....
}
You have checked for .hasData which ensures that data should be available in the Stream. However, the data in the Stream can also be null data. So, you should check if data equals null:
child: StreamBuilder(
stream: Firestore.instance.document('data/Sqprices').snapshots(),
builder: (context, snapshot){
if(!snapshot.hasData){
return Center(child: CircularProgressIndicator(backgroundColor: Colors.black,),);
}
if(snapshot.data == null) return Center(child: Text("No data"));
else {
return ListView(