Related
am new to flutter, and stuck logically on this problem :
i have a dropdown menu where the user will choose a gate from,
then show the chosen gate in the google map.
i've tried having the longitude and latitudes as global vairiables, but it didn't work . as if google map widget doesn't see it after it changes,
i also tried passing the longitude and latitudes using the navigator, with this the attributes does change in the google map but the dropdown menu stops showing the chosen item in the front.
i just want to change the google map depending on the choice of the dropdown menu.
heres my full code
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import '../widgets/My_wedgits.dart';
// shmalyh 3 LatLng(21.489191114466923, 39.24285294444855)
//shmalyh 1 LatLng( 21.490190928284374, 39.24029335794148)
//west 2 LatLng(21.489312801215913, 39.239637004938416)
//double lat = 21.48880614639443;
//double leng = 39.24159501940586;
String dropdownvalue = "";
const List<String> gatelist = <String>[
'NorthGate 1',
'NorthGate 3',
'WestGate 2'
];
class homepage extends StatefulWidget {
//const homepage({super.key});
double lat;
double lan;
homepage({Key? mykey, required this.lan, required this.lat})
: super(key: mykey);
#override
State<homepage> createState() => _homepageState();
}
class _homepageState extends State<homepage> {
DropdownButtonExample mydropdown = DropdownButtonExample();
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 60,
centerTitle: true,
title: const Text(
'Wajeeh',
style: TextStyle(
fontSize: 28,
),
),
elevation: 10,
backgroundColor: const Color.fromARGB(255, 4, 105, 55),
leading: Padding(
padding: const EdgeInsets.all(6.0),
child: Image.asset(
'images/logo2.png',
height: 30,
),
),
),
backgroundColor: Colors.white,
body: Column(
children: [
const SizedBox(
height: 70,
),
Row(
// ignore: prefer_const_literals_to_create_immutables
children: [
Expanded(
child: Align(
alignment: Alignment.topCenter,
child: SizedBox(
width: 250,
child: mydropdown,
),
)),
],
),
const SizedBox(
height: 45,
),
Row(
children: [
Expanded(
child: Column(
children: [
Image.asset('images/full.jpg'),
const Text(
'Total Parking',
style: TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 0, 0, 0)),
),
const Text(
'33',
style: TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 4, 105, 55)),
),
],
)),
Expanded(
child: Column(
children: [
Image.asset('images/remain.jpg'),
const Text(
'Available Parking',
style: TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 0, 0, 0)),
),
const Text(
"100",
style: TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 4, 105, 55)),
),
],
))
],
),
//here where the map should be
const SizedBox(
height: 70,
),
Row(
// ignore: prefer_const_literals_to_create_immutables
children: [
Expanded(
child: Align(
alignment: Alignment.topCenter,
child: SizedBox(
width: 355,
height: 315,
child: Stack(
children: [
GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(widget.lan, widget.lat),
zoom: 16,
),
),
Container(
alignment: Alignment.topLeft,
child: const Icon(
Icons.star,
color: Color.fromARGB(255, 231, 210, 23),
size: 40,
),
),
],
),
),
)),
],
),
],
));
}
// ignore: unused_element
}
class DropdownButtonExample extends StatefulWidget {
const DropdownButtonExample({super.key});
#override
State<DropdownButtonExample> createState() => _DropdownButtonExampleState();
/*Widget goodglemap() {
return GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(lat, leng),
zoom: 16,
),
);
}*/
}
class _DropdownButtonExampleState extends State<DropdownButtonExample> {
double lat = 21.48880614639443;
double leng = 39.24159501940586;
String dropdownValue = gatelist.first;
// ignore: avoid_print
#override
Widget build(BuildContext context) {
return DropdownButton<String>(
hint: const Text("Choose a Gate"),
isExpanded: true,
value: dropdownValue,
icon: const Icon(Icons.arrow_drop_down_sharp),
style: const TextStyle(color: const Color.fromARGB(255, 4, 105, 55)),
underline: Container(
height: 2,
color: const Color.fromARGB(255, 4, 105, 55),
),
onChanged: (String? value) {
// This is called when the user selects an item.
setState(() {
dropdownValue = value!;
//see if i can reach the other classs from here
if (identical(dropdownValue, "NorthGate 1")) {
lat = 21.490190928284374;
leng = 39.24029335794148;
}
//see if i can reach the other classs from here
if (identical(dropdownValue, "NorthGate 3")) {
lat = 21.489191114466923;
leng = 39.24285294444855;
}
if (identical(dropdownValue, "WestGate 2")) {
lat = 21.489312801215913;
leng = 39.239637004938416;
}
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => homepage(lat: lat, lan: leng)));
});
},
items: gatelist.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
),
);
}).toList(),
);
}
Widget goodglemap() {
return GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(lat, leng),
zoom: 16,
),
);
}
}
I am creating an app and I am working on the profile setup and am using a tabcontroller. I have my tabcontroller working to navigate my first 3 screens, but for some reason I get a "late initializtion" error for my last screen. I have a custom button that I use for each screen, and the error gets shown once I add the custom button to my last acrren. Could someone explain to me what I need to do to get it working for my last screen? I've attached my code for the tabcontroller, custom button, and my last screen:
Tabcontroller onboarding model:
class AccountOnboarding extends StatefulWidget {
const AccountOnboarding({Key? key}) : super(key: key);
#override
State<AccountOnboarding> createState() => _AccountOnboardingState();
}
class _AccountOnboardingState extends State<AccountOnboarding> {
static const List<Tab> tabs = <Tab>[
Tab(text: 'Name'),
Tab(text: 'Age and Profile'),
Tab(text: 'Bio and Interests'),
Tab(text: 'Selection')
];
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: tabs.length,
child: Builder(builder: (BuildContext context) {
final TabController tabController = DefaultTabController.of(context)!;
tabController.addListener(() {
if (!tabController.indexIsChanging) {}
});
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: const Color(0xff31708c),
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.transparent,
elevation: 0,
title: Row(
children: [
Expanded(
child: Image.asset('assets/images/Logo_Strength.png',
height: 50),
),
Expanded(
flex: 2,
child: RichText(
text: TextSpan(
style: GoogleFonts.montserrat(
fontSize: 30),
children: <TextSpan> [
TextSpan(text: 'Stren',
style: GoogleFonts.montserrat(
color: Colors.white,
fontWeight: FontWeight.bold,
letterSpacing: 1,
shadows: [
Shadow(
color: Colors.black.withOpacity(0.7),
offset: const Offset(1.5, 0.0))
])),
TextSpan(text: ';',
style: GoogleFonts.montserrat(
color: const Color(0xffef6a7a), fontWeight: FontWeight.bold,
letterSpacing: 1,
shadows: [
Shadow(
color: Colors.black.withOpacity(0.7),
offset: const Offset(1.5, 0.0))
])),
TextSpan(text: 'th',
style: GoogleFonts.montserrat(
color: Colors.white,
fontWeight: FontWeight.bold,
letterSpacing: 1,
shadows: [
Shadow(
color: Colors.black.withOpacity(0.7),
offset: const Offset(1.5, 0.0))
]))
],
),
),
),
],
)
),
body: TabBarView(
// physics: const NeverScrollableScrollPhysics(),
children: [
NamePage(tabController: tabController,),
ageAndPicture(tabController: tabController,),
bioAndInterests(tabController: tabController,),
SelectionPage(tabController: tabController,)
],
),
);
}));
}}
Custom Button:
class CustomButton extends StatelessWidget {
final TabController tabController;
const CustomButton({Key? key,
required this.tabController})
: super(key: key);
#override
Widget build(BuildContext context) {
return DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.white
),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(
vertical: 16),
elevation: 0,
primary: Colors.transparent
),
onPressed: () {
tabController.animateTo(tabController.index + 1);
},
child: Container(
width: double.infinity,
child: Center(
child: Text('Continue',
style: GoogleFonts.montserrat(
color: const Color.fromARGB(255, 20, 83, 106),
fontSize: 19,
fontWeight: FontWeight.w600
),),
),
)
),
);
}
}
Last Screen code:
class SelectionPage extends StatefulWidget {
final TabController tabController;
const SelectionPage({Key? key,
required this.tabController}) : super(key: key);
#override
_SelectionPageState createState() => _SelectionPageState();
}
class _SelectionPageState extends State<SelectionPage>{
List <Item>listOfModel = [];
late TabController tabController;
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
String retrieveString;
final data = ModalRoute.of(context)!.settings;
if (data.arguments == null) {
retrieveString = "empty";
} else {
retrieveString = data.arguments as String;
}
listOfModel.add(Item(title: "Maintaining healthy relationships"));
listOfModel.add(Item(title: "Stress and anxiety management"));
listOfModel.add(Item(title: "Maintaing a better work-life balance"));
listOfModel.add(Item(title: "Personal growth and development"));
listOfModel.add(Item(title: "Being happier and more content in life"));
listOfModel.add(Item(title: "Mental and emotional well-being"));
double _height = MediaQuery.of(context).size.height;
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: const Color(0xff31708c),
body: Padding(
padding: EdgeInsets.only(
left: 30,
right: 30,
top: _height * 0.07,
bottom: _height * 0.05),
child: Column(
children: [
Column(
children: [
Column(
children: <Widget>[
Text('Hello there $retrieveString! What all would you like to focus on?',
style: GoogleFonts.montserrat(
color: Colors.white70,
fontSize: 19,
fontWeight: FontWeight.w600
),
textAlign: TextAlign.center,),
const SizedBox(height: 10),
Text("You can pick all that apply:",
style: GoogleFonts.montserrat(
color: Colors.white70,
fontSize: 14.5,
fontWeight: FontWeight.w600
),),
const SizedBox(height: 15,),
GridView.count(
primary: true,
shrinkWrap: true,
padding: const EdgeInsets.all(10),
childAspectRatio: 1.15,
crossAxisCount: 2,
crossAxisSpacing: 25,
mainAxisSpacing: 25,
children: [
gridItem(listOfModel[0],MyFlutterApp.relationships),
gridItem(listOfModel[1],MyFlutterApp2.meditate),
gridItem(listOfModel[2],MyFlutterApp.balance),
gridItem(listOfModel[3],MyFlutterApp2.personal_growth),
gridItem(listOfModel[4],MyFlutterApp.happy),
gridItem(listOfModel[5],MyFlutterApp3.well_rounded),
],
),
const SizedBox(height: 18,),
],
),
CustomButton(tabController: tabController)
],
),
],
),
),
);
}
Widget gridItem(Item item, IconData icon){
return GestureDetector(
onTap: () {
setState(() {
item.isSelected = !item.isSelected;
});
},
child: Stack(
children: [Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: const Color.fromARGB(255, 20, 83, 106),
width: 2.5),
color: item.isSelected ? Color.fromARGB(255, 234, 188, 193) : Colors.white
),
child: Column(
children: [
Align(alignment: Alignment.topCenter,
child: Icon(
icon,
color: const Color(0xff31708c),
size: 45,
),
),
const SizedBox(height: 4,),
Text(item.title,
style: GoogleFonts.montserrat(
fontSize: 14,
fontWeight: FontWeight.w500,
color: const Color(0xff31708c)
),
textAlign: TextAlign.center,),
],
),
),
Positioned(
top: 0,
right: 0,
child: Offstage(
offstage: !item.isSelected,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 2.5),
shape: BoxShape.circle),
child: const Icon(
Icons.check,
color: Colors.green,
),
),
),
)
],
)
);
}
}
class Item{
String title;
bool isSelected;
Item({required this.title, this.isSelected = false});
}
Remove
late TabController tabController;
in SelectionPage and change
CustomButton(tabController: tabController)
in SelectionPage to
CustomButton(tabController: widget.tabController)
Need to display icon with checkmark based on a String value that comes dynamically.
Like
this image is its pending show first widget with tick and rest are blank.
if delivered show with tick and the rest are blank.
Facing problems in creating logic using enums.
Currently, it displays the icons on button clicks
based on four constants which is fine with the widget CheckStatus.
Need to make in a way based on a boolean check if it's true and pending that pending tick widget displayed
and similar with other values.
Here is the complete code for it currently.
import 'package:dotted_border/dotted_border.dart';
import 'package:dotted_line/dotted_line.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:matab/models/order.dart';
import 'package:matab/ui/general_widgets/check_status.dart';
import 'package:matab/ui/pages/styles.dart';
import '../../general_widgets/custom_gradient_button.dart';
class TrackOrder extends StatefulWidget {
const TrackOrder({Key? key, required this.order}) : super(key: key);
final Order order;
#override
State<TrackOrder> createState() => _TrackOrderState();
}
enum Status { Pending, Confirmed, Shipped, Received }
class _TrackOrderState extends State<TrackOrder> {
static const darkGreyColor = Colors.grey;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Center(child: Text('Track Order')),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => Get.back(),
),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 50),
Text(
"Order ID:" + widget.order.orderID,
style: const TextStyle(
color: darkGreyColor,
fontSize: 18,
fontWeight: FontWeight.bold),
),
const SizedBox(height: 50),
const Text('Sat, 12 Mar 2022',
style: TextStyle(
color: darkGreyColor,
fontSize: 18,
fontWeight: FontWeight.bold)),
const SizedBox(
height: 15,
),
Container(
margin: const EdgeInsets.fromLTRB(15, 0, 0, 0),
child: const Text('Estimated Time: 07 Days',
style: TextStyle(fontSize: 23, fontWeight: FontWeight.bold)),
),
const SizedBox(height: 30),
SizedBox(
width: 200,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
OrderStatusBar(title: widget.order.orderStatus, status: true),
dottedLine(),
OrderStatusBar(
title: widget.order.orderStatus, status: false),
dottedLine(),
OrderStatusBar(
title: widget.order.orderStatus, status: false),
dottedLine(),
OrderStatusBar(
title: widget.order.orderStatus, status: false),
],
),
),
const SizedBox(
height: 40,
),
Container(
margin: const EdgeInsets.fromLTRB(15, 0, 0, 0),
child: const Text('Shipping Address',
style: TextStyle(fontSize: 23, fontWeight: FontWeight.bold)),
),
Center(
child: Text(widget.order.deliveryAddress.address,
style: const TextStyle(
color: Colors.grey,
fontSize: 18,
fontWeight: FontWeight.bold)),
),
Center(
child: Padding(
padding: const EdgeInsets.all(
50.0,
),
child: CustomGradientButton(
buttonText: "Track Order".tr, buttonFunction: () => {}),
),
),
Center(
child: Padding(
padding: const EdgeInsets.only(top: 18.0),
child: GestureDetector(
child: Text(
'Back to Home'.tr,
style: TextStyle(
color: mainColor,
fontSize: 23,
fontWeight: FontWeight.bold),
),
onTap: () => {
Get.off(CheckStatus(
order: widget.order,
))
},
),
),
)
],
),
),
);
}
}
class OrderStatusBar extends StatefulWidget {
const OrderStatusBar({Key? key, required this.title, required this.status})
: super(key: key);
final String title;
final bool status;
#override
State<OrderStatusBar> createState() => _OrderStatusBarState();
}
class _OrderStatusBarState extends State<OrderStatusBar> {
#override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Row(
children: [
widget.status ? dottedCircleWithCheckMark() : dottedCircle(),
const SizedBox(width: 30),
Text(
widget.title.tr,
style: TextStyle(
fontSize: 20,
fontWeight: widget.status ? FontWeight.bold : null,
),
),
],
),
);
}
}
const size = 25.0;
const strokeWidth = 1.0;
const checkedColor = Color.fromRGBO(232, 113, 65, 1);
Widget dottedLine() {
return Directionality(
textDirection: TextDirection.rtl,
child: Align(
alignment: Alignment.topRight,
child: Container(
margin: const EdgeInsets.fromLTRB(0, 0, size / 2, 0),
child: const Padding(
padding: EdgeInsets.only(left: 27 / 2),
child: SizedBox(
height: size,
child: DottedLine(
dashColor: Colors.black,
direction: Axis.vertical,
lineLength: size,
lineThickness: strokeWidth,
dashLength: 5,
dashGapLength: 5,
),
),
),
),
),
);
}
dottedCircle() {
return DottedBorder(
borderType: BorderType.Circle,
dashPattern: const [5, 5],
child: Container(
height: size,
width: size,
decoration: const BoxDecoration(shape: BoxShape.circle),
));
}
dottedCircleWithCheckMark() {
return Container(
height: size + strokeWidth * 2,
width: size + strokeWidth * 2,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: checkedColor,
),
child: const Icon(
Icons.check,
color: Colors.white,
size: size / 4 * 3,
),
);
}
// ignore_for_file: constant_identifier_names
class CheckStatus extends StatefulWidget {
const CheckStatus({Key? key, required this.order}) : super(key: key);
final Order order;
#override
State<CheckStatus> createState() => _CheckStatusState();
}
class _CheckStatusState extends State<CheckStatus> {
int selectedItemIndex = 0;
var pending = Status.Pending;
List<bool> orderStatus = [true,true,true,false];
#override
void initState() {
// TODO: implement initState
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
for (int i = 0; i < Status.values.length; i++)
ElevatedButton(
onPressed: () {
selectedItemIndex = i;
setState(() {});
},
child: Text("Order Status ${Status.values[i]}"),
),
Row(
children: [
for (int i = 0; i <= selectedItemIndex; i++)
Container(
height: size + strokeWidth * 2,
width: size + strokeWidth * 2,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: checkedColor,
),
child: const Icon(
Icons.check,
color: Colors.white,
size: size / 4 * 3,
),
),
ElevatedButton(onPressed: () {}, child: Text("Back"))
],
)
],
),
);
}
}
I don't know how to do navigation bringing dynamic data.
This is my current code.
import 'package:bottom_bar_with_sheet/bottom_bar_with_sheet.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
iconTheme: IconThemeData(
color: Colors.blue,
),
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _bottomBarController = BottomBarWithSheetController(initialIndex: -1);
int selectedPosition = 4;
int _selectedIndex = -1;
#override
void initState() {
_bottomBarController.itemsStream.listen((i) {
if( i < 4 )
{
setState(() {
selectedPosition = -1;
_selectedIndex = i;
});
}
here would trigger the click of quick accesses, notes, profile, settings and alerts by BottomBarWithSheetItem
switch(i)
{
// case "HOME" : FutureBuilder: Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=> Home())); break;
case 0: print("Acesso rápido 0");break;
case 1: print("Acesso rápido 1");break;
case 2: print("Acesso rápido 2");break;
case 3: print("Acesso rápido 3");break;
}
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue,
body: Center(
child: Text(
"Criar navegacao aqui",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.w900,
),
),
),
bottomNavigationBar: BottomBarWithSheet(
selectedIndex:_selectedIndex,
controller: _bottomBarController,
bottomBarTheme: BottomBarTheme(
mainButtonPosition: MainButtonPosition.middle, // posicao do botao de 'mais -> (+)'
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(25)),
),
itemIconColor: Colors.grey,
itemTextStyle: TextStyle(
color: Colors.grey,
fontSize: 10.0,
),
selectedItemTextStyle: TextStyle(
color: Colors.blue,
fontSize: 10.0,
),
),
onSelectItem: (index) {
setState(() {
_selectedIndex = index;
});
},
sheetChild: Padding(
padding: EdgeInsets.only(top:10,bottom:6),
child:Column(
children: <Widget>[
Divider(
height: 10,
thickness: 2,
color: Colors.blue,
indent: 0,
),
Expanded(
child: GridView.count(
physics: NeverScrollableScrollPhysics(), //kill scrollable
// shrinkWrap: true,
crossAxisCount: 4,
children: <Widget>[
_createBottomBarSheetChild(context, 'Home', Icons.api_sharp, _routeMenu, 4),
_createBottomBarSheetChild(context, 'Produto', Icons.apartment, _routeMenu, 5),
_createBottomBarSheetChild(context, 'Cliente', Icons.person, _routeMenu, 6),
_createBottomBarSheetChild(context, 'Proposta', Icons.account_balance_wallet_outlined, _routeMenu, 7),
],
),
),
Expanded(
child: GridView.count(
physics: NeverScrollableScrollPhysics(), //kill scrollable
// shrinkWrap: true,
crossAxisCount: 4,
children: <Widget>[
_createBottomBarSheetChild(context, 'Reservas', Icons.add_location_rounded, _routeMenu, 8),
_createBottomBarSheetChild(context, 'Unidade', Icons.workspaces_filled, _routeMenu, 9),
_createBottomBarSheetChild(context, 'Contratos', Icons.work, _routeMenu, 10),
_createBottomBarSheetChild(context, 'Tarefas', Icons.calendar_today, _routeMenu, 11),
],
),
),
],
),
),
items: [
BottomBarWithSheetItem(label: "Notas",icon: Icons.notes),
BottomBarWithSheetItem(label: "Perfil",icon: Icons.account_circle),
BottomBarWithSheetItem(label: "Configurações",icon: Icons.settings),
BottomBarWithSheetItem(label: "Alertas",icon: Icons.add_alert),
],
),
);
}
#override
Widget _createBottomBarSheetChild(BuildContext context, String name, IconData icon, Function action, posicao)
{
return GestureDetector(
child: Card(
elevation: 0,
margin: EdgeInsets.only(
left: 3.0,
top: 25,
right: 3.0
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(
icon,
size: 26,
color: selectedPosition == posicao ? Colors.blue : Colors.grey,
),
Container(
margin: EdgeInsets.only(top: 4, bottom: 6, ),
child: Column(
children: [
Text(
name,
// textAlign: TextAlign.center,
style: TextStyle(
color: selectedPosition == posicao ?
Colors.blue :
Colors.grey,
),
),
Divider(
height: 16,
thickness: 2,
color: selectedPosition == posicao ? Colors.blue : Colors.grey,
indent: 30,
endIndent:30
),
],
)
),
],
),
),
onTap: () {
// Navigator.pop(context);
setState(() {
selectedPosition = posicao;
_bottomBarController.selectItem(posicao);
});
Navigator.of(context);
action(context, name, posicao);
},
);
}
here would trigger the click of the hidden buttons, such as product, home in the _createBottomBarSheetChild function
_routeMenu(context, rota, posicao)
{
print("rota ${rota.toUpperCase()}");
switch(rota.toUpperCase())
{
case "HOME" :""; posicao = 5;break;
case "PRODUTO":"";posicao = 6;break;
case "CLIENTE": "";posicao = 7; break;
case "PROPOSTA": "";posicao = 8; break;
case "RESERVA": "";posicao = 9; break;
case "UNIDADE": "";posicao = 10; break;
case "NOVIDADE": "";posicao = 11; break;
case "TAREFAS": "";posicao = 12; break;
}
}
}
I want to create a custom calendar, like this:
How can I do this?
You can design your own custom Calendar Widget as follows
import 'package:flutter/material.dart';
class Calendar extends StatefulWidget {
#override
_CalendarState createState() => _CalendarState();
}
class _CalendarState extends State<Calendar> {
DateTime selectedDate = DateTime.now(); // TO tracking date
int currentDateSelectedIndex = 0; //For Horizontal Date
ScrollController scrollController =
ScrollController(); //To Track Scroll of ListView
List<String> listOfMonths = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
];
List<String> listOfDays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
automaticallyImplyLeading: false,
title: Text('My Calendar'),
),
body: Column(
children: [
//To Show Current Date
Container(
height: 30,
margin: EdgeInsets.only(left: 10),
alignment: Alignment.centerLeft,
child: Text(
selectedDate.day.toString() +
'-' +
listOfMonths[selectedDate.month - 1] +
', ' +
selectedDate.year.toString(),
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w800,
color: Colors.indigo[700]),
)),
SizedBox(height: 10),
//To show Calendar Widget
Container(
height: 80,
child: Container(
child: ListView.separated(
separatorBuilder: (BuildContext context, int index) {
return SizedBox(width: 10);
},
itemCount: 365,
controller: scrollController,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () {
setState(() {
currentDateSelectedIndex = index;
selectedDate =
DateTime.now().add(Duration(days: index));
});
},
child: Container(
height: 80,
width: 60,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.grey[400],
offset: Offset(3, 3),
blurRadius: 5)
],
color: currentDateSelectedIndex == index
? Colors.black
: Colors.white),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
listOfMonths[DateTime.now()
.add(Duration(days: index))
.month -
1]
.toString(),
style: TextStyle(
fontSize: 16,
color: currentDateSelectedIndex == index
? Colors.white
: Colors.grey),
),
SizedBox(
height: 5,
),
Text(
DateTime.now()
.add(Duration(days: index))
.day
.toString(),
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.w700,
color: currentDateSelectedIndex == index
? Colors.white
: Colors.grey),
),
SizedBox(
height: 5,
),
Text(
listOfDays[DateTime.now()
.add(Duration(days: index))
.weekday -
1]
.toString(),
style: TextStyle(
fontSize: 16,
color: currentDateSelectedIndex == index
? Colors.white
: Colors.grey),
),
],
),
),
);
},
))),
],
),
));
}
}
Flutter Table Calendar
Fully Customisable as per requirement
You can copy paste run full code below
You can reference source code of package https://pub.dev/packages/calendar_timeline or directly use it
code snippet
CalendarTimeline(
initialDate: DateTime(2020, 2, 20),
firstDate: DateTime(2020, 2, 15),
lastDate: DateTime(2021, 11, 20),
onDateSelected: (date) => print(date),
leftMargin: 20,
monthColor: Colors.white70,
dayColor: Colors.teal[200],
//dayNameColor: Color(0xFF333A47),
activeDayColor: Colors.white,
activeBackgroundDayColor: Colors.redAccent[100],
dotsColor: Color(0xFF333A47),
selectableDayPredicate: (date) => date.day != 23,
),
working demo
full code
import 'package:calendar_timeline/calendar_timeline.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF333A47),
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16),
child: Text(
'Calendar Timeline',
style: Theme.of(context).textTheme.title.copyWith(color: Colors.tealAccent[100]),
),
),
CalendarTimeline(
initialDate: DateTime(2020, 2, 20),
firstDate: DateTime(2020, 2, 15),
lastDate: DateTime(2021, 11, 20),
onDateSelected: (date) => print(date),
leftMargin: 20,
monthColor: Colors.white70,
dayColor: Colors.teal[200],
//dayNameColor: Color(0xFF333A47),
activeDayColor: Colors.white,
activeBackgroundDayColor: Colors.redAccent[100],
dotsColor: Color(0xFF333A47),
selectableDayPredicate: (date) => date.day != 23,
),
],
),
),
);
}
}