Related
I am currently learning how to use the Bloc state management library in Flutter, and I have a scenario where I would like to listen to an action performed (e.g. Radio and dropDownButton).
I want to rebuild ui to with correct way to set state the new changes when press on Radio
this is code with cubit state management
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import '../../shared/styles/colors.dart';
import '../../shared/components/components.dart';
import 'cubit/registration_cubit.dart';
class RegistrationScreen extends StatelessWidget {
const RegistrationScreen({super.key});
#override
Widget build(BuildContext context) {
bool isKeyboard = MediaQuery.of(context).viewInsets.bottom != 0;
var size = MediaQuery.of(context).size;
List<Step> getSteps() => [
Step(
state: RegistrationCubit.get(context).currentStep > 0
? StepState.complete
: StepState.indexed,
title: const Text(""),
content: Form(
key: RegistrationCubit.get(context).formKey1,
child: Column(
children: [
SizedBox(
height: 60,
child: defaultFormField(
controller:
RegistrationCubit.get(context).fullNameController,
type: TextInputType.text,
label: 'الاسم الكامل',
prefix: Icons.face,
validate: (val) {
if (val!.isEmpty) {
return 'يجب إدخال الاسم الكامل';
}
return null;
}),
),
const SizedBox(
height: 4,
),
SizedBox(
height: 60,
child: defaultFormField(
controller:
RegistrationCubit.get(context).emailController,
type: TextInputType.emailAddress,
label: 'البريد الالكتروني',
prefix: Icons.email,
validate: (val) {
if (val!.isEmpty) {
return 'يجب إدخال البريد الالكتروني';
}
return null;
}),
),
const SizedBox(
height: 4,
),
SizedBox(
height: 60,
child: defaultFormField(
controller:
RegistrationCubit.get(context).userNameController,
type: TextInputType.text,
label: 'اسم المستخدم',
prefix: Icons.person,
validate: (val) {
if (val!.isEmpty) {
return 'يجب إدخال اسم المستخدم';
}
return null;
}),
),
const SizedBox(
height: 4,
),
SizedBox(
height: 60,
child: defaultFormField(
controller:
RegistrationCubit.get(context).passwordController,
type: TextInputType.visiblePassword,
label: 'كلمة المرور',
prefix: Icons.lock,
suffix: RegistrationCubit.get(context).suffix,
isPassword: RegistrationCubit.get(context).isPassword,
suffixPressed: () {
RegistrationCubit.get(context)
.changePasswordVisibility();
},
validate: (val) {
if (val!.isEmpty) {
return 'يجب إدخال كلمة المرور';
}
return null;
}),
),
Row(
children: [
const Spacer(),
Radio(
fillColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return primaryColor;
}
return Colors.black54;
}),
value: "male",
groupValue: RegistrationCubit.get(context).sex,
onChanged: (value) {
RegistrationCubit.get(context).changeRadio(
RegistrationCubit.get(context).sex,
value.toString());
},
),
const Text(
"ذكر",
style: TextStyle(fontSize: 15),
),
const Spacer(),
Radio(
fillColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return primaryColor;
}
return Colors.black54;
}),
value: "female",
groupValue: RegistrationCubit.get(context).sex,
onChanged: (value) {
// setState(() {
// sex = value.toString();
// });
},
),
const Text(
"أنثى",
style: TextStyle(fontSize: 15),
),
const SizedBox(width: 16),
const Spacer()
],
),
],
),
),
isActive: RegistrationCubit.get(context).currentStep >= 0),
Step(
state: RegistrationCubit.get(context).currentStep > 1
? StepState.complete
: StepState.indexed,
title: const Text(""),
content: Column(
children: [
const FittedBox(
fit: BoxFit.cover,
child: Text("■ هل لديك السماحية بحجز مناوبات عمليات : ",
style: TextStyle(
color: thirdColor,
fontWeight: FontWeight.normal,
fontSize: 20))),
Row(
children: [
const Spacer(),
Radio(
fillColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return primaryColor;
}
return Colors.black54;
}),
value: "yes",
groupValue: RegistrationCubit.get(context).operations,
onChanged: (value) {
// setState(() {
// operations = value.toString();
// });
},
),
const Text(
"نعم",
style: TextStyle(fontSize: 16),
),
const Spacer(),
Radio(
fillColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return primaryColor;
}
return Colors.black54;
}),
value: "no",
groupValue: RegistrationCubit.get(context).operations,
onChanged: (value) {
// setState(() {
// operations = value.toString();
// });
},
),
const Text(
"لا",
style: TextStyle(fontSize: 16),
),
const Spacer()
],
),
const SizedBox(height: 20),
const FittedBox(
fit: BoxFit.cover,
child: Text("■ هل لديك السماحية بحجز مناوبات قائد قطاع :",
style: TextStyle(
color: thirdColor,
fontWeight: FontWeight.normal,
fontSize: 20))),
Row(
children: [
const Spacer(),
Radio(
fillColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return primaryColor;
}
return Colors.black54;
}),
value: "yes",
groupValue: RegistrationCubit.get(context).opLeader,
onChanged: (value) {
// setState(() {
// opLeader = value.toString();
// });
},
),
const Text(
"نعم",
style: TextStyle(fontSize: 16),
),
const Spacer(),
Radio(
fillColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return primaryColor;
}
return Colors.black54;
}),
value: "no",
groupValue: RegistrationCubit.get(context).opLeader,
onChanged: (value) {
// setState(() {
// opLeader = value.toString();
// });
},
),
const Text(
"لا",
style: TextStyle(fontSize: 16),
),
const Spacer()
],
),
const SizedBox(height: 20),
const FittedBox(
fit: BoxFit.cover,
child: Text(
"■ قم باختيار المركز التابع إليه والرتبة : ",
style: TextStyle(
color: thirdColor,
fontWeight: FontWeight.normal,
fontSize: 20))),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
defaultDropdownButton(
context: context,
choice: RegistrationCubit.get(context).location,
label: "المركز",
list: RegistrationCubit.get(context).locationList,
onChange: (val) {
// setState(() {
// location = val.toString();
// });
}),
const SizedBox(width: 10),
defaultDropdownButton(
context: context,
choice: RegistrationCubit.get(context).rank,
label: "الرتبة",
list: RegistrationCubit.get(context).rankList,
onChange: (val) {
// setState(() {
// rank = val.toString();
// });
}),
],
),
const SizedBox(
height: 15,
)
],
),
isActive: RegistrationCubit.get(context).currentStep >= 1),
Step(
state: RegistrationCubit.get(context).currentStep > 2
? StepState.complete
: StepState.indexed,
title: const Text(""),
content: Column(
children: <Widget>[
CircleAvatar(
radius: 50.0,
backgroundColor: Colors.transparent,
child: RegistrationCubit.get(context).imageFile == null
? Image.asset('assets/images/id.png')
: Image.file(RegistrationCubit.get(context).imageFile!),
),
const SizedBox(
height: 10.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
buildButton(
height: 38,
fontSize: 16,
radius: 5,
width: 100,
text: "اختيار",
backgroundColor: secondaryColor,
borderColor: secondaryColor,
foregroundColor: Colors.black54,
function: () {
RegistrationCubit.get(context).getImage();
},
),
buildButton(
height: 38,
fontSize: 16,
radius: 5,
width: 100,
text: "تعليمات",
backgroundColor: secondaryColor,
borderColor: secondaryColor,
foregroundColor: Colors.black54,
function: () {},
),
],
),
const SizedBox(
height: 40.0,
),
SizedBox(
height: 60,
child: defaultFormField(
controller:
RegistrationCubit.get(context).phoneController,
type: TextInputType.phone,
label: 'رقم الموبايل',
prefix: Icons.call,
validate: (val) {
if (val!.isEmpty) {
return 'يجب إدخال رقم الموبايل';
}
return null;
})),
const SizedBox(
height: 10.0,
),
],
),
isActive: RegistrationCubit.get(context).currentStep >= 1),
];
return BlocConsumer<RegistrationCubit, RegistrationState>(
listener: (context, state) {},
builder: (context, state) {
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
backgroundColor: secondaryColor,
body: Stack(
alignment: Alignment.topCenter,
children: [
Container(
height: size.height * 0.4,
width: size.width,
decoration: const BoxDecoration(
color: primaryColor,
borderRadius: BorderRadiusDirectional.vertical(
bottom: Radius.circular(
25.0,
),
),
),
child: Padding(
padding: const EdgeInsets.only(top: 40, right: 10),
child: Align(
alignment: Alignment.topRight,
child: IconButton(
onPressed: () async {
FocusManager.instance.primaryFocus?.unfocus();
await Future.delayed(
const Duration(milliseconds: 100), () {
Navigator.pop(context);
});
},
icon: const Icon(
Icons.arrow_back,
size: 30,
color: Colors.white,
),
),
),
),
),
SizedBox(
height: size.height * 0.4 - 30,
child: Visibility(
visible: !isKeyboard,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
height: 90,
width: 90,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadiusDirectional.all(
Radius.circular(
20.0,
),
),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
"assets/images/logo.png",
),
),
),
const Text("تسجيل إشتراك",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 22)),
],
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 100),
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: !isKeyboard
? size.height * 0.4 - 175
: size.height * 0.4 - 250,
),
Container(
margin: const EdgeInsets.symmetric(horizontal: 30),
height: 455,
width: double.infinity,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadiusDirectional.all(
Radius.circular(
25.0,
),
),
),
child: Theme(
data: ThemeData(
fontFamily: GoogleFonts.cairo().fontFamily,
primarySwatch: Colors.red,
canvasColor: Colors.transparent,
colorScheme: const ColorScheme.light(
primary: primaryColor)),
child: Stepper(
physics: const NeverScrollableScrollPhysics(),
type: StepperType.horizontal,
elevation: 0,
steps: getSteps(),
currentStep:
RegistrationCubit.get(context).currentStep,
controlsBuilder: (BuildContext context,
ControlsDetails controls) {
final isLastStep =
RegistrationCubit.get(context)
.currentStep ==
getSteps().length - 1;
return Row(
children: <Widget>[
Expanded(
child: buildButton(
height: 38,
fontSize: 16,
radius: 5,
width: size.width,
text:
isLastStep ? "تأكيد" : "التالي",
backgroundColor: primaryColor,
borderColor: primaryColor,
foregroundColor: Colors.white,
function: () {
if (isLastStep) {
} else {
RegistrationCubit.get(context)
.changeCurrentStep(1);
}
}),
),
if (RegistrationCubit.get(context)
.currentStep !=
0)
const SizedBox(width: 12),
if (RegistrationCubit.get(context)
.currentStep !=
0)
Expanded(
child: buildButton(
height: 38,
fontSize: 16,
radius: 5,
width: size.width,
text: "رجوع",
backgroundColor: secondaryColor,
borderColor: secondaryColor,
foregroundColor: Colors.black54,
function: () {
if (RegistrationCubit.get(context)
.currentStep !=
0) {
RegistrationCubit.get(context)
.changeCurrentStep(-1);
}
},
),
),
],
);
},
),
)),
const SizedBox(
height: 30,
)
],
),
),
),
],
),
),
);
},
);
}
}
I was trying to show 2 dialog same time and when i open second dialog, its not focusing on the widget that was in second dialog, its focusing on the widget thats on first dialog that i have opened before.
Is this issue or am i not supposed to open 2 dialog at same time?
Here is video to the issue
Here is first dialog code
showDialog(
context: context,
builder: (_) =>
AlertDialog(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: 16,
height: 32,
decoration: BoxDecoration(
color: AppColors.colorFFBC99,
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(
width: 16,
),
Text(
S.addaRecipe,
style: Theme.of(context).textTheme.headlineSmall!.copyWith(
fontWeight: FontWeight.w600,
color: Colors.black,
),
),
],
),
SizedBox(
width: 300,
child: Row(
children: [
Text(
S.recipeBy,
style: Theme.of(context)
.textTheme
.labelLarge!
.copyWith(fontWeight: FontWeight.w500),
),
SizedBox(
width: 8,
),
Expanded(
child: CustomMyDropDownButton(label: 'dsfsdsf'),
),
],
),
)
],
),
content: Form(
// key: formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(
height: 16,
),
Text(
S.addPhotos,
style: Theme.of(context)
.textTheme
.labelLarge!
.copyWith(fontWeight: FontWeight.w500),
),
const SizedBox(
height: 8,
),
Container(
width: double.infinity,
// height: 200,
color: Colors.white,
child: Wrap(
children: [
for (int i = 0; i < 10; i++)
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
width: 200,
height: 200,
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(
S.recipeNetworkImage,
fit: BoxFit.cover,
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: () {},
child: Container(
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(8),
),
width: 200,
height: 200,
child: const Center(
child: Icon(
Icons.add,
size: 32,
),
),
),
),
),
],
),
),
const SizedBox(
height: 16,
),
CustomTextField(
showLabel: true,
// controller: textEditingController,
label: S.recipeName,
validator: (v) {
if (v!.isEmpty) {
return 'This field is required';
}
return null;
},
),
const SizedBox(
height: 16,
),
CustomTextField(
showLabel: true,
// controller: textEditingController,
label: S.description,
validator: (v) {
if (v!.isEmpty) {
return 'This field is required';
}
return null;
},
),
const SizedBox(
height: 32,
),
Row(
children: [
Text(
S.nutritionalInfo,
style: Theme.of(context)
.textTheme
.labelLarge!
.copyWith(fontWeight: FontWeight.w500),
),
IconButton(
onPressed: () {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: const Text(
S.addNutrition,
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: const [
CustomTextField(
showLabel: true,
label: S.name,
),
CustomTextField(
showLabel: true,
label: S.value,
),
],
),
actions: [
CustomOutlinedButton(
name: S.close,
onPress: () {
context.pop();
}),
CustomElevatedButton(
name: S.add,
onPress: () {},
),
],
),
);
},
icon: const Icon(Icons.add),
)
],
),
const SizedBox(
height: 8,
),
Container(
padding: EdgeInsets.all(8),
color: Colors.grey.shade100,
child: 1 == 1
? Text(
"Nutrition Info....",
)
: Column(
children: [
for (int i = 0; i < 0; i++)
ListTile(
leading:
Icon(Icons.horizontal_split_rounded),
title: Text('Calories'),
subtitle: Text('237'),
trailing: IconButton(
onPressed: () {},
icon: Icon(Icons.delete),
),
),
],
),
),
const SizedBox(
height: 32,
),
Text(
S.steps,
style: Theme.of(context)
.textTheme
.labelLarge!
.copyWith(fontWeight: FontWeight.w500),
),
const SizedBox(
height: 8,
),
Container(
color: AppColors.colorF4F4F4,
height: 300,
width: MediaQuery.of(context).size.width * .8,
child: HtmlEditor(
controller: HtmlEditorController(),
htmlEditorOptions: const HtmlEditorOptions(
hint: "Steps....",
),
otherOptions: const OtherOptions(
height: 400,
decoration: BoxDecoration(color: Colors.red)),
),
),
const SizedBox(
height: 32,
),
],
),
),
),
const SizedBox(
height: 32,
),
Stack(
children: [
Text(
'',
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Colors.red,
),
),
Text(
'',
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Colors.green,
),
),
],
),
],
),
),
actions: [
CustomOutlinedButton(
name: S.close,
onPress: () {
context.pop();
}),
CustomElevatedButton(
name: S.add,
onPress: () {},
),
],
);
Here is the code of second dialog show dialog
showDialog(
context: context,
builder: (_) => AlertDialog(
title: const Text(
S.addNutrition,
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: const [
CustomTextField(
showLabel: true,
label: S.name,
),
CustomTextField(
showLabel: true,
label: S.value,
),
],
),
actions: [
CustomOutlinedButton(
name: S.close,
onPress: () {
context.pop();
}),
CustomElevatedButton(
name: S.add,
onPress: () {},
),
],
),
);
Here is customtextfield code
import 'package:flutter/material.dart';
class CustomTextField extends StatefulWidget {
final String? label;
final TextEditingController? controller;
final String? Function(String?)? validator;
final Function(String?)? onSaved;
final bool showLabel;
final bool enableSuggestions;
final bool autocorrect;
final TextInputType? keyBoardType;
final Function(String)? onChange;
final bool showSuffixIcon;
const CustomTextField({
Key? key,
this.label,
this.controller,
this.validator,
this.onSaved,
this.enableSuggestions = true,
this.autocorrect = true,
this.keyBoardType,
this.onChange,
this.showSuffixIcon = false,
this.showLabel = false,
}) : super(key: key);
#override
State<CustomTextField> createState() => _CustomTextFieldState();
}
class _CustomTextFieldState extends State<CustomTextField> {
final textFieldFocusNode = FocusNode();
bool _obscured = false;
#override
void initState() {
// TODO: implement initState
if (widget.showSuffixIcon) {
_obscured = true;
}
super.initState();
}
void _toggleObscured() {
setState(() {
_obscured = !_obscured;
if (textFieldFocusNode.hasPrimaryFocus)
return; // If focus is on text field, dont unfocus
textFieldFocusNode.canRequestFocus =
false; // Prevents focus if tap on eye
});
}
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
widget.showLabel
? Text(
widget.label!,
style: Theme.of(context)
.textTheme
.labelLarge!
.copyWith(fontWeight: FontWeight.w500),
)
: const SizedBox(),
SizedBox(
height: widget.showLabel ? 8 : 0,
),
TextFormField(
controller: widget.controller,
validator: widget.validator,
onSaved: widget.onSaved,
onChanged: widget.onChange,
focusNode: textFieldFocusNode,
obscureText: _obscured,
enableSuggestions: widget.enableSuggestions,
autocorrect: widget.autocorrect,
keyboardType: widget.keyBoardType,
decoration: InputDecoration(
isDense: true,
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
borderSide: BorderSide(
color: Colors.black12,
),
),
focusedBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
borderSide: BorderSide(
color: Colors.black12,
),
),
errorBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
borderSide: BorderSide(
color: Colors.red,
),
),
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
borderSide: BorderSide(
color: Colors.black12,
),
),
labelText: widget.showLabel ? null : widget.label,
// labelStyle: CustomTextStyle.kTextStyle16400.copyWith(
// color: AppColors.textColor2,
// ),
suffixIcon: widget.showSuffixIcon
? Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 4, 0),
child: GestureDetector(
onTap: _toggleObscured,
child: Icon(
_obscured
? Icons.visibility_rounded
: Icons.visibility_off_rounded,
size: 24,
color: Colors.grey,
),
),
)
: null,
),
),
],
);
}
}
Try to add autofocus: true, on your CustomTextField. It should do handle rest I believe.
TextField(
autofocus: true,
);
I have a problem. I would like to use emoji_picker_flutter. This should be displayed under the TextInputField but is not displayed. What is the reason for this? Do I have to implement it differently or what is the reason? I tried to add the Config, but it did not change anything.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
import 'package:flutter/foundation.dart' as foundation;
import '../Model/ChatModel.dart';
class IndidivdualPage extends StatefulWidget {
final ChatModel chatModel;
const IndidivdualPage({Key? key, required this.chatModel}) : super(key: key);
#override
_IndividualPageState createState() => _IndividualPageState();
}
class _IndividualPageState extends State<IndidivdualPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(
leadingWidth: 70,
titleSpacing: 0,
leading: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.arrow_back, size: 24,),
CircleAvatar(
child: SvgPicture.asset(widget.chatModel.isGroup ? "assets/account-group.svg" : "assets/account.svg",
color: Colors.white, height: 34, width: 34),
radius: 20,
backgroundColor: Colors.lightBlue,
),
],
),
),
title: InkWell(
onTap: () {},
child: Container(
margin: EdgeInsets.all(6),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(widget.chatModel.name, style: TextStyle(
fontSize: 18.5,
fontWeight: FontWeight.bold
),),
Text("last seend today at 15:03", style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal
),)
],
),
),
),
actions: [
IconButton(onPressed: () {}, icon: Icon(Icons.videocam)),
IconButton(onPressed: () {}, icon: Icon(Icons.call)),
PopupMenuButton<String>(
onSelected: (value){
print(value);
},
itemBuilder: (BuildContext context){
return [
PopupMenuItem(child: Text("View Contact"), value:"View Contact",),
];
})
],
),
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Stack(
children: [
ListView(),
Align(
alignment: Alignment.bottomCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Row(
children: [
Container(
width: MediaQuery.of(context).size.width - 60,
child:
Card(
margin: EdgeInsets.only(left: 2, right: 2, bottom: 8),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),
child: TextFormField(
textAlignVertical: TextAlignVertical.center,
keyboardType: TextInputType.multiline,
maxLines: 5,
minLines: 1,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Send a message",
prefixIcon: IconButton(icon: Icon(Icons.emoji_emotions), onPressed: () { },),
suffixIcon: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(onPressed: () {}, icon: Icon(Icons.attach_file)),
IconButton(onPressed: () {}, icon: Icon(Icons.camera_alt)),
],
),
contentPadding: EdgeInsets.all(5),
),
),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 8, right: 5, left: 2),
child: CircleAvatar(
radius: 25,
backgroundColor: Colors.lightBlue,
child: IconButton(icon: Icon(Icons.mic),color: Colors.white, onPressed: () {},),
),
),
],
),
emojiSelect(),
],
)
)
],
),
),
);
}
Widget emojiSelect() {
return EmojiPicker(
onEmojiSelected: (Category? category, Emoji? emoji) {
print(emoji);
},
onBackspacePressed: () {
// Do something when the user taps the backspace button (optional)
}, // pass here the same [TextEditingController] that is connected to your input field, usually a [TextFormField]
config: Config(
columns: 7,
emojiSizeMax: 32 * (Platform.isIOS ? 1.30 : 1.0), // Issue: https://github.com/flutter/flutter/issues/28894
verticalSpacing: 0,
horizontalSpacing: 0,
gridPadding: EdgeInsets.zero,
initCategory: Category.RECENT,
bgColor: Color(0xFFF2F2F2),
indicatorColor: Colors.blue,
iconColor: Colors.grey,
iconColorSelected: Colors.blue,
backspaceColor: Colors.blue,
skinToneDialogBgColor: Colors.white,
skinToneIndicatorColor: Colors.grey,
enableSkinTones: true,
showRecentsTab: true,
recentsLimit: 28,
noRecents: const Text(
'No Recents',
style: TextStyle(fontSize: 20, color: Colors.black26),
textAlign: TextAlign.center,
), // Needs to be const Widget
loadingIndicator: const SizedBox.shrink(), // Needs to be const Widget
tabIndicatorAnimDuration: kTabScrollDuration,
categoryIcons: const CategoryIcons(),
buttonMode: ButtonMode.MATERIAL,
),
);
}
}
you need to set height for your emojiSelect like this:
SizedBox(height: 300, child: emojiSelect()),
So there are multiple errors shown when you try to run your code. If you scroll to the top there are a lot of indicators that something is wrong with the height of the view.
If you check the example provided within the library, you can see that the author wrapped the EmojiPicker with SizedBox.
If you do something similar to:
child: SizedBox(height: 250, child: EmojiPicker(...),)
it should help.
I'm new to flutter and creating a chat app similar to WhatsApp. I'm getting an overflow near the chat box when I implement the record button icon next to send Icon. how to get rid of this overflow. as I guess chat box width need to be decrease. not sure. how to overcome this. appreciate your help on this.
Container(
height: 60,
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(
width: size.width - 55,
child: Card(
margin:
const EdgeInsets.only(left: 2, right: 2, bottom: 8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25)),
child: TextField(
focusNode: forcusNode,
controller: _message,
keyboardType: TextInputType.multiline,
maxLines: 5,
minLines: 1,
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
border: InputBorder.none,
prefixIcon: IconButton(
onPressed: () {
forcusNode.unfocus();
forcusNode.canRequestFocus = false;
show = !show;
},
icon: Icon(
Icons.emoji_emotions,
color: textGrey,
)),
suffixIcon: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(
Icons.attach_file,
color: textGrey,
),
onPressed: () {
// getImage();
showModalBottomSheet(
context: context,
builder: (builder) =>
bottomsheet());
},
),
IconButton(
onPressed: () {},
icon: Icon(
Icons.camera_alt,
color: textGrey,
))
]),
hintText: 'Type Message',
),
),
),
),
IconButton(
onPressed: () {
onSendMessage();
print(_message.text);
},
icon: Icon(
Icons.send,
color: mainGreen,
)),
Container(
height: 30,
width: 30,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: mainGreen,
),
child: IconButton(
onPressed: () async {
await recorder.toggleRecording();
final isRecording = recorder.isRecording;
setState(() {});
if (isRecording) {
timerController.startTimer();
} else {
timerController.stoptTimer();
}
},
icon: Icon(icon, color: Colors.white,)
),
),
]),
),
This is an example, wrap all of them in Expanded and give them different flex values:
Container(
height: 60,
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
flex: 5,
child: Card(
margin:
const EdgeInsets.only(left: 2, right: 2, bottom: 8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25)),
child: TextField(
focusNode: forcusNode,
controller: _message,
keyboardType: TextInputType.multiline,
maxLines: 5,
minLines: 1,
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
border: InputBorder.none,
prefixIcon: IconButton(
onPressed: () {
forcusNode.unfocus();
forcusNode.canRequestFocus = false;
show = !show;
},
icon: Icon(
Icons.emoji_emotions,
color: textGrey,
)),
suffixIcon: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(
Icons.attach_file,
color: textGrey,
),
onPressed: () {
// getImage();
showModalBottomSheet(
context: context,
builder: (builder) =>
bottomsheet());
},
),
IconButton(
onPressed: () {},
icon: Icon(
Icons.camera_alt,
color: textGrey,
))
]),
hintText: 'Type Message',
),
),
),
),
Expanded(
flex: 1,
child: IconButton(
onPressed: () {
onSendMessage();
print(_message.text);
},
icon: Icon(
Icons.send,
color: mainGreen,
)),
),
Expanded(
flex: 1,
child: Container(
height: 30,
width: 30,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: mainGreen,
),
child: IconButton(
onPressed: () async {
await recorder.toggleRecording();
final isRecording = recorder.isRecording;
setState(() {});
if (isRecording) {
timerController.startTimer();
} else {
timerController.stoptTimer();
}
},
icon: Icon(icon, color: Colors.white,)
),
),
),
]),
),
when I click on address textformField then a open a alert dialog box,In this alert dialog box I have Dropdown, when i choose any dropdown item then that time not showing data, when i refresh the page then my data is showing on dropdown show.
This is my code
import 'dart:convert';
import 'dart:io';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:http_interceptor/http/intercepted_client.dart';
import 'package:image_picker/image_picker.dart';
import 'package:multi_image_picker2/multi_image_picker2.dart';
import 'package:readmore/readmore.dart';
import 'package:http/http.dart' as http;
class ViewEditProfile extends StatefulWidget {
const ViewEditProfile({Key? key}) : super(key: key);
#override
_ViewEditProfileState createState() => _ViewEditProfileState();
}
class _ViewEditProfileState extends State<ViewEditProfile> {
var _fullNameController = TextEditingController();
var _emailController = TextEditingController();
var _dobController = TextEditingController();
var _genderController = TextEditingController();
var _addressController = TextEditingController();
var _adharController = TextEditingController();
var _panController = TextEditingController();
var userPhoneNumber;
List? stateList = [];
List? districtList = [];
List? tehsilList = [];
List? villageList = [];
String? _selectedState;
String? _selectedDistrict;
String? _selectedTehsil;
String? _selectedVillage;
DatabaseService db = DatabaseService();
#override
void initState() {
// TODO: implement initState
super.initState();
// _loadSharedPrefs();
getGeoPointsDetailsUsingType();
// genderFunct();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbarNoSearch(),
body: SingleChildScrollView(
child: Container(
child: Column(
children: [
Container(
color: mPrimaryColor,
height: MediaQuery
.of(context)
.size
.height / 23,
width: MediaQuery
.of(context)
.size
.width,
child: Row(
children: [
SizedBox(
width: 15,
),
InkWell(
onTap: () {
Navigator.pop(context);
},
child: Container(
height: MediaQuery
.of(context)
.size
.height / 23,
width: 30,
child: Icon(
Icons.arrow_back_ios_rounded,
size: 20,
color: whitetext,
),
),
),
Expanded(
child: Text(
"VIEW EDIT PROFILE".tr(),
style: headingWhite(),
textAlign: TextAlign.center,
),
),
SizedBox(
width: 40,
)
],
),
),
Container(
height: MediaQuery
.of(context)
.size
.height / 3.9,
width: MediaQuery
.of(context)
.size
.width,
// width: 110,
// height: 110,
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: grey,
offset: const Offset(
0,
5.0,
),
blurRadius: 5.0,
spreadRadius: 0,
), //BoxShadow
BoxShadow(
color: Colors.white,
offset: const Offset(0.0, 0.0),
blurRadius: 0.0,
spreadRadius: 0.0,
), //BoxShadow
]),
child: Column(
children: [
Container(
padding: EdgeInsets.only(top: 7, right: 15),
child: GestureDetector(
onTap: () {
isEnableFun(context);
},
child: Container(
height: 24,
child: Align(
alignment: Alignment.topRight,
child: isEnable
? Text(
'UPDATE',
style: cardTitleGreen(),
)
: Text(
'EDIT',
style: cardTitleGreen(),
),
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: EdgeInsets.all(2),
width: 120,
height: 120,
decoration: BoxDecoration(
border:
Border.all(color: mPrimaryColor, width: 1.0),
borderRadius: BorderRadius.circular(60),
),
child: isEnable == false
? Container(
margin: EdgeInsets.all(1),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(60),
image: DecorationImage(
image: NetworkImage(
"https://www.aiyd.org/wp-content/uploads/2016/09/no-image-icon-hi-1.png"),
fit: BoxFit.cover)),
)
: Stack(
children: [
Container(
margin: EdgeInsets.all(1),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(60),
image: DecorationImage(
image: NetworkImage(
"https://www.aiyd.org/wp-content/uploads/2016/09/no-image-icon-hi-1.png"),
fit: BoxFit.cover)),
),
Positioned(
top: 0,
right: 0,
child: InkWell(
onTap: () {
// shopLogoLoadAssets();
getImage();
},
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
width: 4, color: Colors.white),
color: mPrimaryColor,
),
child: Icon(
Icons.edit,
color: Colors.white,
),
),
),
),
],
),
),
SizedBox(
width: 25,
),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
//star address part
Padding(
padding: const EdgeInsets.only(
top: 14, left: 23, right: 23),
child: Theme(
data: ThemeData(
disabledColor: cardTextbgYellow,
),
child: TextFormField(
readOnly: true,
controller: _addressController,
minLines: 2,
maxLines: 3,
keyboardType: TextInputType.multiline,
cursorColor: mPrimaryColor,
style: TextStyle(color: mPrimaryColor),
enabled: isEnable,
decoration: InputDecoration(
prefixIconConstraints: BoxConstraints(
minWidth: 23,
),
prefixIcon: Padding(
padding: const EdgeInsets.only(
right: 17,
),
child: Icon(
Icons.location_on_outlined,
color: mPrimaryColor,
),
),
hintText: "Your Address",
hintStyle: cardTitleGreen(),
enabledBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: cardTextbg.withOpacity(0.5)),
),
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: cardTextbg.withOpacity(0.5)),
),
),
onTap: () {
setState(() {
showAddressDialog();
});
},
),
),
),
//end address partpan part
SizedBox(
height: 20,
),
isEnable
? CustomButton(
text: "SAVE".tr(),
textColor: Colors.white,
gradient: buttongradient,
icon: Icons.arrow_forward_ios_outlined,
iconColor: Colors.white,
onPressed: () {},
)
: Container(),
SizedBox(
height: 20,
),
],
)
],),
] ),),]),)
)
,
);
}
getGeoPointsDetailsUsingType() async {
db.getGeoPointDetailsByType("State").then((onValue) =>
{
setState(() {
stateList = onValue;
print("line 1");
print("object::: " + stateList!.length.toString());
print("line 2");
})
});
}
getGeoPointsDetailsUsingId(String id, String type) async {
db.getGeoPointDetailsById(id).then((onValue) =>
{
print(type),
setState(() {
print("id:: " + id);
if (type == "District") {
districtList = onValue;
print("districtList:: " + districtList.toString());
} else if (type == "Tehsil") {
tehsilList = onValue;
} else if (type == "VillagePanchayat") {
villageList = onValue;
}
})
});
}
showAddressDialog() {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) =>
AlertDialog(
insetPadding: EdgeInsets.symmetric(horizontal: 10),
scrollable: true,
actions: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CustomButton2(
text: "OK",
onPressed: () {
Navigator.of(context).pop();
},
gradient: buttongradient,
)
],
)
],
content: Container(
width: MediaQuery
.of(context)
.size
.width,
child: Column(
children: [
Row(
children: [
Expanded(
child: Container(
height: 30,
padding:
EdgeInsets.only(top: 0, left: 4, bottom: 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8),
bottomLeft: Radius.circular(8)),
border: Border.all(
color: mPrimaryColorLight, width: 0.5)),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
focusColor: Colors.red,
hint: Text(
"State".tr(),
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
),
value: _selectedState,
isExpanded: true,
elevation: 2,
icon: Icon(
// Add this
Icons.arrow_drop_down, // Add this
color: mPrimaryColorLight, // Add this
),
items: stateList!.length > 0
? List.generate(
stateList!.length,
(index) =>
DropdownMenuItem<String>(
value:
"${stateList![index]['referenceId']}",
child: new Text(
stateList![index]['name'],
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
),
),
)
: ["Select State"].map((option) {
return DropdownMenuItem(
child: Text(
"$option",
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
),
value: option,
);
}).toList(),
onChanged: (String? val) {
setState(() {
_selectedState = val;
print(_selectedState);
if (stateList!.length > 0) {
getGeoPointsDetailsUsingId(
_selectedState!, "District");
}
});
},
),
),
),
),
Expanded(
child: Container(
height: 30,
padding:
EdgeInsets.only(top: 0, left: 4, bottom: 0),
decoration: BoxDecoration(
border: Border.all(
color: mPrimaryColorLight, width: 0.5)),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
focusColor: Colors.red,
hint: Text(
"District".tr(),
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
),
value: _selectedDistrict,
icon: Icon(
// Add this
Icons.arrow_drop_down, // Add this
color: mPrimaryColorLight, // Add this
),
isExpanded: true,
elevation: 2,
items: districtList!.length > 0
? List.generate(
districtList!.length,
(index) =>
DropdownMenuItem<String>(
value:
"${districtList![index]['referenceId']}",
child: new Text(
districtList?[index]['name'],
style: TextStyle(
fontSize: 13,
fontWeight:
FontWeight.w500),
overflow: TextOverflow.ellipsis,
),
))
: ["Select District"].map((option) {
return DropdownMenuItem(
child: Text(
"$option",
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
),
value: option,
);
}).toList(),
onChanged: (String? val) {
setState(() {
_selectedDistrict = val;
if (districtList!.length > 0) {
getGeoPointsDetailsUsingId(
_selectedDistrict!, "Tehsil");
}
});
},
),
),
),
),
Expanded(
child: Container(
height: 30,
padding:
EdgeInsets.only(top: 0, left: 4, bottom: 0),
decoration: BoxDecoration(
border: Border.all(
color: mPrimaryColorLight, width: 0.5)),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
focusColor: Colors.red,
hint: Text(
"Tehsil".tr(),
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
),
value: _selectedTehsil,
isExpanded: true,
elevation: 2,
icon: Icon(
// Add this
Icons.arrow_drop_down, // Add this
color: mPrimaryColorLight, // Add this
),
items: tehsilList!.length > 0
? List.generate(
tehsilList!.length,
(index) =>
DropdownMenuItem<String>(
value:
"${tehsilList![index]['referenceId']}",
child: new Text(
tehsilList![index]['name'],
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
)))
: ["Select Tehsil"].map((option) {
return DropdownMenuItem(
child: Text(
"$option",
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
),
value: option,
);
}).toList(),
onChanged: (String? val) {
setState(() {
_selectedTehsil = val;
if (tehsilList!.length > 0) {
getGeoPointsDetailsUsingId(
_selectedTehsil!, "VillagePanchayat");
}
});
},
),
),
),
),
Expanded(
child: Container(
height: 30,
padding:
EdgeInsets.only(top: 0, left: 4, bottom: 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(8),
bottomRight: Radius.circular(8)),
border: Border.all(
color: mPrimaryColorLight, width: 0.5)),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
focusColor: Colors.red,
hint: Text(
"Village".tr(),
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
),
value: _selectedVillage,
isExpanded: true,
elevation: 2,
icon: Icon(
// Add this
Icons.arrow_drop_down, // Add this
color: mPrimaryColorLight, // Add this
),
items: villageList!.length > 0
? List.generate(
villageList!.length,
(index) =>
DropdownMenuItem<String>(
value:
"${villageList![index]['referenceId']}",
child: new Text(
villageList![index]['name'],
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
)))
: ["Select Village"].map((option) {
return DropdownMenuItem(
child: Text(
"$option",
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
),
value: option,
);
}).toList(),
onChanged: (String? val) {
setState(() {
_selectedVillage = val;
// getGeoPointsDetailsUsingId(
// _selectedVillage!);
});
},
),
),
),
),
],
),
SizedBox(
height: 5,
),
],
),
),
));
}
}
Try to wrap your dialog with StatefulBuilder
StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
//Your AlertDialog
}