I'm using chips in my code when I tap on chip a counter is displayed, I want to update the chip label with when count is added.
Widget returnWidget() {
return InkWell(
child: Chip(
label: Text(temp!),
),
onTap: () {
print(temp);
_showMyDialog();
},
);
}
This is the widget I'm using to add multiple chips.
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
scrollable: false,
title: const Text('Add Count'),
content: Container(
height: 50,
width: 50,
alignment: Alignment.center,
padding: const EdgeInsets.all(3),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
AddCount(),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('Cancel'),
onPressed: () {
{
setState(() {
_itemCount = 0;
});
}
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Add'),
onPressed: () {
if(count==0) {
setState((){
temp = temp! + _itemCount.toString();
Text(temp!);
count++;
});
}
print(text);
},
),
],
);
},
);
}
This is the code block which is showing a counter dialog. I want to update chip label on add.
Hello here I have a solution, I did not see more details about your code but here I did a working solution, the variable you want to update should be located inside the classed where is used but you can also use state management or InheritedWidget to update variables globally:
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Example(),
);
}
}
class Example extends StatefulWidget {
const Example({Key? key}) : super(key: key);
#override
State<Example> createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
int temp = 0; // declare the variable inside the class you want to update it
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
scrollable: false,
title: const Text('Add Count'),
content: Container(
height: 50,
width: 50,
alignment: Alignment.center,
padding: const EdgeInsets.all(3),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
// AddCount(),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Add'),
onPressed: () {
setState((){
temp = temp += 1; // update the chip UI
});
Navigator.of(context).pop();
},
),
],
);
},
);
}
Widget returnWidget() {
return InkWell(
child: Chip(
label: Text("count $temp"), // <-- new change
),
onTap: () {
print(temp);
_showMyDialog();
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.red,
body: Center(
child: Container(
margin: const EdgeInsets.all(32),
child: returnWidget(),
),
),
);
}
}
Related
I'm creating a reset password page for my flutter app and I'm using showDialog for giving the feedback to the user to, but while running the code the message does not appear in screen, kindly check the code and tell me is there any mistate which I have made.
If anyone know the solution please help, I was trying to solve it but I can't find any solution.
The code is below:
class ForgotPasswordMailScreen extends StatefulWidget {
const ForgotPasswordMailScreen({Key? key}) : super(key: key);
#override
State<ForgotPasswordMailScreen> createState() =>
_ForgotPasswordMailScreenState();
}
final TextEditingController _email = TextEditingController();
class _ForgotPasswordMailScreenState extends State<ForgotPasswordMailScreen> {
final formKey = GlobalKey<FormState>();
bool loading = false;
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(
Icons.arrow_back_ios_new,
color: Colors.blue,
),
),
),
body: SingleChildScrollView(
child: Container(
padding: const EdgeInsets.all(kDefaultSize),
child: Column(
children: [
const SizedBox(height: kDefaultSize * 4),
const FormHeaderWidget(
image: kForgotPasswordImage,
title: kForgotPassword,
subTitle: kForgotEmailTitle,
crossAxisAlignment: CrossAxisAlignment.center,
heightBetween: 10.0,
textAlign: TextAlign.center,
),
const SizedBox(height: kFormHeight),
Form(
key: formKey,
child: Column(
children: [
TextFormField(
controller: _email,
validator: (value) {
if (value!.isEmpty ||
!RegExp(r'^[\w-\.]+#([\w-]+\.)+[a-z]{2,5}$')
.hasMatch(value)) {
return 'Enter a valid email address.';
} else {
return null;
}
},
decoration: const InputDecoration(
label: Text(kEmail),
hintText: kEmail,
prefixIcon: Icon(Icons.mail_outline_rounded),
),
),
const SizedBox(height: 20.0),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () async {
if (formKey.currentState!.validate()) {
resetPassword();
formKey.currentState?.reset();
// _email.clear();
}
},
child: const Text(kNext),
),
),
],
),
),
],
),
),
),
),
);
}
// showLoadingScreen() {}
showMessage() {
showDialog(
context: context,
builder: (context) {
return const AlertDialog(
content: Text('Password reset link sent! Check your email.'),
);
});
}
showErrorMessage(String eMsg) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(eMsg),
);
});
}
resetPassword() async {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => const Center(
child: CircularProgressIndicator(),
),
);
try {
await FirebaseAuth.instance
.sendPasswordResetEmail(email: _email.text.trim())
.then((value) {
Navigator.pop(context);
});
showMessage();
} on FirebaseAuthException catch (e) {
String error = e.message.toString();
showErrorMessage(error);
Navigator.pop(context);
}
}
}
I am trying to select one item from phone contacts list (List view widget)
class PhoneContacts extends StatefulWidget {
const PhoneContacts({Key? key}) : super(key: key);
#override
State<PhoneContacts> createState() => _PhoneContactsState();
}
class _PhoneContactsState extends State<PhoneContacts> {
List<Contact> _contacts = [];
late PermissionStatus _permissionStatus;
late Customer _customer;
#override
void initState(){
super.initState();
getAllContacts();
}
void getAllContacts() async {
_permissionStatus = await Permission.contacts.request();
if(_permissionStatus.isGranted) {
List<Contact> contacts = await ContactsService.getContacts(withThumbnails: false);
setState(() {
_contacts = contacts;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Phone Contacts"),
backgroundColor: Colors.indigo[600],
),
body: Container(
padding: const EdgeInsets.all(5),
child: ListView.builder(
itemCount: _contacts.length,
itemBuilder: (BuildContext context, int index) {
Contact contact = _contacts[index];
return contactItem(contact);
}
),
),
);
}
Widget contactItem(Contact contact){
return ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>Dashboard(contact)));
},
leading: const CircleAvatar(
backgroundColor: Colors.pinkAccent,
child: Icon(Icons.person_outline_outlined)),
title : Text(contact.displayName.toString()),
subtitle: Text(contact.phones!.first.value.toString()),
);
}
}
and insert and display it to dashboard list (another List view widget)
class Dashboard extends StatefulWidget {
final Contact? contact;
const Dashboard([this.contact]);
#override
State<Dashboard> createState() => _DashboardState();
}
class _DashboardState extends State<Dashboard> {
final Color? themeColor = Colors.indigo[600];
late GlobalKey<RefreshIndicatorState> refreshKey;
late List<CardGenerator> existingCustomerContactList = getCustomerContactList();
#override
void initState(){
super.initState();
refreshKey=GlobalKey<RefreshIndicatorState>();
}
void addCustomerContact() {
existingCustomerContactList.add(
CardGenerator(
Text(widget.contact!.displayName.toString()),
const Icon(Icons.account_circle),
Text(widget.contact!.phones!.first.value.toString())));
}
List<CardGenerator> getCustomerContactList () {
existingCustomerContactList = [
CardGenerator(
const Text('Dave', style: TextStyle(fontSize: 24.0), textAlign: TextAlign.start,),
const Icon(Icons.account_circle, size: 100, color: Colors.white,),
const Text('Address 1')),
CardGenerator(
const Text('John', style: TextStyle(fontSize: 24.0)),
const Icon(Icons.account_circle, size: 100, color: Colors.white),
const Text('Address 2')),
CardGenerator(
const Text('Richard', style: TextStyle(fontSize: 24.0)),
const Icon(Icons.account_circle, size: 100, color: Colors.white),
const Text('Address 3')),
];
return existingCustomerContactList;
}
Future<void> refreshList() async {
await Future.delayed(const Duration(seconds: 1));
setState(() => {
addCustomerContact(),
getCustomerContactList()
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[50],
appBar: AppBar(
title: const Text("Dashboard"),
backgroundColor: themeColor,
),
body: RefreshIndicator(
key: refreshKey,
onRefresh: () async {
await refreshList();
},
child: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: existingCustomerContactList.length,
key: UniqueKey(),
itemBuilder: (BuildContext context, int index) {
return OpenContainer(
closedColor: Colors.transparent,
closedElevation: 0.0,
openColor: Colors.transparent,
openElevation: 0.0,
transitionType: ContainerTransitionType.fadeThrough,
closedBuilder: (BuildContext _, VoidCallback openContainer) {
return Card(
color: Colors.white,
child: GestureDetector(
onTap: openContainer,
child: SizedBox(
height: 140,
child: Row(
children: [
Container(
decoration: const BoxDecoration(
color: Colors.indigo,
borderRadius: BorderRadius.only(topLeft: Radius.circular(7.0),bottomLeft: Radius.circular(7.0))
),
height: 140,
width: 120,
child: existingCustomerContactList[index].icon,
),
Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: existingCustomerContactList[index].title,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: existingCustomerContactList[index].address,
),
],
)
],
),
),
),
);
},
openBuilder: (BuildContext _, VoidCallback openContainer) {
return ConsumerHome();
}
);
}),
),
],
),
),
);
}
}
I found the
selected item has been added to the Dashboard items list but when I refresh it it doesn't newly added item in the dashboard list view.
I am a newcomer in flutter please bare with me. I already did my search for this problem unfortunately, no luck.
Change the order of execution. You are adding the item in the list and then making a new list again in the current order
addCustomerContact(),
getCustomerContactList()
change this to
getCustomerContactList()
addCustomerContact(),
I have a dialog box, when I click on the Send Again button, I make a request to the server and, if successful, another _emailSentDialog dialog box opens from above. How can I make the first EmailVerifyDialog automatically close when the second _emailSentDialog is opened?
class EmailVerifyDialog extends StatelessWidget {
final CurrentEmailCubit cubit;
const EmailVerifyDialog({Key? key, required this.cubit}) : super(key: key);
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return AlertDialogGradientBorder(
height: size.height * .5,
child: SizedBox(
width: size.width,
child: Padding(
padding: const EdgeInsets.only(bottom: 35),
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 45),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
children: [
WidgetSpan(
child: FittedBox(
child: Row(
children: [
const Text(
'Didn’t recieve a link? ',
style: constants.Styles.smallBookTextStyleWhite,
),
TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.zero),
onPressed: () async {
await cubit
.sendConfirmationCode(
email: cubit.currentEmail)
.then((value) => {
if (value)
{
_emailSentDialog(context),
}
else
{
_errorNotification(context),
}
});
log(cubit.currentEmail);
},
child: const Text(
'Send Again',
style: constants
.Styles.smallBookUnderlineTextStyleWhite,
),
),
],
),
),
),
],
),
),
),
],
),
),
),
);
}
void _closeDialog(BuildContext context) {
Navigator.pop(context);
}
void _emailSentDialog(context) async {
showDialog(
context: context,
builder: (BuildContext context) => const EmailSentDialog(),
);
}
I was referring this way
onPressed: () async {
setState(() {
text = "checking on Server";
});
final showSecondDialog = await serverResult();
if (showSecondDialog) {
if (!mounted) return;
Navigator.of(context).pop();
showDialog2(context);
}
},
class TestDialogActivity extends StatefulWidget {
const TestDialogActivity({Key? key}) : super(key: key);
#override
State<TestDialogActivity> createState() => _TestDialogActivityState();
}
class _TestDialogActivityState extends State<TestDialogActivity> {
showDialog2(context) async {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: () async {
Navigator.of(context).pop();
},
child: Text(" close Second dialog "))
],
),
),
);
}
Future<bool> serverResult() async {
await Future.delayed(Duration(seconds: 1));
return true;
}
showDialog1(context) async {
String text = "sendAgain";
showDialog(
context: context,
builder: (context) => StatefulBuilder(
builder: (context, setState) => AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: () async {
setState(() {
text = "checking on Server";
});
final showSecondDialog = await serverResult();
if (showSecondDialog) {
if (!mounted) return;
Navigator.of(context).pop();
showDialog2(context);
}
},
child: Text("$text"))
],
),
),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () => showDialog1(context),
),
);
}
}
So I am implementing a 'settings' view in my Flutter app. The idea is all settings will appear in a ListView, and when the user will click on a ListTile, a showModalBottomSheet will pop where the user will be able to manipulate the setting. The only problem I am having is I am unable to migrate the showModalBottomSheet to a separate class as I cannot make the new function (outside the class) return the manipulated setting variable. This has lead to a messy code, all in a single class.
class Page extends StatefulWidget {
Page({Key key}) : super(key: key);
#override
_Page createState() => _Page();
}
class _Page extends State<Page> {
var value;
#override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
ListTile(
title: Text("Age"),
trailing: Text(value),
onTap: () {
setState(() {
value = _valueSelector(); // This doesn't work, but to give an idea what I want
});
},
),
],
);
}
}
int _valueSelector(context) { // Doesn't return
var age = 0;
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Wrap(
children: [
Column(
children: <Widget>[
Slider(
value: age.toDouble(),
min: 0,
max: 18,
divisions: 18,
onChanged: (value) {
setState(() {
age = value.toInt();
});
},
),
],
),
],
);
});
},
).whenComplete(() {
return age; // Not sure if return is supposed to be here
});
}
How can I implement showModalBottomSheet in a separate class and just make it return the variable representing the setting chosen by the user?
You can try the below code,
First, create a class custom_bottom_sheet.dart and add the below code. You can use it everywhere in the project. And also use this library modal_bottom_sheet: ^0.2.0+1 to get the showMaterialModalBottomSheet.
customBottomSheet(BuildContext context, {#required Widget widget}) async {
return await showMaterialModalBottomSheet(
context: context,
backgroundColor: AppColors.transparent_100,
barrierColor: AppColors.black_75,
isDismissible: false,
enableDrag: true,
builder: (_, ScrollController scrollController) {
return widget;
},
);
}
Sample example code:
Create another class called bottom_sheet_example.dart and add the below code.
class BottomSheetExample {
static Future getSheet(BuildContext _context,
{ValueChanged<bool> onChanged}) async {
await customBottomSheet(
_context,
widget: SafeArea(
child: Container(
padding: EdgeInsets.only(left: 40.0, right: 40.0),
height: 170.0,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(27.0),
topRight: Radius.circular(27.0))),
child: Container(
padding: EdgeInsets.only(top: 32),
child: Column(
children: [
Text("Were you at Queen Victoria Building?"),
SizedBox(height: 48),
Row(
children: [
Expanded(
child: RaisedButton(
child: Text("No"),
onPressed: () {
Navigator.of(_context).pop();
onChanged(false);
},
),
),
SizedBox(width: 18),
Expanded(
child: RaisedButton(
child: Text("Yes"),
onPressed: () {
Navigator.of(_context).pop();
onChanged(true);
},
),
),
],
),
SizedBox(height: 24),
],
),
),
)),
);
}
}
Button click to show the bottom sheet
#override
Widget build(BuildContext context) {
return Scaffold(
body: yourBodyWidget(),
bottomNavigationBar: Container(
height: 40,
width: double.infinity,
child: FlatButton(
onPressed: () {
/// call BottomSheetExample class
BottomSheetExample.getSheet(
context,
onChanged: (bool result) async {
///
/// add your code
},
);
},
child: Text("show bottom sheet")),
),
);
}
In onChanged callback you can return your value(obj/String/num/bool/list).
Thank you!
How can i show the selected image in my alert dialog ?
In my app, i added an alert dialog which has the camera button. When user clicks the camera button, another alert dialog asks to select file from gallery. After the user selects image file from gallery, i want to show the image in the alert dialog with the camera button, but the image shows only after reopening the alert dialog.
I have posted my code below. I am new to flutter. Please can someone help me? Thanks in advance.
class Test extends StatefulWidget {
#override
_State createState() => new _State();
}
Future<File> imageFile;
class _State extends State<Test> {
Future<void> _openDailog() async {
return showDialog<void>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return AlertDialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Click Photo'),
Ink(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.0),
color: Colors.blue),
child: IconButton(
color: Colors.white,
icon: Icon(Icons.camera_alt),
onPressed: () {
_cameraOptions();
print("test");
},
),
)
],
),
content: SingleChildScrollView(
child: Container(
width: 300.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
showImage(),
InkWell(
child: Container(
margin: EdgeInsets.only(top: 8.0),
child: RaisedButton(
color: Colors.blue,
child: new Text(
"Send",
style: TextStyle(color: Colors.white),
),
onPressed: () {
Navigator.of(context).pop();
print("test");
},
),
)),
],
),
),
),
);
},
);
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FloatingActionButton(
heroTag: null,
child: Icon(Icons.insert_drive_file),
onPressed: () {
_openDailog();
},
)
],
);
}
Future<void> _cameraOptions() {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: new SingleChildScrollView(
child: new ListBody(
children: <Widget>[
FlatButton(
onPressed: () {
pickImageFromGallery(ImageSource.gallery);
Navigator.of(context).pop();
},
color: Colors.transparent,
child: new Text(
'Select From Gallery',
textAlign: TextAlign.start,
style: new TextStyle(
decoration: TextDecoration.underline,
),
),
),
],
),
),
);
});
}
pickImageFromGallery(ImageSource source) {
setState(() {
imageFile = ImagePicker.pickImage(source: source);
});
}
Widget showImage() {
return FutureBuilder<File>(
future: imageFile,
builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.data != null) {
return Image.file(
snapshot.data,
width: MediaQuery.of(context).size.width,
height: 100,
);
} else if (snapshot.error != null) {
return const Text(
'Error Picking Image',
textAlign: TextAlign.center,
);
} else {
return const Text(
'No Image Selected',
textAlign: TextAlign.center,
);
}
},
);
}
}
That is because you would need to setState() however you can't do that in an alert dialogue as it doesn't have its own state, the workaround for that would be to have the dialogue be its own stateful widget. Please check out this article as it shows how to do that. If you faced problems let me know!
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(new MaterialApp(
home: new MyHomePage(),
));
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedIndex = 0;
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text("StackoverFlow"),
),
body: Container(),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await _dialogCall(context);
},
),
);
}
Future<void> _dialogCall(BuildContext context) {
return showDialog(
context: context,
builder: (BuildContext context) {
return MyDialog();
});
}
}
class MyDialog extends StatefulWidget {
#override
_MyDialogState createState() => new _MyDialogState();
}
class _MyDialogState extends State<MyDialog> {
String imagePath;
Image image;
#override
Widget build(BuildContext context) {
return AlertDialog(
content: new SingleChildScrollView(
child: new ListBody(
children: <Widget>[
Container(child: image!= null? image:null),
GestureDetector(
child: Row(
children: <Widget>[
Icon(Icons.camera),
SizedBox(width: 5),
Text('Take a picture '),
],
),
onTap: () async {
await getImageFromCamera();
setState(() {
});
}),
Padding(
padding: EdgeInsets.all(8.0),
),
],
),
),
);
}
Future getImageFromCamera() async {
var x = await ImagePicker.pickImage(source: ImageSource.camera);
imagePath = x.path;
image = Image(image: FileImage(x));
}
}
Try this solution with GestureDetector() .it works
onTap:()async{
var image = await ImagePicker.pickImage(
source: ImageSource.gallery).whenComplete((){
setState(() {
});
}
);
setState(() {
_image = image;
});
},