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,
…
);
Related
I use the component as in the description, I can’t figure out how to remove the answer (child component) in the component itself, or at least how to check if it exists, then show it, if not, then don’t show it.
https://gist.github.com/lomanu4/3abba49f6fbcecbde4c07df82c3ce11c
class _ComentCardState extends State<ComentCard> {
bool childcomment = false;
#override
Widget build(BuildContext context) {
return Column(children: [
Container(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
child: CommentTreeWidget<Comment, Comment?>(
Comment(
avatar: 'null',
userName: widget.snap['name'],
content: '${widget.snap['text']} '),
[
Comment(avatar: 'null', userName: 'null', content: 'null'),
],
treeThemeData: childcomment
? TreeThemeData(lineColor: Colors.green[500]!, lineWidth: 3)
: TreeThemeData(lineColor: Colors.green[500]!, lineWidth: 3),
avatarRoot: (context, data) => PreferredSize(
preferredSize: const Size.fromRadius(18),
child: Row(
children: [
CircleAvatar(
radius: 18,
backgroundColor: Colors.grey,
backgroundImage:
NetworkImage(widget.snap['profilePic'].toString()),
),
],
),
),
avatarChild: (context, data) => const PreferredSize(
preferredSize: Size.fromRadius(12),
child: CircleAvatar(
radius: 12,
backgroundColor: Colors.grey,
backgroundImage: AssetImage('lib/assets/homescreen.png'),
),
),
contentChild: (context, data) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding:
const EdgeInsets.symmetric(vertical: 8, horizontal: 8),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(12)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'dangngocduc',
style: Theme.of(context).textTheme.caption?.copyWith(
fontWeight: FontWeight.w600, color: Colors.black),
),
const SizedBox(
height: 4,
),
Text(
'${data!.content}',
style: Theme.of(context).textTheme.caption?.copyWith(
fontWeight: FontWeight.w300, color: Colors.black),
),
],
),
),
DefaultTextStyle(
style: Theme.of(context).textTheme.caption!.copyWith(
color: Colors.grey[700], fontWeight: FontWeight.bold),
child: Padding(
padding: const EdgeInsets.only(top: 4),
child: Row(
children: const [
SizedBox(
width: 8,
),
Text('Reply'),
],
),
),
)
],
);
},
contentRoot: (context, data) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding:
const EdgeInsets.symmetric(vertical: 8, horizontal: 8),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(12)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.snap['name'],
style: Theme.of(context).textTheme.caption!.copyWith(
fontWeight: FontWeight.w600, color: Colors.black),
),
const SizedBox(
height: 4,
),
Text(
'${data.content}',
style: Theme.of(context).textTheme.caption!.copyWith(
fontWeight: FontWeight.w300, color: Colors.black),
),
const SizedBox(
height: 4,
),
],
),
),
DefaultTextStyle(
style: Theme.of(context).textTheme.caption!.copyWith(
color: Colors.grey[700], fontWeight: FontWeight.bold),
child: Padding(
padding: const EdgeInsets.only(top: 4),
child: Row(
children: [
SizedBox(
width: 8,
),
Text('Like'),
SizedBox(
width: 24,
),
Expanded(child: Text('Reply')),
Container(
padding: const EdgeInsets.all(8),
child: const Icon(
Icons.favorite_border,
size: 16,
),
)
],
),
),
),
],
);
},
),
),
]);
}
So far it just goes in the middle even with a padding Edge Inset set to zero and Box Constraints.
Row(children: [
Padding(
padding: const EdgeInsets.fromLTRB(
3, 3, 3, 6),
child: Container(
width: 150,
height: 30,
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"Title Sub-title",
textAlign: TextAlign.left,
maxLines: 2,
style: TextStyle(
height: 1.2,
fontFamily:
'Roboto’,
fontSize: 12,
letterSpacing: 0.15,
color: Colors.black,
),
),
),
),
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(
0, 10, 0, 3),
),
IconButton(
padding: EdgeInsets.zero,
constraints: BoxConstraints(),
onPressed: () {},
icon: Icon(
Icons.bookmark_border,
size: 20.0,
color: Colors.black,
),
),
Text(
"Author",
textAlign: TextAlign.left,
style: TextStyle(
height: 1.1,
fontFamily: 'Roboto Light',
fontSize: 8,
color: Colors.black,
),
),
],
),
],
),
),
),
],
),
Try with column tree and adjust your padding as you desire
import 'package:flutter/material.dart';
import 'package:so_test/screen/child_page.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
// This widget is the root of your application.
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool visible = true;
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text("Test obviously"),
),
body: SingleChildScrollView(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.green,
),
),
Padding(
padding: const EdgeInsets.fromLTRB(10, 10, 3, 0),
child: Container(
width: 150,
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"Title",
textAlign: TextAlign.left,
maxLines: 2,
style: TextStyle(
height: 1.2,
fontSize: 12,
letterSpacing: 0.15,
color: Colors.black,
),
),
),
),
),
Container(
padding: const EdgeInsets.fromLTRB(10, 10, 3, 0),
width: 150,
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"Sub Title",
textAlign: TextAlign.left,
maxLines: 2,
style: TextStyle(
height: 1.2,
fontSize: 12,
letterSpacing: 0.15,
color: Colors.black,
),
),
),
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: 5,
),
IconButton(
padding: EdgeInsets.zero,
constraints: BoxConstraints(),
onPressed: () {},
icon: Icon(
Icons.bookmark_border,
size: 20.0,
color: Colors.black,
),
),
Text(
"Author",
textAlign: TextAlign.left,
style: TextStyle(
height: 1.1,
fontFamily: 'Roboto Light',
fontSize: 8,
color: Colors.black,
),
),
],
),
],
),
),
));
}
}
Output:
You can keep the first Container in different column and create the separate column for below three children's.
I am trying to add a fixed buildHelpCard(context, alldata) above the scrollable list but whenever I try to add the buildHelpCard the list got disappeared and only the buildHelpCard is showing ... can you guys please suggest me how to fix this issues
**here is my code**
```
import 'package:flutter/material.dart';
import '../colors/constants.dart';
import 'package:get/get.dart';
import 'package:flutter_svg/flutter_svg.dart';
class duesDetails extends StatefulWidget {
var data;
var count;
duesDetails(this.data, this.count);
#override
_duesDetailsState createState() => _duesDetailsState();
}
class _duesDetailsState extends State<duesDetails> {
#override
Widget build(BuildContext context) {
var alldata = widget.data; // added all value to data for easy access
int count = widget.count;
return Scaffold(
appBar: buildAppBar(alldata),
body: Container(
decoration: BoxDecoration(
color: kPrimaryColor.withOpacity(0.03),
),
child: Center(
child: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Card(
child: Padding(
padding: const EdgeInsets.only(
top: 22, bottom: 22, left: 16, right: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
InkWell(
onTap: () {},
child: Text(
'${alldata[count]['pay list'][index]['discription']}',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 22),
),
),
Text(
'Capital',
style: TextStyle(color: Colors.grey.shade500),
),
],
),
Container(
height: 30,
width: 50,
child: Image.asset('assets/facebook.png'),
)
],
),
),
);
},
itemCount: alldata[count]['pay count'] == null ? 0 : alldata[count]['pay count'],
),
),
),
);
}
AppBar buildAppBar(var data) {
return AppBar(
backgroundColor: kPrimaryColor.withOpacity(.05),
elevation: 0,
//title: Obx(() => Text('Randas ', style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),),),
title: Text("${data[0]['name']} Pay Details", style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),),
iconTheme: IconThemeData(
color: kPrimaryColor,
size: 28.0,
),
);
}
Container buildHelpCard(BuildContext context, var data) {
return Container(
height: 150,
width: double.infinity,
child: Stack(
alignment: Alignment.bottomLeft,
children: <Widget>[
Container(
padding: EdgeInsets.only(
// left side padding is 40% of total width
left: MediaQuery.of(context).size.width * .4,
top: 20,
right: 20,
),
height: 130,
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xFF60BE93),
Color(0xFF1B8D59),
],
),
borderRadius: BorderRadius.circular(20),
),
child: RichText(
text: TextSpan(
children: [
TextSpan(
text: "${data[5]["title"]}\n",
style: Theme.of(context)
.textTheme
.headline6
.copyWith(color: Colors.white),
),
TextSpan(
text: "${data[5]["dis"]}",
style: TextStyle(
color: Colors.white.withOpacity(0.7),
),
),
],
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0.0, 0.0, 210.0, 20.0),
child: SvgPicture.asset("assets/svg/friends.svg"),
),
],
),
);
}
}
```
NOTE - I want to add buildHelpCard(context, alldata) function above the start of the card list... but when I try to do this the list got disappeared
Try this
child: Column(
children: [
buildHelpCard()
Expanded(child:
ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Card(
child: Padding(
padding: const EdgeInsets.only(
top: 22, bottom: 22, left: 16, right: 16),
child:........
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.
I'm having a hard time making a custom collapsing toolbar, attached below is a video for a normal case.
Then here's a screen record of the misbehavior, most of the time this happens.
Aside from the fact that the scrolling is not so snappy, you'll see in the second video that the sliver on the top is not completely collapsed.
Do you have any suggestion to improve the performance of the app and a solution for the bug?
here's my code inside the SliverPersistentHeaderDelegate
class DashboardHeaderPersistentDelegate extends SliverPersistentHeaderDelegate {
...
#override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
double shrinkPercentage = min(1, shrinkOffset / (maxExtent - minExtent));
double titleTopMargin = titleCollapsedTopPadding +
(titleExpandedTopPadding - titleCollapsedTopPadding) *
(1 - shrinkPercentage);
double titleFontSize = titleCollapsedFontSize +
(titleExpandedFontSize - titleCollapsedFontSize) *
(1 - shrinkPercentage);
double infoWidgetHeight = minExtent +
(maxExtent - minExtent) -
shrinkOffset -
titleTopMargin -
titleFontSize -
44;
double collapasedInfoOpacity = max(0, shrinkPercentage-.7)/.3;
return Material(
elevation: 0,
shadowColor: Colors.white,
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
height: titleFontSize,
alignment: Alignment.center,
child: Text(
'\$ 5329.05',
style: TextStyle(
fontFamily: 'Barlow',
fontSize: titleFontSize,
fontWeight: FontWeight.w500),
),
margin: EdgeInsets.only(top: titleTopMargin, bottom: 8),
),
Container(
height: shrinkPercentage == 1 ? 20 : infoWidgetHeight,
width: MediaQuery.of(context).size.width,
alignment: Alignment.center,
child: Stack(
alignment: Alignment.bottomCenter,
children: [
Opacity(
opacity: 1 - shrinkPercentage,
child: _buildInformationWidget(context),
),
Opacity(
opacity: collapasedInfoOpacity,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: _buildCollapsedInformationWidget(),
),
)
],
),
)
],
),
),
);
}
Widget _buildInformationWidget(BuildContext context) => ClipRect(
child: OverflowBox(
maxWidth: double.infinity,
maxHeight: double.infinity,
child: FittedBox(
fit: BoxFit.fitWidth,
alignment: Alignment.center,
child: Container(
width: MediaQuery.of(context).size.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'AVAILABLE BALANCE',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w900,
color: Colors.black26),
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 100,
child: Text(
'\$ 11200',
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 18,
fontWeight: FontWeight.w700,
color: Colors.green[400]),
),
),
Text(
' I ',
style: TextStyle(fontSize: 20, color: Colors.black12),
),
Container(
width: 100,
child: Text(
'\$ 400',
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 18,
fontWeight: FontWeight.w700,
color: Colors.red[400]),
),
)
],
),
),
Container(
margin: EdgeInsets.only(left: 12, top: 12),
alignment: Alignment.centerLeft,
child: Text(
"CATEGORIES",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w900,
color: Colors.black26),
),
),
Container(
height: 88,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categories.length,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(
left: (index == 0) ? 24.0 : 8.0,
right: (index == categories.length - 1)
? 24.0
: 8.0),
child: _buildCategoryItem(
categoriesIcons[index], categories[index], .9),
);
}),
)
],
),
),
),
),
);
Widget _buildCollapsedInformationWidget() => Row(
children: [
Text("Recent"),
Spacer(),
Container(
child: Text(
'\$ 11200',
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 14,
fontWeight: FontWeight.w700,
color: Colors.green[400]),
),
),
Text(
' I ',
style: TextStyle(fontSize: 20, color: Colors.black12),
),
Container(
child: Text(
'\$ 400',
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 14,
fontWeight: FontWeight.w700,
color: Colors.red[400]),
),
)
],
);
Widget _buildCategoryItem(
IconData data, String categoryTitle, double percentage) =>
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.black12),
borderRadius: BorderRadius.circular(28),
color: Colors.blue[400]),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Icon(
data,
size: 28,
color: Colors.white,
),
),
),
Container(
width: 40,
height: 40,
child: CircularProgressIndicator(
value: percentage,
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation(Colors.white),
),
)
],
),
Container(
width: 72,
alignment: Alignment.center,
child: Text(categoryTitle,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
maxLines: 1,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Colors.black45)),
)
],
);
...
}
When it's possible..Use dependend on parent size widgets insted of calcualting children sizes manualy.
FittedBox. Can scale the font size of the children widget according on parents size and fit parameter.
ConstrainedBox, BoxConstraints.tightFor
Expanded. Probably you know how it works.
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: SafeArea(
child: MyHomePage(),
),
),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
SliverPersistentHeader(
pinned: true,
floating: false,
delegate: DashboardHeaderPersistentDelegate(),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(_, i) => Card(
margin: const EdgeInsets.all(10),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
flex: 1,
child: Text(
i.toString(),
),
),
const Expanded(
flex: 3,
child: Text('Text'),
),
],
),
),
),
childCount: 100,
),
),
],
);
}
}
const categories = [
'Grocieries',
'Transport',
'House Rent',
'Shopping',
'Career'
];
const categoriesIcons = [
Icons.ac_unit,
Icons.access_alarms,
Icons.dashboard,
Icons.accessible_forward,
Icons.backspace,
];
class DashboardHeaderPersistentDelegate extends SliverPersistentHeaderDelegate {
#override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
double shrinkPercentage = min(1, shrinkOffset / (maxExtent - minExtent));
return Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.blueAccent,
),
),
child: Material(
elevation: 0,
shadowColor: Colors.white,
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
ConstrainedBox(
constraints: BoxConstraints.tightFor(
height: max(
60,
100 * (1 - shrinkPercentage),
),
),
child: FittedBox(
child: Container(
padding: EdgeInsets.all(20),
width: 200,
child: const Text(
'\$ 5329.05',
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 30,
fontWeight: FontWeight.w500,
),
),
),
),
),
Expanded(
child: Stack(
alignment: Alignment.bottomCenter,
children: [
if (shrinkPercentage != 1)
Opacity(
opacity: 1 - shrinkPercentage,
child: _buildInformationWidget(context),
),
if (shrinkPercentage != 0)
Opacity(
opacity: shrinkPercentage,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: _buildCollapsedInformationWidget(),
),
),
],
),
)
],
),
),
),
);
}
Widget _buildInformationWidget(BuildContext context) => ClipRect(
child: OverflowBox(
maxWidth: double.infinity,
maxHeight: double.infinity,
child: FittedBox(
fit: BoxFit.fitWidth,
alignment: Alignment.center,
child: Container(
width: MediaQuery.of(context).size.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
const Text(
'AVAILABLE BALANCE',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w900,
color: Colors.black26),
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 100,
child: Text(
'\$ 11200',
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 18,
fontWeight: FontWeight.w700,
color: Colors.green[400],
),
),
),
const Text(
' I ',
style: TextStyle(
fontSize: 20,
color: Colors.black12,
),
),
Container(
width: 100,
child: Text(
'\$ 400',
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 18,
fontWeight: FontWeight.w700,
color: Colors.red[400],
),
),
)
],
),
),
Container(
margin: EdgeInsets.only(left: 12, top: 12),
alignment: Alignment.centerLeft,
child: const Text(
"CATEGORIES",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w900,
color: Colors.black26,
),
),
),
Container(
height: 88,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categories.length,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(
left: (index == 0) ? 24.0 : 8.0,
right: (index == categories.length - 1)
? 24.0
: 8.0),
child: _buildCategoryItem(
categoriesIcons[index],
categories[index],
.9,
),
);
},
),
)
],
),
),
),
),
);
Widget _buildCollapsedInformationWidget() => Row(
children: [
const Text("Recent"),
const Spacer(),
Container(
child: Text(
'\$ 11200',
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 14,
fontWeight: FontWeight.w700,
color: Colors.green[400],
),
),
),
const Text(
' I ',
style: TextStyle(
fontSize: 20,
color: Colors.black12,
),
),
Container(
child: Text(
'\$ 400',
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 14,
fontWeight: FontWeight.w700,
color: Colors.red[400],
),
),
)
],
);
Widget _buildCategoryItem(
IconData data, String categoryTitle, double percentage) =>
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(
width: 1,
color: Colors.black12,
),
borderRadius: BorderRadius.circular(28),
color: Colors.blue[400],
),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Icon(
data,
size: 28,
color: Colors.white,
),
),
),
Container(
width: 40,
height: 40,
child: CircularProgressIndicator(
value: percentage,
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation(Colors.white),
),
)
],
),
Container(
width: 72,
alignment: Alignment.center,
child: Text(
categoryTitle,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
maxLines: 1,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Colors.black45,
),
),
)
],
);
#override
double get maxExtent => 300;
#override
double get minExtent => 80;
#override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
}