Image not loading from firestore in flutter app - flutter

I am very new to Flutter and Firestore. So I uploaded some photos on Firebase storage.
Here is how storage looks
Then I pasted their download URL into firestore database.
Here is how firestore looks
but every time I try to get them in my app I am getting the following error
════════ Exception caught by widgets library ═══════════════════════════════════
'package:flutter/src/painting/_network_image_io.dart': Failed assertion: line 26 pos 14: 'url != null': is not true.
The relevant error-causing widget was
FutureBuilder
But other data is reading and showing up in the widget.
here is my code:
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:dotted_line/dotted_line.dart';
class CourseList extends StatefulWidget {
#override
_CourseListState createState() => _CourseListState();
}
class _CourseListState extends State<CourseList> {
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: FirebaseFirestore.instance
.collection('students')
.doc(FirebaseAuth.instance.currentUser.uid)
.get(),
builder: (BuildContext context, snapshot) {
if (snapshot.hasData) {
Map<String, dynamic> documentFields = snapshot.data.data();
return ListView(
shrinkWrap: true,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
overflow: Overflow.visible,
children: [
Positioned(
// top: 0,
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
child: Container(
width: 430,
height: 230,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/hero.png"),
fit: BoxFit.cover,
),
),
),
),
),
Positioned(
top: 200,
left: 20,
right: 20,
child: Card(
color: Hexcolor('#3B3E43'),
elevation: 10,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: const EdgeInsets.all(15),
child: Column(
children: [
Text(
'Welcome to Class Information System',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontFamily: 'ProductSans',
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 10,
),
Text(
'UTM Class Management system offers UTM students a varity of features such as, managing and making real time class schedule, finding class venue with dynamic maps and finding all the lecturers office, phone and email all at one place!',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.grey[300],
fontFamily: 'ProductSans',
fontSize: 11,
),
),
SizedBox(
height: 15,
),
Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
Image.asset(
'assets/001-school.png',
scale: 8,
),
SizedBox(
width: 0,
),
Image.asset(
'assets/002-teacher.png',
scale: 8,
),
SizedBox(
width: 0,
),
Image.asset(
'assets/003-calendar.png',
scale: 8,
),
],
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
Text(
'Finding class\nvenue with\ndynamic maps',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.grey[300],
fontFamily: 'ProductSans',
fontSize: 10,
),
),
Text(
'Finding all the\nlecturers informations\nat one place!',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.grey[300],
fontFamily: 'ProductSans',
fontSize: 10,
),
),
Text(
'Make & Edit\nreal time\nclass schedule',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.grey[300],
fontFamily: 'ProductSans',
fontSize: 10,
),
),
],
),
],
)
],
),
),
),
),
],
),
SizedBox(
height: 220,
),
Padding(
padding: const EdgeInsets.fromLTRB(25, 10, 0, 0),
child: Text(
'Courses Taken',
textAlign: TextAlign.left,
style: TextStyle(
color: Hexcolor('#E69405'),
fontFamily: 'ProductSans',
fontSize: 18,
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(25, 10, 25, 5),
child: DottedLine(
direction: Axis.horizontal,
lineLength: double.infinity,
lineThickness: 1.0,
dashLength: 4.0,
dashColor: Hexcolor('#707070'),
dashRadius: 0.0,
dashGapLength: 6.0,
dashGapColor: Colors.transparent,
dashGapRadius: 0.0,
),
),
SizedBox(
height: 15,
),
Card(
color: Hexcolor('#3B3E43'),
elevation: 10,
margin: EdgeInsets.fromLTRB(25, 0, 25, 20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: const EdgeInsets.all(15),
child: ListView(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
children: [
Row(
children: [
Expanded(
child: Padding(
padding:
const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: CircleAvatar(
backgroundImage:
NetworkImage(documentFields['img1']),
radius: 28,
),
),
),
Expanded(
flex: 4,
child: Padding(
padding:
const EdgeInsets.fromLTRB(20, 0, 0, 0),
child: RichText(
text: TextSpan(
style: TextStyle(
fontFamily: 'ProductSans',
fontSize: 17,
),
text: documentFields['course1'],
children: <TextSpan>[
TextSpan(
text:
'\nSection: ${documentFields['section1']}',
style: TextStyle(
fontFamily: 'ProductSans',
fontSize: 14,
color: Colors.grey[400],
),
),
],
),
),
),
),
],
),
SizedBox(
height: 15,
),
DottedLine(
direction: Axis.horizontal,
lineLength: double.infinity,
lineThickness: 1.0,
dashLength: 10,
dashColor: Hexcolor('#707070'),
dashRadius: 0.0,
dashGapLength: 0,
dashGapColor: Colors.transparent,
dashGapRadius: 0.0,
),
SizedBox(
height: 15,
),
Row(
children: [
Expanded(
child: Padding(
padding:
const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: CircleAvatar(
child: Image.network(
'${documentFields['img2']}'),
radius: 28,
),
),
),
Expanded(
flex: 4,
child: Padding(
padding:
const EdgeInsets.fromLTRB(20, 0, 0, 0),
child: RichText(
text: TextSpan(
style: TextStyle(
fontFamily: 'ProductSans',
fontSize: 17,
),
text: documentFields['course2'],
children: <TextSpan>[
TextSpan(
text:
'\nSection: ${documentFields['section2']}',
style: TextStyle(
fontFamily: 'ProductSans',
fontSize: 14,
color: Colors.grey[400],
),
),
],
),
),
),
),
],
),
SizedBox(
height: 15,
),
DottedLine(
direction: Axis.horizontal,
lineLength: double.infinity,
lineThickness: 1.0,
dashLength: 10,
dashColor: Hexcolor('#707070'),
dashRadius: 0.0,
dashGapLength: 0,
dashGapColor: Colors.transparent,
dashGapRadius: 0.0,
),
SizedBox(
height: 15,
),
Row(
children: [
Expanded(
child: Padding(
padding:
const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: CircleAvatar(
child: Image.network(
'${documentFields['img3']}'),
radius: 28,
),
),
),
Expanded(
flex: 4,
child: Padding(
padding:
const EdgeInsets.fromLTRB(20, 0, 0, 0),
child: RichText(
text: TextSpan(
style: TextStyle(
fontFamily: 'ProductSans',
fontSize: 17,
),
text: documentFields['course3'],
children: <TextSpan>[
TextSpan(
text:
'\nSection: ${documentFields['section3']}',
style: TextStyle(
fontFamily: 'ProductSans',
fontSize: 14,
color: Colors.grey[400],
),
),
],
),
),
),
),
],
),
SizedBox(
height: 15,
),
DottedLine(
direction: Axis.horizontal,
lineLength: double.infinity,
lineThickness: 1.0,
dashLength: 10,
dashColor: Hexcolor('#707070'),
dashRadius: 0.0,
dashGapLength: 0,
dashGapColor: Colors.transparent,
dashGapRadius: 0.0,
),
SizedBox(
height: 15,
),
Row(
children: [
Expanded(
child: Padding(
padding:
const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: CircleAvatar(
child: Image.network(
'${documentFields['img4']}'),
radius: 28,
),
),
),
Expanded(
flex: 4,
child: Padding(
padding:
const EdgeInsets.fromLTRB(20, 0, 0, 0),
child: RichText(
text: TextSpan(
style: TextStyle(
fontFamily: 'ProductSans',
fontSize: 17,
),
text: documentFields['course4'],
children: <TextSpan>[
TextSpan(
text:
'\nSection: ${documentFields['section4']}',
style: TextStyle(
fontFamily: 'ProductSans',
fontSize: 14,
color: Colors.grey[400],
),
),
],
),
),
),
),
],
),
],
),
),
)
],
),
],
);
}
return Center(child: CircularProgressIndicator());
},
);
}
}
Any help will be really appreciated. Thanks!

So, I finally figured it out. If any one is looking for an answer. All you have to do is, after storing the image in firebase storage you have to copy the storage location not the download URL, then put it inside firestore. Then use firebase image provider package to call it in your app
child: ListTile(
leading: CircleAvatar(
radius: 25,
backgroundImage: FirebaseImage(coffee.img),
),

Try to print the image URL in the console to make sure of its value.
The error is saying that its value is null so you might have not written the key Map key of the image URL correctly.

Related

Flutter : call getData function only when I click on expansion tile

I have a complex UI , am displaying a listViewbuilder composed of many expansion tiles.
At first , I retrieve the list of data show it , then I call on another function to which I give the id of my object to display details when I click on the expansion tile . The only problem here , is that the code complexity is too high , say we have 20 items in the list every time I call the function that returns the details of my item using futurebuilder or provider it will call the function 20 times even though I didn't click on the expansion tile to view the details. I want to be able to call my future function only when I click on the expansion tile.
this is my view :
enter image description here
and this is my code using provider and future builder
child: FutureBuilder(
future: futureQrqc,
builder: (BuildContext context,
AsyncSnapshot<QrqcDetails?> snapshot) {
if (snapshot.hasData) {
String? backgroundImage;
String? _setImage() {
String _mTitle = "${snapshot.data!.type}";
if(_mTitle == "Delivery") {
backgroundImage = "assets/icons/delivery.png";
} else if(_mTitle == "Security") {
backgroundImage = "assets/icons/security.png";
}
else if(_mTitle == "Quality") {
backgroundImage = "assets/icons/quality.png";
}
else if(_mTitle == "Cost") {
backgroundImage = "assets/icons/Cost.png";
}
else if(_mTitle == "People") {
backgroundImage = "assets/icons/people.png";
}
print("_mTitle: $_mTitle");
print("_mTitle: $backgroundImage");
return backgroundImage; // here it returns your _backgroundImage value
}
return Column(
children: [
ConditionalBuilder(
condition: myQrqcListViewModel
.articlesList[index].status ==
'INIT',
builder: (context) => Container(
// ignore: prefer_const_constructors
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(20)),
),
foregroundDecoration:
const RotatedCornerDecoration(
color: Colors.orange,
geometry: BadgeGeometry(
width: 40,
height: 40,
cornerRadius: 16),
textSpan: TextSpan(
text: 'INIT',
style: TextStyle(
fontSize: 10,
letterSpacing: 1,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
child: ExpansionTile(
title: Text(
myQrqcListViewModel
.articlesList[index].id
.toString(),
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black),
),
leading: QrqcCardLeaing(
imgPath: _setImage(),
),
subtitle: Text(myQrqcListViewModel
.articlesList[index].title),
trailing: QrqcCardtrailing(percent: myQrqcListViewModel
.articlesList[index]
.progress
.toString(),text: myQrqcListViewModel
.articlesList[index]
.progress
.toString(),),
children: [
QrqcDetailsCardFirstRow(product: snapshot.data?.product?? "No product" ,role: myQrqcListViewModel
.articlesList[index].role, ),
const SizedBox(height: 10),
Row(
children: [
Expanded(
child: Image.asset(
"assets/icons/location.png",
width: 20,
height: 20,
),
),
Expanded(
child: Text(
snapshot.data!.perimeter,
style: TextStyle(fontSize: 10),
)),
const SizedBox(width: 50),
Expanded(
child: Image.asset(
"assets/icons/calendar.png",
width: 20,
height: 20,
),
),
Expanded(
child: Text(
convertDateTimeDisplay(snapshot.data!.creation_date),
style: TextStyle(fontSize: 10),
)),
],
),
const SizedBox(height: 10),
],
),
),
fallback: null,
),
ConditionalBuilder(
condition: myQrqcListViewModel
.articlesList[index].status ==
'SUBMITTED',
builder: (context) => Container(
// ignore: prefer_const_constructors
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(20)),
),
foregroundDecoration:
const RotatedCornerDecoration(
color: Colors.blueAccent,
geometry: BadgeGeometry(
width: 40,
height: 40,
cornerRadius: 16),
textSpan: TextSpan(
text: 'SUB',
style: TextStyle(
fontSize: 10,
letterSpacing: 1,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
child: ExpansionTile(
leading: QrqcCardLeaing(
imgPath: _setImage(),
),
title: Text(
myQrqcListViewModel
.articlesList[index].id
.toString(),
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black),
),
subtitle: Text(myQrqcListViewModel
.articlesList[index].title),
trailing: Column(
children: [
Expanded(
child: CircularPercentIndicator(
radius: 20.0,
lineWidth: 2.0,
percent: double.parse(
myQrqcListViewModel
.articlesList[index]
.progress
.toString()) /
100,
center: Text(
myQrqcListViewModel
.articlesList[index]
.progress
.toString(),
style: const TextStyle(
fontSize: 10),
),
progressColor: kPrimaryColor,
)),
],
),
children: [
Row(
children: [
Expanded(
child: Image.asset(
"assets/icons/user.png",
width: 20,
height: 20,
),
),
Expanded(
child: Text(
myQrqcListViewModel
.articlesList[index].role,
style: const TextStyle(
fontSize: 10),
)),
const SizedBox(width: 50),
Expanded(
child: Image.asset(
"assets/icons/product.png",
width: 20,
height: 20,
),
),
Expanded(
child: Text(
snapshot.data?.product?? "No product" ,
style: TextStyle(fontSize: 10),
)),
],
),
const SizedBox(height: 10),
Row(
children: [
Expanded(
child: Image.asset(
"assets/icons/location.png",
width: 20,
height: 20,
),
),
Expanded(
child: Text(
snapshot.data!.perimeter,
style: TextStyle(fontSize: 10),
)),
const SizedBox(width: 50),
Expanded(
child: Image.asset(
"assets/icons/calendar.png",
width: 20,
height: 20,
),
),
Expanded(
child: Text(
snapshot.data!.creation_date,
style: TextStyle(fontSize: 10),
)),
],
),
const SizedBox(height: 10),
],
),
),
fallback: null,
),
ConditionalBuilder(
condition: myQrqcListViewModel
.articlesList[index].status ==
'VALIDATED',
builder: (context) => Container(
// ignore: prefer_const_constructors
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(20)),
),
foregroundDecoration:
const RotatedCornerDecoration(
color: Colors.green,
geometry: BadgeGeometry(
width: 40,
height: 40,
cornerRadius: 16),
textSpan: TextSpan(
text: 'VALID',
style: TextStyle(
fontSize: 10,
letterSpacing: 1,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
child: ExpansionTile(
leading: QrqcCardLeaing(
imgPath: _setImage(),
),
title: Text(
myQrqcListViewModel
.articlesList[index].id
.toString(),
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black),
),
subtitle: Text(myQrqcListViewModel
.articlesList[index].title),
trailing: Column(
children: [
Expanded(
child: CircularPercentIndicator(
radius: 20.0,
lineWidth: 2.0,
percent: double.parse(
myQrqcListViewModel
.articlesList[index]
.progress
.toString()) /
100,
center: Text(
myQrqcListViewModel
.articlesList[index]
.progress
.toString(),
style: const TextStyle(
fontSize: 10),
),
progressColor: kPrimaryColor,
)),
],
),
children: [
Row(
children: [
Expanded(
child: Image.asset(
"assets/icons/user.png",
width: 20,
height: 20,
),
),
Expanded(
child: Text(
myQrqcListViewModel
.articlesList[index].role,
style: const TextStyle(
fontSize: 10),
)),
const SizedBox(width: 50),
Expanded(
child: Image.asset(
"assets/icons/product.png",
width: 20,
height: 20,
),
),
Expanded(
child: Text(
snapshot.data?.product?? "No product" ,
style: TextStyle(fontSize: 10),
)),
],
),
const SizedBox(height: 10),
Row(
children: [
Expanded(
child: Image.asset(
"assets/icons/location.png",
width: 20,
height: 20,
),
),
Expanded(
child: Text(
snapshot.data!.perimeter,
style: TextStyle(fontSize: 10),
)),
const SizedBox(width: 50),
Expanded(
child: Image.asset(
"assets/icons/calendar.png",
width: 20,
height: 20,
),
),
Expanded(
child: Text(
snapshot.data!.creation_date,
style: TextStyle(fontSize: 10),
)),
],
),
const SizedBox(height: 10),
],
),
),
fallback: null,
),
);
} else if (snapshot.hasError) {
return NoDataUI();
}
print(snapshot.error.toString());
return const Center(
child: CircularProgressIndicator());
})
If anyone can help please don't hesitate , this is an important issue to optimise my code before launching my app for users on stores . Thank you so much and happy coding :)
You can wrap your ExpansionTile with GestureDetector or InkWell and call the function in onTap method.

How can I expand this Stack Widget?

here I am face a issue in Stack Widget. When I am give height width then The scaffold is scrolled. When I am remove the height Scaffold not scrolled. But in body I give
SingleChildScrollView().
..
I hope, Here I found my solution. Thanks......................................
This is custom Container Widget:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hexcolor/hexcolor.dart';
Widget customContainerWidget({
required Widget child,
double? height,
Color? color,
BorderRadiusGeometry? borderRadius,
}) {
return Container(
// height: height,
width: Get.width,
decoration: BoxDecoration(
color: color != null ? color : HexColor('#FFE58F'),
borderRadius:
borderRadius != null ? borderRadius : BorderRadius.circular(40),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 120,
spreadRadius: .10,
offset: Offset(1, 20),
),
],
),
child: ListView(
shrinkWrap: true,
primary: false,
children: [child],
),
);
}
This is my page Widget :
import 'package:Darucheeni/src/controllers/mainController/baseController.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:Darucheeni/src/configs/appColors.dart';
import 'package:Darucheeni/src/configs/appConfigs.dart';
import 'package:Darucheeni/src/widgets/button/customBackButton.dart';
import 'package:Darucheeni/src/widgets/ConatinerWidget/customBorderContainer.dart';
import 'package:Darucheeni/src/widgets/ConatinerWidget/customContainerWidget.dart';
import 'package:Darucheeni/src/widgets/textWidget/kText.dart';
class AcceptOrderPage extends StatelessWidget with BaseController {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
sizeH20,
Container(
//height: 3000, when I am give here Height then the Screen scrolled.
width: Get.width,
child: Stack(
clipBehavior: Clip.none,
children: [
Card(
elevation: 10,
margin: EdgeInsets.all(0),
child: Container(
height: 120,
width: Get.width,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
yellow,
green,
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: Padding(
padding: EdgeInsets.only(bottom: 20, left: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
customBackButton(),
KText(
text: 'Accept Order',
fontSize: 35,
fontFamily: brushScriptFonts,
color: black,
),
Container(),
],
),
),
),
),
Positioned(
top: 100,
left: 20,
right: 20,
child: customContainerWidget(
// height: 400,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 20,
vertical: 50,
),
child: Column(
children: [
ListView.builder(
shrinkWrap: true,
primary: false,
itemCount: productOrderC.productOrderList.length,
itemBuilder: (context, index) {
final item =
productOrderC.productOrderList[index];
return Padding(
padding: EdgeInsets.only(bottom: 30),
child: customBorderContainer(
child: customOrderHistory(
// onTap: () => Get.to(OrderCheckDetailsPage(
// allOrders: item,
// )),
onTap: () {},
orderId: '${item.trackingId}',
deliveryAddress: '23/A, Mirpur-10,Dhaka',
orderTime: item.createdAt.toString(),
status: item.ordertype!.name.toString(),
),
),
);
},
),
],
),
),
),
),
],
),
),
SizedBox(height: 100),
],
),
),
);
}
Widget customOrderHistory({
required String? orderId,
required String deliveryAddress,
required String orderTime,
required String status,
required void Function()? onTap,
}) {
return Padding(
padding: EdgeInsets.symmetric(
horizontal: 20,
vertical: 20,
),
child: Column(
children: [
Row(
children: [
KText(
text: 'Order ID : ',
color: black,
fontSize: 11,
fontWeight: FontWeight.bold,
),
SizedBox(width: 10),
KText(
text: '$orderId',
fontSize: 20,
letterSpacing: 1.80,
fontWeight: FontWeight.bold,
),
],
),
sizeH20,
Row(
children: [
KText(
text: 'Delivery Address : ',
color: black,
fontSize: 11,
fontWeight: FontWeight.bold,
),
SizedBox(width: 10),
KText(
text: deliveryAddress,
fontSize: 12,
fontWeight: FontWeight.bold,
),
],
),
sizeH20,
Row(
children: [
KText(
text: 'Time : ',
color: black,
fontSize: 11,
fontWeight: FontWeight.bold,
),
SizedBox(width: 10),
KText(
text: orderTime,
fontSize: 12,
fontWeight: FontWeight.bold,
),
],
),
sizeH20,
Row(
children: [
KText(
text: 'Status : ',
color: black,
fontSize: 11,
fontWeight: FontWeight.bold,
),
SizedBox(width: 10),
KText(
text: status,
fontSize: 12,
fontWeight: FontWeight.bold,
),
Spacer(),
GestureDetector(
onTap: onTap,
child: KText(
text: 'Check Details',
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
],
),
);
}
}
Try to use
Stack(
fit: StackFit.expanded,
…
);

how to add horizontal scroll bar flutter

I'm trying to make a grocery app UI using flutter. How do I add a horizontal scroll bar to this code? suggest a proper way to do this without affecting other codes? the right side of the image shows my implementation so far. can someone please suggest to me a way to do this? also how do I add that left green box in front of search box?
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xffEDEFF4),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home,color: Colors.green ),
label: 'Home',
backgroundColor: Colors.white,
),
BottomNavigationBarItem(
icon: Icon(Icons.person,color: Colors.grey),
label: 'Profile',
// backgroundColor:Colors.blue,
),
BottomNavigationBarItem(
icon: Icon(Icons.shopping_cart,color: Colors.grey),
label: 'cart',
// backgroundColor:Colors.blue,
),
BottomNavigationBarItem(
icon: Icon(Icons.notifications ,color: Colors.grey),
label: 'bell',
// backgroundColor:Colors.blue,
),
BottomNavigationBarItem(
icon: Icon( Icons.more_horiz, color: Colors.grey),
label: 'bell',
// backgroundColor:Colors.blue,
),
]),
body: Padding(
padding: const EdgeInsets.only(top: 40, left: 20, right: 20),
child: ListView(
children: [
buildSearchInput(),
Stack(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0, 45, 10, 0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: Color(0xffFFFCEE),
),
height: 180,
width: 380,
child: Column(
children: const [
Padding(
padding: EdgeInsets.fromLTRB(0, 20, 180, 10),
child: Text(
"FRUIT AND BERRIES",
style: TextStyle(
fontFamily:'Roboto',
fontSize: 10,
color: Colors.lightGreen,
fontWeight: FontWeight.w700),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 180, 10),
child: Text(
"Tangerine",
style: TextStyle(
fontFamily:'Roboto',
fontSize: 22,
color: Colors.black,
fontWeight: FontWeight.w700),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 220, 10),
child: Text(
"Rs.0.90/kg",
style: TextStyle(
fontFamily:'Roboto',
fontSize: 12,
color: Colors.grey,
fontWeight: FontWeight.w700),
),
),
],
)
)
),
const Padding(
padding: EdgeInsets.fromLTRB(120, 0, 40, 0),
child: Image(
image: AssetImage("assets/images/banana.png"),
),
),
],
),
Stack(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0, 45, 10, 0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: Color(0xffFFFCEE),
),
height: 180,
width: 380,
child: Column(
children: const [
Padding(
padding: EdgeInsets.fromLTRB(0, 20, 180, 10),
child: Text(
"FRUIT AND BERRIES",
style: TextStyle(
fontFamily:'Roboto',
fontSize: 10,
color: Colors.lightGreen,
fontWeight: FontWeight.w700),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 180, 10),
child: Text(
"Tangerine",
style: TextStyle(
fontFamily:'Roboto',
fontSize: 22,
color: Colors.black,
fontWeight: FontWeight.w700),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 220, 10),
child: Text(
"Rs.0.90/kg",
style: TextStyle(
fontFamily:'Roboto',
fontSize: 10,
color: Colors.grey,
fontWeight: FontWeight.w700),
),
),
],
)
)),
const Padding(
padding: EdgeInsets.fromLTRB(120, 0, 40, 0),
child: Image(
image: AssetImage("assets/images/orange.png"),
),
),
],
),
Stack(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0, 45, 10, 0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: Color(0xffE2F3DF),
),
height: 180,
width: 380,
child: Column(
children: const [
Padding(
padding: EdgeInsets.fromLTRB(0, 20, 180, 10),
child: Text(
"FRUIT AND BERRIES",
style: TextStyle(
fontFamily:'Roboto',
fontSize: 10,
color: Colors.lightGreen,
fontWeight: FontWeight.w700),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 180, 10),
child: Text(
"Tangerine",
style: TextStyle(
fontFamily:'Roboto',
fontSize: 22,
color: Colors.black,
fontWeight: FontWeight.w700),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 220, 10),
child: Text(
"Rs.0.90/kg",
style: TextStyle(
fontFamily:'Roboto',
fontSize: 10,
color: Colors.grey,
fontWeight: FontWeight.w700),
),
),
],
)
)),
const Padding(
padding: EdgeInsets.fromLTRB(100, 0, 40, 0),
child: Image(
image: AssetImage("assets/images/kiwi.png"),
// height:200,
),
),
],
),
],
),
),
);
}
Widget buildSearchInput() => Container(
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(14)),
child: Padding(
padding: const EdgeInsets.only(left: 20.0, right: 20),
child: Row(
children: [
Icon(
Icons.search,
size: 30,
color: Colors.grey.shade300,
),
Flexible(
child: TextField(
decoration: InputDecoration(border: InputBorder.none),
),
),
],
),
),
);
}
You can add ListView with scrollDirection: Axis.horizontal, in this case it will be needed to have fixed height, and it will be scrolled up based on parent ListView scroll event.
buildSearchInput(),
SizedBox(
height: kToolbarHeight,
child: ListView(
scrollDirection: Axis.horizontal,
children: List.generate(14, (index) => Text("item $index")),
),
),
If you wish to have it on top fixed position, wrap everything with Column and ListView with Expanded.
body: Padding(
padding: const EdgeInsets.only(top: 40, left: 20, right: 20),
child: Column(
children: [
buildSearchInput(),
SizedBox(
height: kToolbarHeight,
child: ListView(
scrollDirection: Axis.horizontal,
children: List.generate(14, (index) => Text("item $index")),
),
),
Expanded(
child: ListView(
children: [
Stack(....
Head to flutter.dev for info.

Flutter card layout and design

So I'm trying to create an expandable card. But the problem is, I don't even know how to start with the design.
So I'm trying to achieve this output
And this is my current progress
I tried putting two containers in a column, but it just doesn't look right.
Can someone please help me out. I need to achieve the top part of the card.
This is the code for my current progress
Widget buildTabCards() {
return Container(
padding: EdgeInsets.only(
top: 10.0,
left: 10,
right: 10,
),
child: Column(children: [
Card(
elevation: 5.0,
color: Colors.white,
child: Padding(
padding: EdgeInsets.only(
top: 7,
bottom: 10,
),
child: Column(
children: <Widget>[
buildCardDateandTime(),
buildCardAvatar(),
],
),
),
),
Widget buildCardDateandTime() {
return Container(
child: Row(
children: [
Padding(
padding: EdgeInsets.only(
left: 15,
right: 5,
top: 2,
),
child: Icon(
MdiIcons.clockOutline,
size: 22,
color: AppColors.blue,
),
),
Text(
"12 June, 2021, 8:00 AM",
style: TextStyle(
fontFamily: "Poppins",
color: Colors.black87,
letterSpacing: 0.3,
fontSize: 20,
fontWeight: FontWeight.w400,
),
),
SizedBox(width: 5),
Padding(padding: EdgeInsets.only(left: 50)),
IconButton(
icon: Icon(
MdiIcons.fromString('dots-vertical'),
size: 30,
color: AppColors.blue,
),
onPressed: () {
Navigator.of(context).pop();
},
)
],
),
);
}
Widget buildCardAvatar() {
return Padding(
padding: EdgeInsets.only(
left: 25,
top: 5,
bottom: 10,
),
child: Row(mainAxisAlignment: MainAxisAlignment.start, children: [
Container(
padding: EdgeInsets.all(15.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(200),
),
color: Colors.red,
),
child: Text(
"JS",
style: TextStyle(
fontSize: 18.0,
color: Colors.black,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
),
SizedBox(
width: 5.0,
),
Padding(padding: EdgeInsets.only(left: 10)),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"John Renzo",
style: TextStyle(
fontSize: 20.0,
color: Colors.black54,
fontWeight: FontWeight.w500,
),
),
Text(
"Sangalang",
style: TextStyle(
fontSize: 20.0,
color: Colors.black54,
fontWeight: FontWeight.w500,
),
)
]))
]));
}
First declare a variable
bool extended = false;
then
Padding(
padding: const EdgeInsets.only(left: 12.0, right: 12.0, top: 9.0, bottom: 9.0),
child: Container(
width: MediaQuery.of(context).size.width,
child: InkWell(
onTap: () {
setState(() {
if (extended == null || !extended)
extended = true;
else
extended = false;
});
},
enableFeedback: false,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
child: Center(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 10.0,
),
Row(
children: <Widget>[
Expanded(
child: Text(
'Text',
style: TextStyle(fontSize: 16.0),
),
),
Icon(
extended ? Icons.keyboard_arrow_down : Icons.keyboard_arrow_right,
size: 26,
color: Colors.grey,
)
],
),
SizedBox(
height: 10.0,
),
extended
? Container(
height: 100,
)
: Container()
],
),
),
),
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(7.0),
),
boxShadow: <BoxShadow>[
BoxShadow(
color: Color.fromRGBO(0, 0, 0, 0.09),
offset: Offset(0.0, -2.0),
blurRadius: 12.0,
),
BoxShadow(
color: Color.fromRGBO(0, 0, 0, 0.09),
offset: Offset(0.0, 6.0),
blurRadius: 12.0,
),
],
),
),
);
You can use ExpansionPanel to achieve your results
List<bool> isExpanded = []; //the size/length should be equal to the size of your data list
ExpansionPanelList(children: [
//generate the panels from your data list
ExpansionPanel(
headerBuilder: (context, isExpanded) {
return _headerHere();
},
body: _bodyHere(),
isExpanded: isExpanded[0], //index of your card
canTapOnHeader: true,// to make the complete header clickable
)
],
expansionCallback: (panelIndex, expanded) {
setState(() {
isExpanded[panelIndex] = !expanded;
});
},
),

Flutter Card Layout

So I'm new to flutter, and I'm trying to make a card. But I can't seem to get my desired output.
I tried to separate the different widgets, by using rows and columns, but I kept messing it up.
This is my target output
Target output
This is my current progressCurrent progress
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: buildhomePageAppBar(),
body: buildExhibitorBody(),
);
}
Widget buildExhibitorBody() {
return Container(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
buildExhibitorText(),
SizedBox(
height: 10,
),
buildExhibitorCards(),
SizedBox(height: 10),
],
),
),
);
}
Widget buildhomePageAppBar() {
double profileDimension = 35;
return AppBar(
backgroundColor: Colors.white,
titleSpacing: 0,
title: Padding(
padding: EdgeInsets.only(
left: 20,
),
child: Row(
children: [
Padding(
padding: EdgeInsets.only(
top: 5,
bottom: 5,
),
child: Image(
image: AssetImage('assets/images/plain_logo.png'),
height: 30,
),
),
SizedBox(width: 5),
Text(
'Virtex',
style: TextStyle(
color: Colors.black87,
fontFamily: 'Poppins',
fontSize: 16,
fontWeight: FontWeight.bold,
),
)
],
),
),
actions: [
Padding(
padding: EdgeInsets.only(
top: 10,
bottom: 10,
),
child: Container(
height: profileDimension,
width: profileDimension,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.black54,
width: 2,
),
borderRadius: BorderRadius.circular(50),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(50),
child: Image(
width: profileDimension,
height: profileDimension,
image: AssetImage(
'assets/images/profile-image.jpeg',
),
fit: BoxFit.cover,
),
),
),
),
SizedBox(width: 20),
],
);
}
Widget buildExhibitorText() {
return Padding(
padding: EdgeInsets.only(
left: 20,
right: 20,
top: 20,
bottom: 10,
),
child: Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Text(
"Exhibitors",
textAlign: TextAlign.justify,
style: TextStyle(
fontFamily: "DMSans",
letterSpacing: -0.2,
fontSize: 20.0,
color: Colors.black,
fontWeight: FontWeight.w400,
),
),
),
],
),
),
);
}
Widget buildExhibitorCards() { // I think my problem is I don't know how to do the layout here
return Container(
width: 400,
height: 150,
child: Column(children: <Widget>[
Card(
elevation: 1,
child: Padding(
padding: const EdgeInsets.only(),
child: Row(children: [
buildCardImage(),
buildCardExhibitor(),
buildCardIndustry(),
buildCardGo(),
])),
),
]),
);
}
Widget buildCardExhibitor() {
return Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Container(
padding: EdgeInsets.all(10),
width: 40,
height: 40,
child: Center(
child: Row(
children: <Widget>[
Text(
"EN",
style: TextStyle(
fontSize: 15.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
Text('Exhibitor Name')
],
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(200),
),
color: Colors.red,
),
),
]);
}
Widget buildCardImage() {
return Container(
height: 100,
width: 100,
child: Image(
image: AssetImage('assets/images/onboarding-2.jpg'),
height: 100,
),
);
}
Widget buildCardIndustry() {
return Padding(
padding: EdgeInsets.only(
left: 40,
right: 40,
),
child: Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
"Industry 1",
style: TextStyle(
fontFamily: "DMSans",
color: Colors.grey,
letterSpacing: 0.3,
fontSize: 12,
),
),
Text(
"Industry 2",
style: TextStyle(
fontFamily: "DMSans",
letterSpacing: -0.3,
fontSize: 12,
color: Colors.grey,
fontWeight: FontWeight.w500,
),
),
],
),
),
);
}
Widget buildCardGo() {
return Row(mainAxisAlignment: MainAxisAlignment.end, children: [
Text(
'Go to Booth',
style: TextStyle(
color: Colors.blue,
fontFamily: 'Poppins',
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
SizedBox(width: 5),
IconButton(
icon: Icon(
MdiIcons.fromString('arrow-right'),
size: 30,
color: Colors.black,
),
onPressed: () {
Navigator.of(context).pop();
},
),
]);
}
}
I would greatly appreciate any kind of help.
Look:
My own Code
import 'package:flutter/material.dart';
class CardLayout extends StatelessWidget {
Widget buildCardImage = Container(
margin: EdgeInsets.only(right: 10.0),
width: 150,
height: 150,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage("https://picsum.photos/250?image=9"),
),
),
);
Widget buildCardExhibitor =
Row(mainAxisAlignment: MainAxisAlignment.start, children: [
Container(
padding: EdgeInsets.all(10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(200),
),
color: Colors.red,
),
child: Text(
"EN",
style: TextStyle(
fontSize: 15.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
),
SizedBox(
width: 10.0,
),
Text(
'Exhibitor Name',
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
]);
Widget buildCardIndustry = Padding(
padding: EdgeInsets.all(8.0),
child: Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
padding:
EdgeInsets.only(left: 10.0, right: 10.0, top: 5, bottom: 5),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(100),
),
color: Colors.blueGrey.shade400,
),
child: Text(
'Industry 1',
style: TextStyle(
fontFamily: "DMSans",
color: Colors.white,
letterSpacing: 0.3,
fontSize: 12,
),
),
),
SizedBox(
width: 10.0,
),
Container(
padding:
EdgeInsets.only(left: 10.0, right: 10.0, top: 5, bottom: 5),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(100),
),
color: Colors.blueGrey.shade400,
),
child: Text(
'Industry 2',
style: TextStyle(
fontFamily: "DMSans",
color: Colors.white,
letterSpacing: 0.3,
fontSize: 12,
),
),
),
],
),
),
);
Widget buildCardGo = Row(mainAxisAlignment: MainAxisAlignment.end, children: [
Text(
'Go to Booth',
style: TextStyle(
color: Colors.blue,
fontFamily: 'Poppins',
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
SizedBox(width: 3),
IconButton(
icon: Icon(
Icons.arrow_forward_rounded,
size: 30,
color: Colors.blue,
),
onPressed: () {
//Navigator.pop(context);
},
),
]);
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('Exhibitor'),
actions: [
IconButton(
icon: Icon(Icons.filter_list_rounded),
onPressed: () {
Navigator.pop(context);
})
],
),
body: Container(
margin: EdgeInsets.only(top: 10.0),
width: MediaQuery.of(context).size.width,
//height: 150.0, // remove this line -------------- (1) [EDIT]
child: Column(
// wrap card with column and add listtile as children -------------- (2) [EDIT]
children: [
ListTile(
leading: Text('Exhibitor'),
trailing: IconButton(
icon: Icon(Icons.filter_list_rounded),
onPressed: () {
Navigator.pop(context);
}),
),
Card(
elevation: 5.0,
color: Colors.white,
child: Padding(
padding: EdgeInsets.all(5.0),
child: Row(
children: <Widget>[
buildCardImage,
Expanded(
child: Column(
children: <Widget>[
buildCardExhibitor,
buildCardIndustry,
buildCardGo
],
))
],
),
),
),
],
),
),
));
}
}