Google Map behaving Weird in Scrollable Widget (inside ListView.builder) - flutter

I need to show Google Map in ListView.builder. in Ios its behaving weird. the App Header and Bottom App Bar got scrolled with White Space. GoogleMap get freeze as well.
SingleChildScrollView(
child: Container(
margin: EdgeInsets.all(10.0),
child: ListView.separated(
itemCount: state.products.length,
separatorBuilder:
(BuildContext context, int index) => SizedBox(
height: 10,
),
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (context, position) {
return PharmaciesItemWidget(
pharmacies: state.products[position],
remove: true,
removeBottom: true,
onTap: () {
BlocProvider.of<PharmaciesCubit>(context)
.deletePharmacy(
state.products[position].uuid);
},
);
// return Text("$position");
},
),
),
)
/// List Item Class
class PharmaciesItemWidget extends StatefulWidget {
final PharmaciesData pharmacies;
final VoidCallback onTap;
final bool remove;
final bool removeBottom;
const PharmaciesItemWidget({
Key key,
#required this.pharmacies,
this.onTap,
this.remove = false,
this.removeBottom = false,
}) : super(key: key);
#override
_PharmaciesItemWidgetWidgetState createState() =>
_PharmaciesItemWidgetWidgetState();
}
class _PharmaciesItemWidgetWidgetState extends State<PharmaciesItemWidget> {
#override
Widget build(BuildContext context) {
return
// Card(
// clipBehavior: Clip.antiAliasWithSaveLayer,
// elevation: 2,
// margin: EdgeInsets.all(10.0),
// shape: RoundedRectangleBorder(
// // side: BorderSide(color: AppColor.primaryColor, width: 2),
// borderRadius: BorderRadius.circular(15),
// ),
ClipRRect(
clipBehavior: Clip.antiAliasWithSaveLayer,
// elevation: 2,
// margin: EdgeInsets.all(10.0),
borderRadius: BorderRadius.all(Radius.circular(10)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
color: AppColor.primaryColor,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
flex: 1,
child: SvgPicture.asset(
AppImages.pharmacies,
color: AppColor.backgroundWhite,
width: 40,
height: 40,
),
),
SizedBox(
width: 5,
),
Expanded(
flex: 5,
child: Text(
widget.pharmacies.name ?? "",
// overflow: TextOverflow.fade,
maxLines: 2,
// softWrap: false,
style: GoogleFonts.comfortaa(
color: Colors.white, fontSize: 18),
),
),
Spacer(),
Expanded(
flex: 1,
child: GestureDetector(
onTap: () {
widget.onTap();
},
child: widget.remove
? Icon(
Icons.remove_circle_outline,
color: AppColor.backgroundWhite,
size: 40,
)
: SvgPicture.asset(
AppImages.right_arrow_circle,
color: AppColor.backgroundWhite,
width: 40,
height: 40,
),
),
),
],
),
),
),
Container(
height: 5,
color: AppColor.secondaryColor,
),
Container(
padding: EdgeInsets.all(5.0),
color: AppColor.primaryBackground,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 5,
height: 5,
),
Text(widget.pharmacies.addressLine1 ?? "",
style: GoogleFonts.comfortaa(
color: AppColor.primaryColor, fontSize: 14)),
Row(
children: [
Text(widget.pharmacies.city + ", ",
style: GoogleFonts.comfortaa(
color: AppColor.primaryColor,
fontSize: 14)),
Text(widget.pharmacies.stateCode + " ",
style: GoogleFonts.comfortaa(
color: AppColor.primaryColor,
fontSize: 14)),
Text(widget.pharmacies.zip,
style: GoogleFonts.comfortaa(
color: AppColor.primaryColor,
fontSize: 14)),
],
),
SizedBox(
width: 5,
height: 5,
),
// widget.pharmacies.telecom !=null ? GestureDetector(
// onTap: () => dialNo(widget.pharmacies.telecom),
// child: Row(
// children: [
// Text(
// widget.pharmacies.telecom,
//
// style: TextStyle(fontSize: 16,color: AppColor.primaryColor,),
// ),
//
// SvgPicture.asset(
// AppImages.call_text,
// height: 20,
// color: AppColor.primaryColor,
// ),
// ],
// ),
// ) : SizedBox(),
phoneNoWidget(
widget.pharmacies.telecom,
AppColor.primaryColor,
),
enableMessageDebugging
? Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"UUID:",
textAlign: TextAlign.end,
style: TextStyle(
color: AppColor.primaryColor,
fontSize: 16),
),
SizedBox(
width: 10,
),
Text(
widget.pharmacies.uuid,
style: TextStyle(fontSize: 16),
)
],
)
: SizedBox(),
widget.removeBottom
? SizedBox(
height: 0,
)
: Column(
children: [
SizedBox(
height: 5,
),
Container(
height: 5,
color: AppColor.primaryColor,
),
SizedBox(
height: 5,
),
Padding(
padding: const EdgeInsets.all(5.0),
child: Row(
children: [
Text(
widget.pharmacies.distanceInMiles
.toStringAsFixed(1) +
" Miles Away",
style: GoogleFonts.comfortaa(
fontSize: 18,
color: AppColor.secondaryColor),
),
Spacer(),
// Text(
// Strings.delivery_partner,
// style: GoogleFonts.comfortaa(fontSize: 18),
// )
Image.asset(
AppImages.lyft_logo,
width: 25,
height: 17,
alignment: Alignment.bottomRight,
)
],
),
)
],
)
],
),
),
Container(
height: 5,
color: AppColor.primaryColor,
),
Container(
// decoration: BoxDecoration(
// image: DecorationImage(
// image: AssetImage(AppImages.map), fit: BoxFit.cover),
// ),
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.width,
child: SafeArea(
child: Container(
color: Colors.blueGrey.withOpacity(.8),
child: Center(
child: Column(
children: [
Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.width,
child: GoogleMap(
initialCameraPosition: CameraPosition(target: LatLng(widget.pharmacies.latitude,widget.pharmacies.longitude), zoom: 15),
markers: <Marker>{
Marker(
markerId: MarkerId("location"),
position: LatLng(
widget.pharmacies.latitude,
widget.pharmacies.longitude,
),
infoWindow: InfoWindow(
title: "location",
snippet: '*',
),
),
},
mapType: MapType.normal,
// onMapCreated: _onMapCreated,
myLocationButtonEnabled: false,
),
) ,
],
),
),
),
),
),
Container(
height: 5,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10.0),
bottomRight: Radius.circular(10.0),
),
color: AppColor.primaryColor,
),
)
],
),
],
));
}
}
these are the some pictures of the issues
above is the ss of actual screen, adding ss for issues when we scroll it

I get to know today. Using Clip.antiAliasWithSaveLayer is costly.
There are enum property which define what it cost.
After investing many days i got to know antiAliasWithSaveLayer is very expensive to use.
hardEdge, which is the fastest clipping, but with lower fidelity.
antiAlias, which is a little slower than hardEdge, but with smoothed edges.
antiAliasWithSaveLayer, which is much slower than antiAlias, and should rarely be used.
Visit here for more information

Related

How to avoid overlap in widget inside GridView?

The widget inside the gridView overlap each other , the bottom portion of the widget is overlapped by another widget , How to avoid overlap in widget inside GridView?I want to avoid the overlap amoung the widget.
Here is my codes
It contain a gridview builder containing the widget, the widget is made by stack , position.fill
// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables
import 'package:flutter/material.dart';
import 'package:iconsax/iconsax.dart';
class WorkshopsCloseToYouPage extends StatelessWidget {
const WorkshopsCloseToYouPage({super.key});
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: GridView.builder(
itemCount: 6,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisSpacing: 4.0, mainAxisSpacing: 4.0),
itemBuilder: (BuildContext context, int index) {
return workshopCard();
},
),
),
);
}
Stack workshopCard() {
return Stack(
clipBehavior: Clip.none,
children: [
Container(
width: 200,
height: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
image: DecorationImage(
image: AssetImage('assets/workshop_image.png'),
fit: BoxFit.cover,
),
),
),
Positioned.fill(
bottom: -100,
child: Align(
alignment: Alignment.bottomCenter,
child: Card(
margin: const EdgeInsets.all(5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"Pottery Throwing Taster Class",
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(
height: 5,
),
Row(
children: [
SizedBox(
width: 100,
child: Column(
children: [
Row(
children: [
Icon(
Iconsax.location5,
size: 16,
color: Color(0xFF083AA9),
),
SizedBox(
width: 2,
),
Text(
"Honslow",
// style: TextStyle(fontSize: 8),
)
],
),
SizedBox(
height: 5,
),
Row(
children: [
Icon(
Iconsax.profile_2user,
size: 16,
color: Color(0xFF083AA9),
),
SizedBox(
width: 2,
),
Text("1 to 15")
],
),
SizedBox(
height: 5,
),
Row(
children: [
Icon(
Iconsax.tag_right,
size: 16,
color: Color(0xFF083AA9),
),
SizedBox(
width: 2,
),
Text("1 to 15")
],
),
SizedBox(
height: 5,
),
Row(
children: [
Icon(
Iconsax.star,
size: 16,
color: Color(0xFF083AA9),
),
SizedBox(
width: 2,
),
Text("5(37)")
],
),
],
),
),
ElevatedButton(
onPressed: () {},
style: TextButton.styleFrom(
minimumSize: const Size(70, 35),
maximumSize: const Size(70, 35),
backgroundColor: Color(0xFF0c3cac),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20))),
child: Row(
children: [
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
child: Text(
"Join",
style: TextStyle(
color: Colors.white,
fontSize: 12,
),
),
),
Icon(size: 5, Icons.arrow_forward_ios),
Icon(
color: Color.fromARGB(255, 231, 227, 227),
size: 5,
Icons.arrow_forward_ios),
Icon(
color: Color.fromARGB(255, 181, 180, 180),
size: 5,
Icons.arrow_forward_ios),
],
)),
],
),
],
),
)),
),
)
],
);
}
}
Output page showing the widget overlap

How to change circularprogressindicator in Center

I'm having a little problem here, I want to map a circularprogressindicator in the middle of the page but it just appears in the top center of the page, how do I move it to the middle of the page, I've tried wrapping it using the Column widget but an error occurs. How do I solve this simple problem.
and one more how do I add a hintText in the dropdown as the default value, because the dropdown immediately takes the value 1.
Thank you.
note:
green color for dropdown case
red for circularprogressindicator cases
Here I attach the code.
class JadwalKuliah extends StatefulWidget {
const JadwalKuliah({super.key});
#override
State<JadwalKuliah> createState() => _JadwalKuliahState();
}
class _JadwalKuliahState extends State<JadwalKuliah> {
String? _selectedItem1;
List<int> listitems = [1, 2, 3, 4, 5, 6, 7, 8];
int semester = 1;
List<Datum> data = [];
#override
void initState() {
super.initState();
fetchData(semester);
}
fetchData(int smt) async {
final apiResponse = await JadwalKuliahProvider.getJadwalKuliah(smt);
setState(() {
data = (apiResponse);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(kToolbarHeight),
child: CustomAppbar(
title: 'Jadwal Kuliah',
),
),
body: Center(
child: Padding(
padding: const EdgeInsets.only(
left: 14,
top: 14,
right: 14,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Header(),
listJadwal(),
],
),
),
),
);
}
Widget Header() {
return Container(
padding: const EdgeInsets.only(left: 12, right: 8),
width: double.infinity,
height: 50,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 1,
blurRadius: 9,
offset: const Offset(
1,
2,
),
),
],
),
child: DropdownButtonHideUnderline(
child: DropdownButton(
// hint: const Text('Pilih Semester'),
value: semester,
onChanged: (value) {
setState(
() {
semester = value!;
},
);
fetchData(value!);
},
hint: const SizedBox(
width: 150, //and here
child: Text(
"Pilih Semester",
style: TextStyle(color: Colors.grey),
),
),
items: listitems.map(
(itemone) {
return DropdownMenuItem(
value: itemone, child: Text(itemone.toString()));
},
).toList(),
),
),
);
}
Widget listJadwal() {
return FutureBuilder<List<Datum>>(
future: JadwalKuliahProvider.getJadwalKuliah(semester),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Expanded(
child: ListView.builder(
padding: const EdgeInsets.only(
top: 10,
),
physics: const BouncingScrollPhysics(),
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(top: 14),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(
Radius.circular(
10,
),
),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 1,
blurRadius: 9,
offset: const Offset(
1, 2), // changes position of shadow
),
],
),
padding: const EdgeInsets.symmetric(
horizontal: 16, vertical: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
// "Audit Bank Syariah (SPI)",
snapshot.data![index].nmMk.toString(),
style: bold6,
),
Text(
snapshot.data![index].dosenAjar!.nmDosen.toString(),
style: regular7,
),
Text(
// "Perbankan Syariah",
snapshot.data![index].prodi.toString(),
style: regular7,
),
const SizedBox(
height: 5,
),
Row(
children: [
Container(
height: 30,
width: 70,
decoration: BoxDecoration(
color: const Color(0xffECECEC),
borderRadius: BorderRadius.circular(5)),
child: Padding(
padding: const EdgeInsets.all(5),
child: Row(
children: [
Icon(
Icons.location_on_outlined,
color: greyColor,
size: 18,
),
const SizedBox(
width: 3,
),
Text(
'A201',
// snapshot.data![index]
// .dosenAjar!.nmDosen
// .toString(),
style: bold6.copyWith(color: greyColor),
),
],
),
),
),
const SizedBox(
width: 10,
),
Container(
height: 30,
width: 120,
decoration: BoxDecoration(
color: const Color(0xffECECEC),
borderRadius: BorderRadius.circular(5)),
child: Padding(
padding: const EdgeInsets.all(5),
child: Row(
children: [
Icon(
Icons.watch_later_outlined,
color: greyColor,
size: 18,
),
const SizedBox(
width: 3,
),
const SizedBox(
width: 3,
),
Text(
// snapshot
// .data![index].jamAwal
// .toString(),
'09:00',
style: bold6.copyWith(
color: greyColor,
),
),
const SizedBox(
width: 3,
),
Text(
'-',
// snapshot
// .data![index].jamAkhir
// .toString(),
style: bold6.copyWith(
color: greyColor,
),
),
const SizedBox(
width: 3,
),
Text(
'12:00',
// snapshot
// .data![index].jamAkhir
// .toString(),
style: bold6.copyWith(
color: greyColor,
),
),
],
),
),
),
const SizedBox(
width: 10,
),
SizedBox(
height: 30,
width: 100,
child: ElevatedButton.icon(
onPressed: () {},
icon: const Icon(
Icons.download,
size: 17,
color: Color(0xffCEE1FF),
),
label: Text(
'Materi',
style: bold6,
),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xff0062FF),
),
),
),
],
),
const SizedBox(
height: 10,
),
Container(
width: double.infinity,
height: 38,
child: TextButton(
onPressed: () {},
style: TextButton.styleFrom(
backgroundColor: const Color(0xffC9F7F5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: Text(
"Absen",
style: bold5.copyWith(
color: const Color(
0xff1BC5BD,
),
),
),
),
),
],
),
),
);
}),
);
} else {
return Center(
child: CircularProgressIndicator(color: primaryColor),
);
}
},
);
In your listJadwal change CircularProgressIndicator to this:
} else {
return Expanded(
child: Center(
child: CircularProgressIndicator(color: primaryColor),
),
);
}
Try below code I have same issue occurred I resolve this following code:
SizedBox(
height: MediaQuery.of(context).size.height / 1.0,//change on your need
child: Center(
child: CircularProgressIndicator(color: primaryColor),
),
),
Try this, Column will use your full screen size to center the widget
body: Column(mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: CircularProgressIndicator(),
)
],),

Flutter cant't align image to vertical center in ListTile with Stack

What every I try column, row, center, positioned, and aligned widgets, I still can't seem to align the dog image to the vertical center.
Does anyone know how to do this
Here is my widget
Widget build(BuildContext context) {
final dogTypes = dog.type!.map((type) => type.name).toList();
final teams = dog.teams.map((team) => team.name).toList();
return GestureDetector(
onTap: () => viewDogProfile(dog, index),
child: SizedBox(
width: double.infinity,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
),
margin: const EdgeInsets.only(top: 25),
child: Padding(
padding: const EdgeInsets.only(bottom: 8),
child: ListTile(
leading: Container(
width: 65,
height: 65,
decoration: const BoxDecoration(
shape: BoxShape.circle,
),
child: Stack(
children: [
CachedNetworkImage(
imageUrl: dog.image.url,
imageBuilder: (context, imageProvider) => Container(
height: 65,
width: 65,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
border: Border.all(
color: accentColor,
width: 2,
),
boxShadow: [
BoxShadow(
color: Colors.black87.withOpacity(0.6),
spreadRadius: 0.8,
blurRadius: 2,
offset: const Offset(1, 1),
),
],
),
),
placeholder: (context, url) =>
const CircularProgressIndicator(
color: primaryColor,
),
errorWidget: (context, url, error) =>
const Icon(Icons.error),
),
DogStatusIcon(
dogStatus: dog.status,
),
],
),
),
title: Row(
children: [
Flexible(
child: Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
dog.name,
style: AppStyles.dogProfileCardHeaderTextStyle,
maxLines: 1,
softWrap: true,
overflow: TextOverflow.ellipsis,
),
),
),
],
),
subtitle: Padding(
padding: const EdgeInsets.only(bottom: 5),
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Teams: ',
style: AppStyles.dogProfileCardSubHeaderTextStyle,
),
Flexible(
child: Text(
teams
.toString()
.replaceAll('[', '')
.replaceAll(']', ''),
style:
AppStyles.dogProfileCardSubHeaderDataTextStyle,
maxLines: 1,
softWrap: false,
overflow: TextOverflow.ellipsis,
),
),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Breed: ',
style: AppStyles.dogProfileCardSubHeaderTextStyle,
),
Flexible(
child: Text(
dog.breed.name,
style:
AppStyles.dogProfileCardSubHeaderDataTextStyle,
maxLines: 1,
softWrap: true,
overflow: TextOverflow.ellipsis,
),
),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Type: ',
style: AppStyles.dogProfileCardSubHeaderTextStyle,
),
Flexible(
child: Text(
dogTypes
.toString()
.replaceAll('[', '')
.replaceAll(']', ''),
style:
AppStyles.dogProfileCardSubHeaderDataTextStyle,
maxLines: 1,
softWrap: false,
overflow: TextOverflow.ellipsis,
),
),
],
),
],
),
),
trailing: Padding(
padding: const EdgeInsets.only(top: 10),
child: IconButton(
icon: const Icon(
Icons.keyboard_arrow_right_rounded,
color: accentColor,
size: 28,
),
onPressed: () {
viewDogProfile(dog, index);
},
),
),
),
),
),
),
);
}

I want to Hide some widgets from SliverAppbar On Scroll Flutter

enter image description here
Hello, I want to keep and hide few things on scroll from SliverAppBar bottom section. For example, when I scroll the list from top to bottom, the logo , branch, distance, etc should hide. The leading, title, actions, and restaurant title will be shown. Below is my code, Can anyone please help?
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:urmenuz/constants/styles.dart';
import 'package:urmenuz/widgets/hidable/hidable.dart';
import '../../constants/colors.dart';
import '../../constants/configs.dart';
import '../../utils/rating_bar.dart';
import 'package:flutter/rendering.dart';
class MenuHeader extends SliverAppBar {
final expandedHeight;
final collapsedHeight;
final bool dineIn;
final Function backFunction;
final Function menuFunction;
final Function infoFunction;
final Function serviceIconFunction;
final Widget tblTextField;
final ScrollController scrollController;
MenuHeader({
this.expandedHeight = 350,
this.collapsedHeight = 160,
this.dineIn = true,
required this.backFunction,
required this.menuFunction,
required this.infoFunction,
required this.serviceIconFunction,
required this.scrollController,
required this.tblTextField,
}) : super(
elevation: 0.0,
pinned: true,
floating: false,
snap: false,
forceElevated: true);
Color? get backgroundColor => AppColors.lightGrey;
// #override
// Widget? get background => Image.asset(IMAGE_ASSET_DIR + 'background2.png',
// fit: BoxFit.cover,
// );
#override
Widget? get leading {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: GestureDetector(
onTap: () => backFunction(),
child: Container(
height: 36,
width: 36,
decoration: BoxDecoration(
color: AppColors.lightRed,
borderRadius: BorderRadius.circular(10)),
child: Center(
child: Icon(
Icons.arrow_back_ios_new,
color: Colors.black,
)),
),
),
);
}
#override
Widget? get title {
return Text(
'urMenu',
style: TextStyle(
color: AppColors.lightGrey,
fontWeight: FontWeight.w600,
fontSize: 20),
);
}
#override
List<Widget>? get actions {
return [
Row(
children: [
GestureDetector(
onTap: () => serviceIconFunction(),
child: Image.asset(
IMAGE_ASSET_DIR + "${dineIn ? "dine_in" : "pick_up"}.png",
height: 40,
width: 40,
),
),
SizedBox(
width: 20,
),
Container(
height: 36,
width: 36,
margin: EdgeInsets.only(right: 20),
decoration: BoxDecoration(
color: AppColors.lightRed,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: AppColors.grey.withOpacity(0.1),
offset: Offset(0.0, 0.0), //(x,y)
blurRadius: 4.0,
),
],
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: GestureDetector(
onTap: () => menuFunction(),
child: Image.asset(
IMAGE_ASSET_DIR + 'menu.png',
color: Colors.black,
)),
)),
],
),
];
}
#override
PreferredSizeWidget? get bottom {
return PreferredSize(
preferredSize: const Size.fromHeight(70),
child: Container(
color: Colors.transparent,
height: 160,
child: Padding(
padding: const EdgeInsets.only(bottom: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Stack(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
// color: Colors.yellow,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
offset: Offset(0.0, 1.0), //(x,y)
blurRadius: 6.0,
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image.network(
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR7-G-E4aXWzIoakYj-4VpNF8tp5hiaUC5K7yZGDaEjaNddIRMWcvV9lJU1_3F1q_RVqIM&usqp=CAU",
height: 75,
width: 75,
),
),
),
],
),
),
const SizedBox(
width: 12,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
// SizedBox(
// height: 3,
// ),
const Text(
"Branch",
style: TextStyle(
color: AppColors.lightGrey,
fontSize: 14,
fontWeight: FontWeight.w500),
),
const SizedBox(
height: 3,
),
Text(
"The Butcher Shop & Grill",
maxLines: 1,
softWrap: true,
// .toUpperCase(),
style: const TextStyle(
color: AppColors.lightGrey,
fontSize: 20,
fontWeight: FontWeight.bold),
),
const SizedBox(
height: 6,
),
buildRatebar(12, 6, gap: .9),
]),
],
),
// Positioned(
// right: 20,
// child: GestureDetector(
// onTap: () => infoFunction(),
// child: Container(
// decoration: BoxDecoration(
// color: AppColors.lightGrey,
// borderRadius: BorderRadius.circular(20)),
// child: Padding(
// padding: EdgeInsets.all(3),
// child: Image.asset(
// IMAGE_ASSET_DIR + 'info_icon_single.png',
// height: 12,
// width: 12,
// color: dineIn ? AppColors.red : AppColors.orange,
// ),
// )),
// ),
// )
],
),
Padding(
padding: const EdgeInsets.only(right: 20, left: 20, top: 10),
child: Row(
children: [
if (dineIn) tblTextField,
// Text(
// '+ Enter Table #',
// style: TextStyle(
// color: AppColors.lightGrey,
// fontWeight: FontWeight.w500,
// fontSize: 14),
// ),
Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Styles.iconButtonWithShape(
Image.asset(
IMAGE_ASSET_DIR + 'location_icon.png',
height: 9,
color: dineIn ? AppColors.red : AppColors.orange,
),
// FaIcon(
// FontAwesomeIcons.locationArrow,
// color: dineIn ? AppColors.red : AppColors.orange,
// size: 12,
// ),
height: 22,
width: 22,
isCircle: true,
showShadow: false,
backgroundColor: dineIn
? AppColors.lightRed
: AppColors.lightOrange,
handler: () {}),
const SizedBox(
width: 6,
),
Text(
"5 KM",
style: TextStyle(
color: AppColors.lightGrey, fontSize: 12),
),
],
),
],
),
)
],
),
),
), // Add this code
);
}
#override
Widget? get flexibleSpace {
return ShaderMask(
// gradient layer ----------------------------
shaderCallback: (bound) {
return LinearGradient(
end: FractionalOffset.topCenter,
begin: FractionalOffset.bottomCenter,
colors: [
Colors.black.withOpacity(0.76),
Colors.black.withOpacity(0.66),
Colors.black26,
],
stops: [
0.0,
0.3,
0.45
]).createShader(bound);
},
blendMode: BlendMode.srcOver,
// your widget ------------------------
child: Container(
// constraints: const BoxConstraints(
// minWidth: 350,
// maxHeight: 350,
// ),
padding: EdgeInsets.all(10),
height: 350,
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://media-cdn.tripadvisor.com/media/photo-s/1b/67/cc/f8/chestnut-restaurant.jpg'),
fit: BoxFit.cover),
)),
);
}
}

How to put Gridview closer to Card widget in Column widget

I'm trying to create a user interface for my app. I need to design like this:
But my recent UI looks like this:
In second screenshot I scrolled down because my gridview widget (which has 4 card widgets) doesn't come closer to other widgets. The other widgets are: a widget for titlebar, a card widget which has a graph and subgraph widgets. I put titlebar and graphs card widget inside a stack for showing them above. I put these two combined widgets inside a column with my gridview widget. And I wrap this column widget with a SingleChildScrollView widget because I want my page to be scrollable. So my questions is this: How I can put my gridview widget closer to my card widget as in the first image ?
Here is the code that I used for this UI:
import 'package:flutter/material.dart';
import 'package:flutter_circular_chart/flutter_circular_chart.dart';
import 'package:intl/intl.dart';
import 'baskana_rapor_icon_icons.dart';
// ignore: must_be_immutable
class MainPage extends StatelessWidget {
List<Widget> widgets = new List();
List<CircularSegmentEntry> dataList = _loadData();
int _totalCount;
Widget s1, s2, total;
final formatter = new NumberFormat("#,##");
#override
Widget build(BuildContext context) {
widgets.add(_buildBody(context));
return Scaffold(body: _buildBody(context));
}
Widget _buildBody(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
//mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
),
_buildTitleBar(context),
Positioned(bottom: 65, left: 35, child: _buildCard(context)),
],
),
_buildGridButtons(context),
],
),
);
},
);
}
Widget _buildGridButtons(BuildContext context) {
int itemWidth = 80;
int itemHeight = 40;
return SafeArea(
child: Column(
children: [
GridView.count(
crossAxisCount: 2,
childAspectRatio: (itemWidth / itemHeight),
shrinkWrap: true,
primary: true,
children: [
GestureDetector(
onTap: () {
Navigator.pushNamed(context, '/MahalleRapor');
},
child: Card(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(25),
),
),
child: Stack(
alignment: Alignment.center,
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Icon(
BaskanaRaporIcon.mahalle_raporu,
color: Colors.redAccent,
size: 30,
),
Text(
'Mahalle Raporu',
style: TextStyle(
color: Colors.black87,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 5,
)
],
),
Positioned(
bottom: 0,
right: 1,
left: 1,
child: Divider(
color: Colors.redAccent,
endIndent: 45,
indent: 50,
thickness: 3,
),
),
],
),
),
),
GestureDetector(
onTap: () {
Navigator.pushNamed(context, '/BirimRapor');
},
child: Card(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(25),
),
),
child: Stack(
alignment: Alignment.center,
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Icon(
BaskanaRaporIcon.birim_raporu,
color: Colors.green[300],
size: 30,
),
Text(
'Birim Raporu',
style: TextStyle(
color: Colors.black87,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 5,
)
],
),
Positioned(
bottom: 0,
right: 1,
left: 1,
child: Divider(
color: Colors.green[300],
endIndent: 45,
indent: 50,
thickness: 3,
),
),
],
),
),
),
GestureDetector(
onTap: () {
Navigator.pushNamed(context, '/GelirGider');
},
child: Card(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(25),
),
),
child: Stack(
alignment: Alignment.center,
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Icon(
BaskanaRaporIcon.gelir_gider,
color: Colors.yellow[700],
size: 30,
),
Text(
'Gelir / Gider',
style: TextStyle(
color: Colors.black87,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 5,
)
],
),
Positioned(
bottom: 0,
right: 1,
left: 1,
child: Divider(
color: Colors.yellow[700],
endIndent: 45,
indent: 50,
thickness: 3,
),
),
],
),
),
),
GestureDetector(
onTap: () {
Navigator.pushNamed(context, '/BaskanaMesaj');
},
child: Card(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(25),
),
),
child: Stack(
alignment: Alignment.center,
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Icon(
BaskanaRaporIcon.baskana_msg,
color: Colors.blueAccent,
size: 30,
),
Text(
'Başkana Mesaj',
style: TextStyle(
color: Colors.black87,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 5,
)
],
),
Positioned(
bottom: 0,
right: 1,
left: 1,
child: Divider(
color: Colors.blueAccent,
endIndent: 45,
indent: 50,
thickness: 3,
),
),
],
),
),
),
],
)
],
),
);
}
// ignore: todo
//TODO: Better implementation of UI
final double buttonHeight = 50;
Widget _buildCard(BuildContext context) {
return Center(
child: Container(
height: 500 + buttonHeight,
child: Stack(
alignment: Alignment.center,
overflow: Overflow.visible,
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
side: BorderSide(color: Colors.blueGrey, width: 0.5),
),
child: Container(
height: MediaQuery.of(context).size.height * .65,
width: MediaQuery.of(context).size.width * .80,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Genel Durum",
style: TextStyle(
fontSize: 20,
color: Colors.black,
letterSpacing: 0.3,
),
),
),
Divider(
color: Colors.grey,
thickness: 0.3,
endIndent: 10,
indent: 10,
),
_buildChart(dataList),
SizedBox(
height: 20,
),
_buildSubGraph(),
SizedBox(
height: 40,
),
],
),
),
),
Positioned(
//top: -buttonHeight /2,
bottom: 27,
child: _buildDetailsButton(context),
),
],
),
),
);
}
Widget _buildDetailsButton(BuildContext context) {
return ButtonTheme(
height: 50,
minWidth: 100,
child: RaisedButton(
onPressed: () {
Navigator.pushNamed(context, '/DetailPage');
},
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
child: Text("Detayları Gör"),
),
);
}
Row _buildSubGraph() {
String s1 = formatter.format((dataList[1].value / _totalCount) * 100);
String s0 = formatter.format((dataList[0].value / _totalCount) * 100);
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
//İşlemde
children: [
Text(
dataList[1].rankKey,
style: TextStyle(
fontSize: 18,
color: Colors.black87,
),
),
Container(
decoration: BoxDecoration(
color: dataList[1].color,
borderRadius: BorderRadius.only(
topRight: Radius.circular(5),
bottomRight: Radius.circular(5),
bottomLeft: Radius.circular(5),
),
),
height: 50,
width: 150,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'${dataList[1].value.toInt()}',
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
SizedBox(
width: 50,
),
Flexible(
child: Text(
'%' + s1,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w300,
),
),
),
],
),
),
],
),
Column(
//Sonuçlanan
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
dataList[0].rankKey,
style: TextStyle(
fontSize: 18,
color: Colors.black87,
),
),
Container(
height: 50,
width: 150,
decoration: BoxDecoration(
color: dataList[0].color,
borderRadius: BorderRadius.only(
topRight: Radius.circular(5),
bottomRight: Radius.circular(5),
bottomLeft: Radius.circular(5),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'${dataList[0].value.toInt()}',
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
SizedBox(
width: 50,
),
Flexible(
child: Text(
'%' + s0,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w300,
),
),
),
],
),
),
],
)
],
);
}
//Map<String, double> dataMap, List<Color> colorList,BuildContext context
Widget _buildChart(List<CircularSegmentEntry> dataList) {
_totalCount = _findTotalCount(dataList);
s1 = _createText("TOPLAMDA", 20, Colors.grey[600], false);
s1 = _createText("TALEP", 20, Colors.grey[600], false);
total = _createText('$_totalCount', 24, Colors.black87, true);
return Container(
child: AnimatedCircularChart(
size: Size(500, 250),
initialChartData: <CircularStackEntry>[
CircularStackEntry(
<CircularSegmentEntry>[
dataList[0],
dataList[1],
],
),
],
chartType: CircularChartType.Radial,
startAngle: -90,
holeRadius: 25,
holeLabel:
"TOPLAMDA \n\t\t\t\t\t\t\t $_totalCount \n\t\t\t TALEP", // $s1 \n\t\t\t\t\t\t\t $total \n\t\t\t $s2
),
);
}
Widget _buildTitleBar(BuildContext context) {
return Align(
alignment: Alignment.topCenter,
child: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * .247,
decoration: BoxDecoration(
color: Colors.blue,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.vertical(
bottom: Radius.circular(25),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.assessment,
color: Colors.white,
),
Text(
"Genel Durum",
style: TextStyle(
color: Colors.white,
fontSize: 28,
fontWeight: FontWeight.bold,
letterSpacing: 0.5,
),
),
],
),
),
],
),
);
}
}
Widget _createText(String msg, double size, Color color, bool isBold) {
return Text(
msg,
style: TextStyle(
color: color,
fontSize: size,
fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
),
);
}
int _findTotalCount(List<CircularSegmentEntry> dataList) {
int result = 0;
for (int i = 0; i < dataList.length; i++) {
result += (dataList[i].value).toInt();
}
return result;
}
List<CircularSegmentEntry> _loadData() {
List<CircularSegmentEntry> dataList = [];
CircularSegmentEntry chartData1 =
new CircularSegmentEntry(150, Colors.greenAccent, rankKey: 'Sonuçlanan');
CircularSegmentEntry chartData2 =
new CircularSegmentEntry(150, Colors.blue, rankKey: 'İşlemde');
dataList.add(chartData1);
dataList.add(chartData2);
return dataList;
}
Extra question: If is there any thing that I can do for a more efficient design, can you tell me that ? Thanks!
Maybe this happening because of this piece of code in your Stack. This Container take your full screen size. that's why your GridView item build immediate after screen size. Try to remove this Container or reduce the height of it.
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
),
UPDATE:
You can try this. I have not tried this but Maybe this will help
Stack(
children: <Widget>[
Align(
alignment: Alignment.topCenter,
child: _buildTitleBar(context),
),
Align(
alignment: Alignment.topCenter,
child: Container(
margin: EdgeInsets.only(top: 100),
child: _buildCard(context),
),
)
],
)