How to have custom color and border if selected - flutter

I wanted to implement a theme picker in my app so I made a dialog and got the title of the theme and the index with which it's going to be chosen class... now I want the dialog to show a border around the selected theme and show the background color of each theme
this is the code I use for the class:
class MultiThemeModel {
int index;
String themeName;
MultiThemeModel({required this.index, required this.themeName});
}
titlesForThemeModel(int index) {
switch (index) {
case 0:
return 'Luxury Purple';
case 1:
return 'Red Wine';
}
return 'No theme for index';
}
List<MultiThemeModel> get themes => List<MultiThemeModel>.generate(
2,
(index) =>
MultiThemeModel(index: index, themeName: titlesForThemeModel(index)));
List<Widget> get widgets => themes
.map((themeData) => MultipleThemeViewerWidget(themeData: themeData))
.toList();
what do I need to do to implement the features described above? I thought about maybe having a boolean and a color property in the class but I don't know how to map it and get it into the list... would be great to get some advice
thanks for the help in advance:)
Edit:
this is the Container for the colors:
class MultipleThemeViewerWidget extends StatelessWidget {
MultipleThemeViewerWidget({Key? key, required this.themeData})
: super(key: key);
final MultiThemeModel themeData;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
getThemeManager(context).selectThemeAtIndex(themeData.index);
},
child: Container(
height: 60,
width: 105,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).scaffoldBackgroundColor.withOpacity(.3),
border: Border.all(
color: Theme.of(context).scaffoldBackgroundColor, width: 3)),
child: Center(
child: Text(
themeData.themeName,
style: GoogleFonts.poppins(
textStyle: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Theme.of(context).scaffoldBackgroundColor,
),
),
),
),
),
);
}
}
this is the dialog I have for the implementation:
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
elevation: 1,
backgroundColor: Theme.of(context).indicatorColor,
insetAnimationCurve: Curves.decelerate,
child: SizedBox(
height: 170,
width: 320,
child: Stack(
children: [
Padding(
padding: const EdgeInsets.only(
top: 25,
left: 35,
right: 35,
),
child: Stack(
children: [
Container(
width: 250,
height: 30,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(90),
color: Colors.black,
),
),
GestureDetector(
onTap: () {
selected = false;
print(selected);
},
child: AnimatedContainer(
duration: const Duration(
milliseconds: 200,
),
width: 138,
height: 30,
decoration: BoxDecoration(
color: Theme.of(context)
.indicatorColor,
borderRadius:
BorderRadius.circular(90),
border: Border.all(
color: Colors.black,
width: 1,
),
),
child: Center(
child: Text(
'Light Mode',
style: GoogleFonts.poppins(
textStyle: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Colors.black,
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 112,
),
child: GestureDetector(
onTap: () {
setState(() {
selected = true;
print(selected);
});
},
child: AnimatedContainer(
duration: const Duration(
milliseconds: 200,
),
width: 138,
height: 30,
decoration: BoxDecoration(
color: selected
? Colors.black
: Colors.transparent,
borderRadius:
BorderRadius.circular(90),
),
child: Center(
child: Text(
'Dark Mode',
style: GoogleFonts.poppins(
textStyle: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
),
),
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(
top: 85,
left: 35,
right: 35,
),
child: SizedBox(
height: 60,
width: 250,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: widgets),
),
),
],
),
),
);
getThemeManager:
/// Returns the [ThemeManger] that
ThemeManager getThemeManager(BuildContext context) =>
Provider.of<ThemeManager>(context, listen: false);
class ThemeModel {
final ThemeData? selectedTheme;
final ThemeData? darkTheme;
final ThemeMode? themeMode;
ThemeModel({
required this.selectedTheme,
required this.darkTheme,
required this.themeMode,
});
}

Related

There is a space between my ListView and the Tiles

I am making and app using flutter and I was using a ListView togenerate the items but there is a gap between the List and the first Tile.
Already tried
Changing the size of the container that wraps around the listview
Removing the "header" with the title "ExercĂ­cios"
Removing the ClipRRect
class ExerciseList extends StatelessWidget {
final List<String> exercises;
const ExerciseList({Key? key, required this.exercises}) : super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding:
const EdgeInsets.only(top: 30, bottom: 20, right: 30, left: 30),
child: ClipRRect(
borderRadius: BorderRadius.circular(30),
child: Column(
children: [
Container(
width: MediaQuery.of(context).size.width,
decoration:
const BoxDecoration(
color: Color.fromARGB(255, 60, 60, 60)
),
child: const Padding(
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Text(
"ExercĂ­cios",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 32,
color: Colors.white
),
),
),
),
Container(
height: 300,
decoration:
const BoxDecoration(
color: Color.fromARGB(255, 65, 65, 65)
),
child: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Container(
decoration: const BoxDecoration(
border: Border(
top: BorderSide(
color: Colors.black,
width: 0.6
)
)
),
child: ListTile(
title: Text(
exercises[index],
style: const TextStyle(
fontSize: 22,
color: Colors.white,
),
),
),
);
},
itemCount: exercises.length,
),
),
],
),
)
);
}
}```
Based on the code you provided, not able to re-create the issue on my end.
Check your data List for any empty entries.

flutter how to display a list by scrolling

i want the popular menu to scroll down as i scroll on the whole page , not as it is right now scrolling only on that little part
its a Listview.builder inside a Listview
Demo : https://i.stack.imgur.com/TZ8xH.gif
here is the full code
its commented where the Listview and Listview.builder are
ctrl+f search this "//////" to quickly find them
import 'dart:async';
import 'package:custom_refresh_indicator/custom_refresh_indicator.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:foodninja/consts.dart';
import 'package:lottie/lottie.dart';
Color whiteBcg = const Color.fromARGB(255, 255, 255, 255);
Color limeColor = const Color.fromARGB(204, 77, 200, 118);
Color blackColor = Colors.black;
Color orangeInside = const Color.fromARGB(255, 210, 122, 0);
Color orangeOutside = const Color.fromARGB(45, 210, 123, 0);
Color cardBcg = const Color.fromRGBO(238, 238, 238, 1);
Color subText = const Color.fromARGB(255, 164, 164, 164);
class MyIconButton extends StatelessWidget {
const MyIconButton({
Key? key,
required this.icon,
required this.onClickAction,
}) : super(key: key);
final IconData icon;
final Function onClickAction;
#override
Widget build(BuildContext context) {
return Container(
height: 50,
width: 50,
decoration: BoxDecoration(
color: orangeOutside,
// border: Border.all(
// color: Colors.red,
// ),
borderRadius: BorderRadius.circular(15)),
child: TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
const Color.fromARGB(2, 255, 149, 0)),
),
onPressed: () => onClickAction(),
child: Icon(
icon,
color: orangeInside,
),
));
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
double h = MediaQuery.of(context).size.height;
double w = MediaQuery.of(context).size.width;
return Scaffold(
body: CustomRefreshIndicator(
onRefresh: () {
return Future(
() {},
);
},
builder: (
BuildContext context,
Widget child,
IndicatorController controller,
) {
return AnimatedBuilder(
animation: controller,
builder: (BuildContext context, _) {
return Stack(
children: <Widget>[
if (controller.isDragging ||
controller.isArmed ||
controller.isLoading)
Positioned(
left: w * 0.37,
top: controller.value * 50,
child: SizedBox(
height: 100,
width: 100,
child: Transform.translate(
offset: Offset(0, controller.value * 20),
child: Transform.scale(
scale: controller.value *1.5,
child:
Lottie.asset("assets/burgerBounce.json"))),
),
),
// if (controller.isArmed)
// Positioned(
// left: 0,
// top: 25 * controller.value,
// child: SizedBox(
// height: 100,
// width: 100,
// child: Lottie.asset("assets/icecream.json"),
// ),
// ),
Transform.translate(
offset: const Offset(0, 0),
child: child,
)
],
);
},
);
},
child: ListView(physics: const BouncingScrollPhysics(), children: [ ///////the list view
SafeArea(
child: Stack(children: [
SizedBox(
width: 500,
child: Image.asset(
'assets/PhoneVerificationPattern.png',
fit: BoxFit.fill,
),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
"Find your \nfavorite food",
style: TextStyle(
fontSize: 35, fontWeight: FontWeight.bold),
),
MyIconButton(
icon: Icons.notifications_none,
onClickAction: () {},
),
]),
const SizedBox(
height: 20,
),
Container(
alignment: Alignment.center,
height: 70,
width: w,
decoration: BoxDecoration(
color: orangeOutside,
// border: Border.all(
// color: Colors.red,
// ),
borderRadius: BorderRadius.circular(15)),
child: TextFormField(
style: TextStyle(color: orangeInside),
decoration: InputDecoration(
hintText: "what do you want to order ?",
hintStyle: TextStyle(color: orangeInside),
prefixIconColor: orangeInside,
fillColor: orangeInside,
focusColor: orangeInside,
border: InputBorder.none,
focusedBorder: InputBorder.none,
prefixIcon: Icon(
Icons.search,
color: orangeInside,
),
contentPadding:
EdgeInsets.fromLTRB(0, 14, 0, 0))),
),
const SizedBox(
height: 20,
),
PromoAdvert(h: h, w: w),
const SizedBox(
height: 15,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
"Nearest resturants",
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
RichText(
text: TextSpan(
children: [
TextSpan(
text: "View more",
style: TextStyle(
fontSize: 15,
color: orangeInside,
),
recognizer: TapGestureRecognizer()
..onTap = () {}),
],
),
),
],
),
const SizedBox(
height: 15,
),
NearestResturants(w: w, h: h),
const SizedBox(
height: 15,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
"Popular menu",
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
RichText(
text: TextSpan(
children: [
TextSpan(
text: "View more",
style: TextStyle(
fontSize: 15,
color: orangeInside,
),
recognizer: TapGestureRecognizer()
..onTap = () {}),
],
),
),
],
),
const SizedBox(
height: 20,
),
SizedBox(
height: 70,
width: 400,
child: ListView.builder( ////////////////List view builder where the problem is
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: 4,
itemBuilder: (context, index) => Container(
height: 70,
width: 400,
decoration: BoxDecoration(
color: cardBcg,
// border: Border.all(
// color: Colors.red,
// ),
borderRadius: BorderRadius.circular(15)),
child: Row(
children: [
Padding(
padding:
const EdgeInsets.fromLTRB(9, 5, 0, 5),
child: Container(
width: 50,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
nearestResturantsContentList[index]
.image,
),
),
borderRadius: BorderRadius.circular(15),
),
),
),
const SizedBox(
width: 20,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Fruit Salade ",
textAlign: TextAlign.start,
),
Text(
"Vegan resto",
textAlign: TextAlign.start,
style: TextStyle(color: subText),
),
],
),
const SizedBox(
width: 150,
),
Text(
"7\$",
textAlign: TextAlign.start,
style: TextStyle(
color: const Color.fromARGB(
255, 254, 171, 29),
fontSize: 23),
)
],
)),
),
),
],
),
)
]),
),
]),
),
);
}
}
class NearestResturantsContent {
late String image;
late String text;
late String subText;
NearestResturantsContent(
this.image,
this.text,
this.subText,
);
}
List<NearestResturantsContent> nearestResturantsContentList = [
NearestResturantsContent(
"assets/veganRestoLogo.png",
"veganResto",
"3KM",
),
NearestResturantsContent(
"assets/AjintiLogo.png",
"Ajinti",
"6KM",
),
NearestResturantsContent(
"assets/ChefGoLogo.png",
"ChefGo",
"10KM",
),
NearestResturantsContent(
"assets/BakeryLogo.png",
"Bakery",
"3KM",
),
NearestResturantsContent(
"assets/healthyFoodLogo.png",
"healthyFood",
"5KM",
),
NearestResturantsContent(
"assets/windowstoLogo.png",
"windowsto",
"3KM",
),
];
class NearestResturants extends StatelessWidget {
const NearestResturants({
Key? key,
required this.w,
required this.h,
}) : super(key: key);
final double w;
final double h;
#override
Widget build(BuildContext context) {
return SizedBox(
width: w,
height: h * 0.22,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: nearestResturantsContentList.length,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.fromLTRB(0, 0, 10, 0),
width: w * 0.4,
height: h * 0.22,
decoration: BoxDecoration(
color: cardBcg,
// border: Border.all(
// color: Colors.red,
// ),
borderRadius: BorderRadius.circular(15)),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
child: SizedBox(
height: 90,
width: 90,
child: Image.asset(
nearestResturantsContentList[index].image,
fit: BoxFit.fill,
),
),
),
Text(
nearestResturantsContentList[index].text,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
overflow: TextOverflow.ellipsis),
),
const SizedBox(
height: 5,
),
Text(
nearestResturantsContentList[index].subText,
style: TextStyle(
color: subText,
fontSize: 13,
fontWeight: FontWeight.bold,
overflow: TextOverflow.ellipsis),
),
],
),
);
},
),
);
}
}
class PromoAdvertContent {
late String image;
late String text;
late String subText;
late Color color;
PromoAdvertContent(this.image, this.text, this.subText, this.color);
}
List<PromoAdvertContent> promoAdvertContentList = [
PromoAdvertContent("assets/promoAdvert.png", "Special deal for \nOctober",
"Buy now", limeColor),
PromoAdvertContent("assets/promoAdvert.png", "Special deal for \nOctober",
"check out", orangeInside),
PromoAdvertContent(
"assets/promoAdvert.png", "No way this \nOctober", "check out", subText)
];
class PromoAdvert extends StatelessWidget {
const PromoAdvert({
Key? key,
required this.h,
required this.w,
}) : super(key: key);
final double h;
final double w;
#override
Widget build(BuildContext context) {
bool isScrollingToRight = true;
int currentPage = 0;
PageController scrollController = PageController(initialPage: 0);
void _scrollToBottom() {
if (currentPage < promoAdvertContentList.length && isScrollingToRight) {
currentPage++;
} else if (!isScrollingToRight && currentPage == 0) {
currentPage++;
isScrollingToRight = true;
} else {
isScrollingToRight = false;
currentPage--;
}
if (scrollController.hasClients) {
scrollController.animateToPage(
currentPage,
duration: const Duration(milliseconds: 1000),
curve: Curves.easeOut,
);
}
}
WidgetsBinding.instance.addPostFrameCallback(
(_) => Timer.periodic(const Duration(seconds: 15), (_) {
_scrollToBottom();
}));
return SizedBox(
width: w,
height: h * 0.217,
child: CustomRefreshIndicator(
onRefresh: () {
return Future(
() {},
);
},
builder: (
BuildContext context,
Widget child,
IndicatorController controller,
) {
return AnimatedBuilder(
animation: controller,
builder: (BuildContext context, _) {
return Stack(
children: <Widget>[
if (controller.isDragging ||
controller.isArmed ||
controller.isLoading)
Positioned(
left: 0,
top: h * 0.05,
child: SizedBox(
height: 100,
width: 100,
child: Transform.translate(
offset: Offset(-controller.value * 20, 0),
child: Transform.rotate(
angle: 11,
child: Lottie.asset("assets/icecream.json"))),
),
),
// if (controller.isArmed)
// Positioned(
// left: 0,
// top: 25 * controller.value,
// child: SizedBox(
// height: 100,
// width: 100,
// child: Lottie.asset("assets/icecream.json"),
// ),
// ),
Transform.translate(
offset: const Offset(0, 0),
child: child,
)
],
);
},
);
},
child: PageView.builder(
controller: scrollController,
physics: const BouncingScrollPhysics(),
scrollDirection: Axis.horizontal,
itemCount: promoAdvertContentList.length,
itemBuilder: (context, index) {
if (promoAdvertContentList.length == index) {
print('a"sqdqsqs');
CircularProgressIndicator();
}
return Container(
width: h * 0.47,
height: 160,
decoration: BoxDecoration(
color: promoAdvertContentList[index].color,
// border: Border.all(
// color: Colors.red,
// ),
borderRadius: BorderRadius.circular(15)),
child: Stack(children: [
SizedBox(
height: 160,
width: h * 0.47,
child: Image.asset(
promoAdvertContentList[index].image,
fit: BoxFit.fill,
),
),
Positioned(
top: 30,
right: 5,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
promoAdvertContentList[index].text,
style: TextStyle(
color: whiteBcg,
fontSize: 20,
fontWeight: FontWeight.bold),
),
const SizedBox(
height: 10,
),
NextButton(
h: h,
w: w,
text: promoAdvertContentList[index].subText,
)
],
))
]),
);
},
),
),
);
}
}
class NextButton extends StatelessWidget {
const NextButton({
Key? key,
required this.h,
required this.w,
required this.text,
}) : super(key: key);
final double h;
final double w;
final String text;
#override
Widget build(BuildContext context) {
return Center(
child: SizedBox(
height: 45,
width: 100,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
elevation: 5,
child: TextButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
)),
backgroundColor: MaterialStateProperty.all<Color>(whiteBcg)),
onPressed: () {},
child: Text(
text,
style: TextStyle(color: limeColor, fontSize: 15),
overflow: TextOverflow.ellipsis,
softWrap: false,
)),
),
),
);
}
}
To the list view that is scrolling separately add physics
physics: NeverScrollableScrollPhysics(),
And remove sized box which is wrapping the listview

Flutter GridView Item Selection Color Change (on tap)

I have created a GridView, and the next step I'm trying to achieve is changing the color of the container when it is tapped/ selected. When I try and do it with both Inkwell and GestureDetector, it changes the color of both containers in the row, rather than changing each one individually. I want to have each container change colors when it is tapped, as well as have a check mark appear on the corner:
(1) My Layout
(2) Example of what I want
I'm very new to Flutter, so I know that the way that I've coded my layout is far from optimal. I'm attaching a small chunk of just the GridView portion to show how I created the GridView (basically, I created 6 containers all with varying custom icons and text). Hopefully I'll receive some assistance :).
Updated June 21st:
class SelectionPage extends StatefulWidget {
const SelectionPage({Key? key}) : super(key: key);
#override
_SelectionPageState createState() => _SelectionPageState();
}
class Item{
String title;
bool isSelected;
Item({required this.title, this.isSelected = false});
List <Item>listOfModel = [];
listOfModel.add(Item(title: "Maintaining healthy relationships"));
listOfModel.add(Item(title: "Being happier and more content in life"));
}
class _SelectionPageState extends State<SelectionPage>{
Color _ContainerColor = Colors.white;
#override
Widget build(BuildContext) {
double _height = MediaQuery.of(context).size.height;
final data = ModalRoute.of(context)!.settings;
late String retrieveString;
if (data.arguments == null)
retrieveString = "empty";
else
retrieveString = data.arguments as String;
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: const Color(0xff31708c),
body: Padding(
padding: EdgeInsets.only(
left: 30,
right: 30,
top: _height * 0.2),
child: Column(
children: <Widget>[
Text('Hello there $data! What all would you like to focus on? You can pick all that apply:',
style: GoogleFonts.montserrat(
color: Colors.white70,
fontSize: 19,
fontWeight: FontWeight.w600
),
textAlign: TextAlign.center,),
const SizedBox(height: 12,),
Column(children: [
GridView.count(
primary: true,
shrinkWrap: true,
padding: const EdgeInsets.all(10),
childAspectRatio: 1.15,
crossAxisCount: 2,
crossAxisSpacing: 25,
mainAxisSpacing: 25,
children: <Widget>[
GestureDetector(
onTap: () {
setState(() {
_ContainerColor = _ContainerColor == Colors.white
? Color(0xffa1d0e6)
: Colors.white;
});
},
child: 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: _ContainerColor
),
child: Column(
children: [
const Align(alignment: Alignment.topCenter,
child: Icon(MyFlutterApp.relationships,
color: Color(0xff31708c),
size: 45,),
),
const SizedBox(height: 4,),
Text('Maintaining healthy relationships',
style: GoogleFonts.montserrat(
fontSize: 14,
fontWeight: FontWeight.w500,
color: const Color(0xff31708c)
),
textAlign: TextAlign.center,)
],
),
),
),
GestureDetector(
onTap: () {
setState(() {
_ContainerColor = _ContainerColor == Colors.white
? Color(0xffa1d0e6)
: Colors.white;
});
},
child: Container(
padding: const EdgeInsets.all(13.5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: const Color.fromARGB(255, 20, 83, 106),
width: 2.5),
color: Colors.white
),
child: Column(
children: [
const Align(alignment: Alignment.topCenter,
child: Icon(MyFlutterApp.happy,
color: Color(0xff31708c),
size: 30,),
),
const SizedBox(height: 12,),
Text('Being happier and more content in life',
style: GoogleFonts.montserrat(
fontSize: 14,
fontWeight: FontWeight.w500,
color: const Color(0xff31708c)
),
textAlign: TextAlign.center,)
],
),
),
),
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: Colors.white
),
child: Column(
children: [
const Align(alignment: Alignment.topCenter,
child: Icon(MyFlutterApp.balance,
color: Color(0xff31708c),
size: 40,),
),
const SizedBox(height: 8,),
Text('Maintaining a better work-life balance',
style: GoogleFonts.montserrat(
fontSize: 14,
fontWeight: FontWeight.w500,
color: const Color(0xff31708c)
),
textAlign: TextAlign.center,)
],
),
),
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: const Color.fromARGB(255, 20, 83, 106),
width: 2.5),
color: Colors.white
),
child: Column(
children: [
const Align(alignment: Alignment.topCenter,
child: Icon(MyFlutterApp2.personal_growth,
color: Color(0xff31708c),
size: 35,),
),
const SizedBox(height: 10,),
Text('Personal growth and development',
style: GoogleFonts.montserrat(
fontSize: 14,
fontWeight: FontWeight.w500,
color: const Color(0xff31708c)
),
textAlign: TextAlign.center,)
],
),
),
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: Colors.white
),
child: Column(
children: [
const Align(alignment: Alignment.topCenter,
child: Icon(MyFlutterApp2.meditate,
color: Color(0xff31708c),
size: 45,),
),
const SizedBox(height: 4,),
Text('Stress and anxiety management',
style: GoogleFonts.montserrat(
fontSize: 14,
fontWeight: FontWeight.w500,
color: const Color(0xff31708c)
),
textAlign: TextAlign.center,)
],
),
),
Container(
padding: const EdgeInsets.all(11),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: const Color.fromARGB(255, 20, 83, 106),
width: 2.5),
color: Colors.white
),
child: Column(
children: [
const Align(alignment: Alignment.topCenter,
child: Icon(MyFlutterApp3.well_rounded,
color: Color(0xff31708c),
size: 37,),
),
const SizedBox(height: 10,),
Text('Mental and emotional well-being',
style: GoogleFonts.montserrat(
fontSize: 14,
fontWeight: FontWeight.w500,
color: const Color(0xff31708c)
),
textAlign: TextAlign.center,)
],
),
),
],
),]),
const SizedBox(height: 17,),
ElevatedButton(
onPressed: () {
Navigator.push(context,
PageTransition(
type: PageTransitionType.bottomToTop,
duration: const Duration(milliseconds: 650),
child: const LoginScreen2() // CHANGE THIS AS SOON AS YOU CAN FIGURE SOMETHING OUT
));
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 88,
vertical: 16),
primary: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)
)
),
child: Text(
'Continue',
style: GoogleFonts.montserrat(
color: const Color.fromARGB(255, 20, 83, 106),
fontSize: 19,
fontWeight: FontWeight.w600
),
),)
],
),
),
);
}
}
Hey you can create a model with 2 variables String title and bool isSelected. If you need you can add icon in item model also -
See below updated code-
class SelectionPage extends StatefulWidget {
const SelectionPage({Key? key}) : super(key: key);
#override
_SelectionPageState createState() => _SelectionPageState();
}
class _SelectionPageState extends State<SelectionPage>{
// Color _ContainerColor = Colors.white;
late String retrieveString;
List <Item>listOfModel = [];
#override
void initState() {
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: "Being happier and more content in life"));
super.initState();
}
#override
Widget build(BuildContext context) {
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.2),
child: Column(
children: <Widget>[
Text('Hello there $data! What all would you like to focus on? You can pick all that apply:',
style: GoogleFonts.montserrat(
color: Colors.white70,
fontSize: 19,
fontWeight: FontWeight.w600
),
textAlign: TextAlign.center,),
const SizedBox(height: 12,),
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],MyFlutterApp.relationships ),
],
),
const SizedBox(height: 17,),
ElevatedButton(
onPressed: () {
Navigator.push(context,
PageTransition(
type: PageTransitionType.bottomToTop,
duration: const Duration(milliseconds: 650),
child: const LoginScreen2() // CHANGE THIS AS SOON AS YOU CAN FIGURE SOMETHING OUT
));
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 88,
vertical: 16),
primary: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)
)
),
child: Text(
'Continue',
style: GoogleFonts.montserrat(
color: const Color.fromARGB(255, 20, 83, 106),
fontSize: 19,
fontWeight: FontWeight.w600
),
),)
],
),
),
);
}
Widget gridItem(Item item, IconData icon){
return GestureDetector(
onTap: () {
setState(() {
item.isSelected = !item.isSelected;
});
},
child: 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 ? const Color(0xffa1d0e6) : 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,)
],
),
),
);
}
}
class Item{
String title;
bool isSelected;
Item({required this.title, this.isSelected = false});
}

How to fetch values from a form in flutter?

As per the image I have to fetch all the values from the required field i.e. from the TextFormField, CustomRadioButton & as well as from the patient age as per my requirement. On click of submit button I have to fetch those values so that I can pass them through the provider.
As I am very new to flutter, I can fetch the value from the TextFormField but couldnot able to fetch from rest of the two.
here is my UI below.
below is the code for CustomRadioButton
Container(
width: 200,
child: CustomRadioButton(
customShape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
elevation: 0,
absoluteZeroSpacing: false,
unSelectedColor: Theme.of(context).canvasColor,
buttonLables: [
'Male',
'Female',
],
buttonValues: [
"MALE",
"FEMALE",
],
buttonTextStyle: ButtonTextStyle(
textStyle: TextStyle(fontSize: 10)),
radioButtonValue: (value) {
print(value);
},
width: 80,
height: 60,
enableShape: true,
selectedBorderColor: Colors.green,
unSelectedBorderColor: Color(0xFFD0D7EB),
selectedColor: Colors.green,
),
),
for the age picker(/do not know I am correct or not because I had just hardcoded the text 12, but want + and - should work./)
Container(
width: 100.0,
height: 55.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
border: Border.all(
color: Color(0xFFD0D7EB),
)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
InkWell(
onTap: () {},
child: Container(
height: 25.0,
width: 25.0,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(7.0),
border: Border.all(
color: Color(0xFFD0D7EB),
)
),
child: Center(
child: Icon(
Icons.remove,
color: Colors.black,
size: 20.0,
),
),
),
),
Text(
'12',
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 20.0,
color: Colors.black),
),
InkWell(
onTap: () {},
child: Container(
height: 25.0,
width: 25.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7.0),
border: Border.all(
color: Color(0xFFD0D7EB),
)
),
child: Center(
child: Icon(
Icons.add,
color: Colors.black,
size: 20.0,
),
),
),
)
],
),
)
],
),
SizedBox(height: 80),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
height: 40,
child: RaisedButton(
color: Color(0xFF888DA1),
child: Text('Submit', style: TextStyle(fontFamily: 'Poppins-Regular',
fontSize: 14, color: Colors.white)),
onPressed: (){
submit();
}
),
),
],
This one is the function where I will fetch those values
submit() async{
print(nameController.text);
}
Please help me how to do this!
So here what i do first set defaultSelected: "MALE", and then store value in one variable and when you change the value then you
get this value from radioButtonValue: this method then simply add this value to my local variable. After that for age i only added simple
increment and decrement logic and set this value to text
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
accentColor: Colors.blue,
),
home: SelectionScreen(),
);
}
}
class SelectionScreen extends StatefulWidget{
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _selectionScreen();
}
}
class _selectionScreen extends State<SelectionScreen>{
var gender = "MALE";
int age = 12;
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Container(
color: Colors.white,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(
children: [
Container(
width: 200,
child: CustomRadioButton(
customShape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
elevation: 0,
absoluteZeroSpacing: false,
unSelectedColor: Theme.of(context).canvasColor,
buttonLables: [
'Male',
'Female',
],
buttonValues: [
"MALE",
"FEMALE",
],
buttonTextStyle: ButtonTextStyle(
textStyle: TextStyle(fontSize: 10)),
radioButtonValue: (value) {
setState(() {
gender = value.toString();
print("=--->>${gender}");
});
},
width: 80,
height: 60,
enableShape: true,
selectedBorderColor: Colors.green,
unSelectedBorderColor: Color(0xFFD0D7EB),
selectedColor: Colors.green,
defaultSelected: "MALE",
),
),
Container(
width: 100.0,
height: 55.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
border: Border.all(
color: Color(0xFFD0D7EB),
)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
InkWell(
onTap: () {
setState(() {
age--;
});
},
child: Container(
height: 25.0,
width: 25.0,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(7.0),
border: Border.all(
color: Color(0xFFD0D7EB),
)
),
child: Center(
child: Icon(
Icons.remove,
color: Colors.black,
size: 20.0,
),
),
),
),
Text(
age.toString(),
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 20.0,
color: Colors.black),
),
InkWell(
onTap: () {
setState(() {
age++;
});
},
child: Container(
height: 25.0,
width: 25.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7.0),
border: Border.all(
color: Color(0xFFD0D7EB),
)
),
child: Center(
child: Icon(
Icons.add,
color: Colors.black,
size: 20.0,
),
),
),
)
],
),
),
SizedBox(height: 80),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
height: 40,
child: RaisedButton(
color: Color(0xFF888DA1),
child: Text('Submit', style: TextStyle(fontFamily: 'Poppins-Regular',
fontSize: 14, color: Colors.white)),
onPressed: (){
print("============>> Radio Button Value: $gender");
print("============>> Age: $age");
}
),
),
],),
],
),),
);
}
}
The most direct way is to build a model class that will have the default values for each form element. Then, when building the form, construct an instance of the form data class, and use the members to establish the value: for each item. Wire up each of the onChanged: callbacks to validate the new value, and store it back into the form data instance. On submit, send the data along its merry way.

Flutter - Align widget all the way to the end of a card view. (View image included)

how can I get the flat button to fill the area under the divider all the way to the end of the card, it appears to not be able to go any further down.
See the white space under the FlatButton? I want it to look like the FlatButton is the end.
Doesn't have to be a flat button, any widget with onTap/press/(or a something hack-ish with gesture detector) listener would be fine.
Dart code is ->
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(4.0),
child: Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15))
),
child: Container(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 24, bottom: 16),
child: Text(_label, style: TextStyle(fontSize: 24, color: Color.fromARGB(190, 0, 0, 0), fontWeight: FontWeight.bold)),
),
Divider(color: Colors.black26, height: 2,),
Padding(
padding: const EdgeInsets.all(24.0),
child: Text(_information, style: TextStyle(fontSize: 20, color: Colors.black87)),
),
Divider(color: Colors.black26, height: 2,),
SizedBox(width: double.infinity, child: FlatButton(onPressed: () => _onTap(), color: Color.fromARGB(50, 100, 100, 100), child: Text('Done', style: TextStyle()), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5))))
],
),
),
),
);
}
Please see the code below, I'm using InkWell & Container :
import 'package:flutter/material.dart';
final Color darkBlue = const Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
//theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
String _label = "";
String _information = "";
return Padding(
padding: const EdgeInsets.all(4.0),
child: Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15))),
child: Container(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 24, bottom: 16),
child: Text(_label,
style: TextStyle(
fontSize: 24,
color: Color.fromARGB(190, 0, 0, 0),
fontWeight: FontWeight.bold)),
),
Divider(
color: Colors.black26,
height: 2,
),
Padding(
padding: const EdgeInsets.all(24.0),
child: Text(_information,
style: TextStyle(fontSize: 20, color: Colors.black87)),
),
Divider(
color: Colors.black26,
height: 2,
),
Spacer(),
InkWell(
onTap: () {}, //_onTap(),
child: Container(
width: double.infinity,
height: 40,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: const Color.fromARGB(50, 100, 100, 100)),
child: const Center(child: Text('Done', style: TextStyle())),
),
)
],
),
),
),
);
}
}
I solved my code like this, setting a height factor it did what i wanted automatically.
SizedBox(width: double.infinity, height: 60, child:
FlatButton(onPressed: () => _onTap(), color: Colors.transparent, child:
Text('Done', style: TextStyle()), shape: RoundedRectangleBorder(borderRadius:
BorderRadius.only(bottomLeft: Radius.circular(15), bottomRight: Radius.circular(15)))))
Only downside is that you have to specify a height rather than letting the widget adjust that based on content. Although there is probably a workaround for that.