I did an app and I have a problem, I runned the app on ios and android but one screen is not like I want, all my child in SizedBox are not full displayed (only on IOS), I think it is a problem with Sizedbox in IOS but I have no Idea how to resolve it.
I try to use other widget but no one works.
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
body: StreamBuilder(
stream: Firestore.instance
.collection('rooms')
.document(pincode)
.snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
int result =
snapshot.data['Votes'][0] - snapshot.data['Votes'][1];
if (result <= 0)
perdantID = snapshot.data['Nominés'][1];
else
perdantID = snapshot.data['Nominés'][0];
leperdant = perdantID;
if (snapshot.data['nb screen'] == 2 && gotdata == 0) {
gotdata++;
gonext(context, perdantID);
}
return Center(
child: FutureBuilder(
future: Firestore.instance
.collection('rooms')
.document(pincode)
.collection('users')
.document(perdantID)
.get(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
var prenomperdant = snapshot.data['prénom'];
return Center(
child: Column(
children: <Widget>[
SizedBox(height: 30),
Text('$prenomperdant',
style: TextStyle(fontSize: 50)),
Padding(
padding: const EdgeInsets.fromLTRB(80, 0, 0, 0),
child: Text(' $subquestion',
style: TextStyle(fontSize: 35)),
),
StreamBuilder(
stream: Firestore.instance
.collection('rooms')
.document(pincode)
.collection('users')
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
return Column(
children: <Widget>[
SizedBox(
height: 140,
child: GridView.count(
crossAxisCount: 2,
children: snapshot.data.documents.map(
(DocumentSnapshot document) {
if (document['id'] == nomines[0] ||
document['id'] == nomines[1])
return Container(
child: OvalPic(
document['photo'],
document['couleur']),
);
else
return null;
}).toList()
..removeWhere((el) => el == null)),
),
SizedBox(
height: 190,
child: GridView.count(
crossAxisCount: 2,
children: <Widget>[
ListView.builder(
physics:
NeverScrollableScrollPhysics(),
itemCount: nbvotes[0],
reverse: true,
itemBuilder:
(BuildContext context,
int index) {
return Align(
alignment: Alignment.center,
heightFactor: 0.94,
child: Image(
image: AssetImage(
'assets/images/results/green.png'),
));
},
),
ListView.builder(
physics:
NeverScrollableScrollPhysics(),
itemCount: nbvotes[1],
reverse: true,
itemBuilder:
(BuildContext context,
int index) {
return Align(
alignment: Alignment.center,
heightFactor: 0.94,
child: Image(
image: AssetImage(
'assets/images/results/green.png'),
));
},
),
],
)),
],
);
} else
return CircularProgressIndicator();
},
),
(perdantID == nameid)
? Column(
children: <Widget>[
rbutton(mygreen, 'PASSER AU DEFI', context,
perdantID, ledefi),
SizedBox(height: 5),
Text('OU'),
SizedBox(height: 5),
rbutton(mypink, 'BOIRE', context, perdantID,
legage),
],
)
: SizedBox(height: 1)
],
));
} else
return Center(child: CircularProgressIndicator());
},
),
);
} else
return Center(child: CircularProgressIndicator());
},
));
}
}
Try to use
ConstrainedBox(
constraints: const BoxConstraints(minHeight: 140),
child:GridView....,
)
instead of
SizedBox(
height: 190,
child: GridView...
)
Related
Hello so the problem i am having is the following code
return Scaffold(
body: Padding(
padding: EdgeInsets.all(20),
child: Row(
children: [
const SizedBox(width: 15),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(widget.routine.title!, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)),
SizedBox(height: 6),
Text(widget.routine.description!),
const Divider(
height: 10,
thickness: 2,
indent: 20,
endIndent: 0,
color: Colors.white,
),
FutureBuilder<List<RoutineTask>>(
future: _getRoutineTasks(widget.routine.id!),
builder: (BuildContext context, AsyncSnapshot<List<RoutineTask>> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if(snapshot.data == null) {
return Center(
child: Text("No Tasks!"),
);
} else if (snapshot.hasError) {
return Center(
child: Text("An Error has Occured: ${snapshot.error}"),
);
} else {
return ListView.separated(
reverse: false,
itemCount: snapshot.data!.length,
scrollDirection: Axis.vertical,
shrinkWrap: true,
separatorBuilder: (BuildContext context, index) => const Divider(),
itemBuilder: (BuildContext context, index) {
return Container(
height: MediaQuery.of(context).size.height * 0.45,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(25)
),
child: CheckboxListTile(
value: snapshot.data![index].isComplete,
onChanged: (bool? value) {
setState(() {
snapshot.data![index].isComplete = value;
});
},
),
);
},
);
}
} else {
return Center(child: CircularProgressIndicator(),);
}
}
)
],
),
],
)),
);
is Returning the error
'package:flutter/src/rendering/viewport.dart': Failed assertion: line 1869 pos 16: 'constraints.hasBoundedWidth': is not true.
and i have no idea how to fix it, been trying every possible combination i can come up with.
Edited: This works. Try to follow this tree structure.
return Scaffold(
body: Row(
children:[
Text('ROWWWWWWWWWWW'),
Expanded(
child: Column(
children:[
Text('COLUMN'),
Expanded(
child: ListView(
children:[
Text('LISTVIEW'),
],
),
),
]
),
)
],
),
);
I have an application:
The listTile items here come from the database.
Codes:
Container(
child: Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 40),
child: Column(
children: [
SizedBox(height: 15,),
Text("Profile", style: TextStyle(fontSize: 27),),
Divider(thickness: 1, color: Colors.black,),
SizedBox(height: 5),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Solved Tests:",style: TextStyle(fontSize: 19)),
],
),
SizedBox(height: 20,),
Container(
width: double.infinity,
height: 200,
child: Expanded(
child: FutureBuilder(
future: listUpload(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
late List<String?> items;
if (snapshot.connectionState == ConnectionState.waiting) {
items = [];
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
items = snapshot.data as List<String?>;
} else {
items = [];
}
return Scrollbar(
isAlwaysShown: true,
controller: _scrollContreller,
scrollbarOrientation: ScrollbarOrientation.right,
child: ListView.builder(
controller: _scrollContreller,
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(bottom: 20, left: 10, right: 10),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10),
),
child: ListTile(
title: Text(
items[index].toString(),
style: TextStyle(fontSize: 20),
),
),
),
);
},
),
);
})),
),
Calling items from database:
dynamic listUpload() async {
final prefences = await SharedPreferences.getInstance();
final getTests = prefences.getStringList("tests"); // get item
debugPrint(getTests.toString());
return Future.value(getTests);
}
If there is no data in the database, I want the listTile to say "not found" in its footprint.
For example, I want to make the system in the picture above. You already understand the system, if there is no data from the database, listTile will say not found in its place.
The listTile in my app looks like this when there is no data:
How can I do that? Thanks in advance for the help.
I think you can just have a check for empty data.
if (!snapshot.hasData){
return myEmptyWidget
}
please try:
items.isEmpty ? const SizedBox() : View(),
Code:
Container(
child: Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 40),
child: Column(
children: [
SizedBox(height: 15,),
Text("Profile", style: TextStyle(fontSize: 27),),
Divider(thickness: 1, color: Colors.black,),
SizedBox(height: 5),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Solved Tests:",style: TextStyle(fontSize: 19)),
],
),
SizedBox(height: 20,),
Container(
width: double.infinity,
height: 200,
child: Expanded(
child: FutureBuilder(
future: listUpload(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
late List<String?> items;
if (snapshot.connectionState == ConnectionState.waiting) {
items = [];
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
items = snapshot.data as List<String?>;
} else {
items = [];
}
return Scrollbar(
isAlwaysShown: true,
controller: _scrollContreller,
scrollbarOrientation: ScrollbarOrientation.right,
child: items.isEmpty ? const SizedBox() : ListView.builder(
controller: _scrollContreller,
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(bottom: 20, left: 10, right: 10),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10),
),
child: ListTile(
title: Text(
items[index].toString(),
style: TextStyle(fontSize: 20),
),
),
),
);
},
),
);
})),
),
You're facing this issue because you're not fully using the power of the FutureBuilder !
It'll "emit" states during Load and Success/Error. Whenever a state is emitted, it'll redraw the widget.
Therefore, you can return a Widget matching every state of your FutureBuilder like this
...
child: FutureBuilder(
future: listUpload(),
builder:
(BuildContext context, AsyncSnapshot snapshot) {
late List<String?> items;
if (snapshot.connectionState ==
ConnectionState.waiting) {
return YourLoaderWidget();
} else if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
items = snapshot.data as List<String?>;
if (items.isEmpty) {
return YourEmptyWidget();
} else {
return YourScrollBar();
}
} else {
return YourErrorWidget();
}
...
body: Consumer(
builder: (context, TransactionProvider provider, Widget child) {
return ListView.builder(
itemCount: 4, //จำนวนเมนูช่อง 4
itemBuilder: (context, int index) {
return Card(
elevation: 6,
margin: const EdgeInsets.all(10),
child: ListTile(
//leading: CircleAvatar(
//child: FittedBox
//child: Text("500"),),
title: Text('menu'),
subtitle: Text('1235'),
),
);
});
}
));
}
}
In this application, I'm using TabBar to divide content into categories. Information of each content is coming from a local database. For listing items from that local database to screen, I'm using FutureBuilder and calling some database helpers to fetch data in the future.
As you can see in the screenshot, I have 6 different tabs on top, and in each tab have fetched data with FutureBuilder. (This was what should normally happen.)
I did not encounter with any debug error but only the first FutureBuilder lists the data to the screen. The second tab is not showing anything. (And also the other tabs have the same issue but I just put a placeholder to make code shorter).
Here is the code:
import 'package:cascade_travel_guide/data/database_helper.dart';
import 'package:cascade_travel_guide/model/Categories.dart';
import 'package:cascade_travel_guide/model/HistoricalPlaces.dart';
import 'package:cascade_travel_guide/model/Parks.dart';
import 'package:flutter/material.dart';
class CategoryScreen extends StatefulWidget {
final townid;
CategoryScreen({Key key, this.townid}) : super(key: key);
#override
_CategoryScreenState createState() => _CategoryScreenState(townid: this.townid);
}
class _CategoryScreenState extends State<CategoryScreen> with TickerProviderStateMixin {
var townid;
_CategoryScreenState({this.townid});
var dbHelper = DbHelper();
ScrollController _scrollController;
TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(length: 6, vsync: this);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).canvasColor,
body: CustomScrollView(
physics: NeverScrollableScrollPhysics(),
controller: _scrollController,
slivers: <Widget>[
SliverAppBar(
bottom: PreferredSize(
child: Container(),
preferredSize: Size(0, 110),
),
pinned: true,
automaticallyImplyLeading: false,
primary: false,
flexibleSpace: Stack(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Image.network(
"https://i.pinimg.com/originals/6b/47/b9/6b47b97543abed38a12d8c2b4643e870.jpg",
fit: BoxFit.cover,
),
),
Positioned(
child: Column(
children: [
TabBar(
controller: _tabController,
isScrollable: true,
labelColor: Colors.white,
labelPadding: EdgeInsets.symmetric(horizontal: 15),
tabs: [
Tab(text: "Historical Places"),
Tab(text: "Parks"),
Tab(text: "Shopping Malls"),
Tab(text: "Restaurants"),
Tab(text: "Hospitals"),
Tab(text: "Police Stations"),
]),
Container(
decoration: BoxDecoration(
color: Theme.of(context).canvasColor,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(40),
topRight: Radius.circular(40),
),
),
),
],
),
bottom: -1,
left: 0,
right: 0,
),
],
),
),
SliverFillRemaining(
child: Container(
child: TabBarView(
controller: _tabController,
children: [
FutureBuilder<List<Categories>>(
future: dbHelper.getCategories(townid),
builder: (context, snapshot) {
if (snapshot.hasData) {
List catid = [];
for (int i = 0; i < snapshot.data.length; i++) {
if (catid.length < snapshot.data.length)
catid.add(snapshot.data[i].categoriesId);
}
print(catid);
return Container(
child: FutureBuilder<List<HistoricalPlaces>>(
future: dbHelper.getHist(catid[0]),
builder: (context, snapshot) {
if (snapshot.hasData)
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(
"${snapshot.data[index].histName}"),
leading: CircleAvatar(),
);
});
else
return Center(
child: CircularProgressIndicator());
}),
);
} else
return Center(
child: CircularProgressIndicator(),
);
}),
FutureBuilder<List<Categories>>(
future: dbHelper.getCategories(townid),
builder: (context, snapshot) {
if (snapshot.hasData) {
List catid = [];
for (int i = 0; i < snapshot.data.length; i++) {
if (catid.length < snapshot.data.length)
catid.add(snapshot.data[i].categoriesId);
}
print(catid);
return Container(
child: FutureBuilder<List<Parks>>(
future: dbHelper.getPark(catid[0]),
builder: (context, snapshot) {
if (snapshot.hasData)
return ListView.builder(
padding: EdgeInsets.zero,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(
"${snapshot.data[index].parkName}"),
);
});
else
return Center(
child: CircularProgressIndicator());
}),
);
} else
return Center(
child: CircularProgressIndicator(),
);
}),
Center(
child: Text("Test"),
),
Center(
child: Text("Test"),
),
Center(
child: Text("Test"),
),
Center(
child: Text("Test"),
),
],
))),
],
),
);
}
}
P.S.: I also tried to add IndexedStack to fetch all lists together but nothing changed :(
I wanted to recreate my List UI like the one in the following Pic:
As you can see the Leading Icon in the List tile has a vertical divider to its right side and it is intersected with the bottom divider, but I'm not able to achieve that look and I'm only able to recreate this UI.
Here is the Code I'm Using:
contentBuilder: (BuildContext context) {
return Container(
child: FutureBuilder(
future: _getFoodDetails(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
print(snapshot.data);
if (snapshot.data == null) {
return Container(child: Center(child: Text("Loading...")));
} else {
return Expanded(
child: ListView.separated(
itemCount: snapshot.data.length,
separatorBuilder: (context, index) {
return Divider();
},
itemBuilder: (BuildContext context, int index) {
return ListTile(
dense: false,
leading: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.phone, color: Colors.blue),
VerticalDivider(),
],
),
title: Text(snapshot.data[index].foodTitle),
subtitle: Text(snapshot.data[index].foodQuantity),
onTap: () {},
trailing: Icon(Icons.keyboard_arrow_right,
color: Colors.yellow, size: 30.0),
);
},
),
);
}
},
),
);
}
Please suggest how can i Achieve the Desired UI Look with the Dividers proeprly intersecting with each other and remove the padding which im obtaining.
One of the solution that I can think of here is to wrap your row in IntrinsicHeight() if you are using VerticalDivider as separator in Row widget like the sample below:
IntrinsicHeight(
child: Row(
children: [
Text('Hello'),
VerticalDivider(
color: Colors.black,
thickness: 2,
),
Text('World'),
],
),
)
contentBuilder: (BuildContext context) {
return Container(
child: FutureBuilder(
future: _getFoodDetails(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
print(snapshot.data);
if (snapshot.data == null) {
return Container(child: Center(child: Text("Loading...")));
} else {
return Expanded(
child: ListView.separated(
itemCount: snapshot.data.length,
separatorBuilder: (context, index) {
return Divider();
},
itemBuilder: (BuildContext context, int index) {
return Container(
width: MediaQuery.of(context).size.width,
height: 80,
color: Colors.blue,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Icon(Icons.phone, color: Colors.blue),
Container(
width: 1,
color: Colors.white,
),
const SizedBox(
width: 10,
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Text(snapshot.data[index].foodTitle),
Text(snapshot.data[index].foodQuantity),
],
),
const Spacer(),
const Icon(Icons.keyboard_arrow_right,
color: Colors.yellow, size: 30.0),
const SizedBox(
width: 10,
),
],
),
),))}}}));
hope this will help