CheckedPopupMenuItem: How to position the checkmark to the right? - flutter

I have a standard PopupMenuButton with CheckedPopupMenuItems:
PopupMenuButton<String>(
icon: const Icon(Icons.sort_by_alpha),
onSelected: (String result) {
if(result == optionOne){ doSomething(); }
},
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
CheckedPopupMenuItem<String>(
value: optionOne,
child: Text("optionOne"),
),
),
],
),
The checkmark for which item is selected appears to the left- I'd like to have it on the right, but can't find how to do this.
EDIT:
Is the only way really to not use CheckedPopupMenuItem completely and build the functionality myself?

Related

How to make pop up like this

Do you guys know how to make pop up that small and appear below icon like this? I have made it with AlertDialog, but the pop up is on the center of the screen and too big.
Using this code you can show the menu where you need
Function
void showPopUpMenuAtTap(BuildContext context, TapDownDetails details) {
showMenu(
context: context,
position: RelativeRect.fromLTRB(
details.globalPosition.dx,
details.globalPosition.dy,
details.globalPosition.dx,
details.globalPosition.dy,
),
items: const [
PopupMenuItem<String>(value: '1', child: Text('menu option 1')),
PopupMenuItem<String>(value: '2', child: Text('menu option 2')),
PopupMenuItem<String>(value: '3', child: Text('menu option 3')),
],
).then((value) {
if (value == null) return;
if (value == "1") {
//code here
log("message", name: value);
} else if (value == "2") {
//code here
log("message", name: value);
} else if (value == "3") {
//code here
log("message", name: value);
}
});
}
You can call like this
GestureDetector(
child: const Icon(Icons.menu),
onTapDown: (details) => showPopUpMenuAtTap(context, details),
),
PopupMenuButton from Flutter sdk
https://api.flutter.dev/flutter/material/PopupMenuButton-class.html
You can profile ShapeBorder as RoundedRectangleBorder.
what you need is popupmenu not AlertDialog here the documantain of popupmenu
with the feature shape, you could play with the shape and size ...etc

Flutter Dynamic PopupMenu Content

I'm trying to create a menu that has a 'load more' functionality. From an interface perspective, PopupMenuButton has worked nicely, but I've been unable to dynamically refresh its content.
I'm using redux and I can successfully dispatch the action to fetch more, and the store is updated, but I don't see the change until I close the menu and re-open it, despite wrapping the PopupMenuButton in a StoreConnector. I also have a check for fetchInProgress that should be changing the bottom 'more' item to a spinner while the fetch is in progress, but that state change isn't noticed either.
I'm relatively new to Flutter so I'm wondering if I'm missing something.
Gif of the behavior
#override
Widget build(BuildContext context) {
return StoreConnector<AppState, _ViewModel>(
converter: (store) => _ViewModel.fromStore(store, oneOnOneId),
builder: (ctx, vm) => PopupMenuButton(
onSelected: (callback) => callback(),
icon: Icon(Icons.expand_more),
itemBuilder: (_) =>
[...vm.pastOneOnOnes.map((m) {
return PopupMenuItem(
child: Center(child: Text(DateFormat('MM/dd/yyyy').format(m.meetingDate))),
value: () => {
Navigator.of(context).pushReplacementNamed(routeName,
arguments: {
'meetingId': m.id
})
}
);
}).toList(),
PopupMenuItem(
enabled: false,
child: Container(
height: 40,
width: double.infinity,
child: vm.fetchInProgress ?
Center(child: CircularProgressIndicator()) :
InkWell(
onTap: () => vm.fetchPastOneOnOnes(oneOnOneId, start: vm.pastOneOnOnes.length + 1),
child: Center(
child: Text('More', style: TextStyle(color: Colors.black))
)
),
),
value: null
)
]
),
);
}
}
You need to update the state when you make a change. When you call => vm.fetchPastOneOnOnes wrap it with setState :
onTap: () {
setState(){
vm.fetchPastOneOnOnes(...);}},

Flutter: disable ExpansionTile

I have an ExpansionTile that checks if the user is allowed to enable it:
ExpansionTile(
tilePadding: widget.rent ? EdgeInsets.all(0) : null,
onExpansionChanged: (bool value) {
if (_canCreateBill) {
setState(() {
_billable = value;
});
} else {
return Navigator.of(context)
.pushNamed('/invoice-details')
.then((val) async {
await _getBillingInfo();
setState(() {
_billable =
_canCreateBill;
});
});
}
widget.onSwitchChange(value);
},
initiallyExpanded: _billable,
title: Text(translate('expense.create_invoice')),
subtitle: Text(translate('expense.create_invoice_info')),
trailing: IgnorePointer(
child: Switch(
value: _billable,
onChanged: (_) {},
),
),
children: [
Visibility(
visible: _canCreateBill,
child: _billingInfo(),
),
],
);
Happy path:
Here we have _canCreateBill which controls if the user can enable the switch. If the user clicks and he's not allowed, I moved him to a page to add some info. After adding that info, he comes back and the switch is enable.
Problem:
The user can go back without adding any info. The switch will be disable but the ExpansionTile will be active because we already clicked on it:
How can check for this also? Can we disable the ExpansionTile or force a click somehow?
This option is not a solution:
IgnorePointer(
ignoring: true,
child: ExpansionTile()
)

typeAhead textfield in flutter web

I am using the typeAhead text field for auto-completion but the onSuggestionSelected function does not work. I am using flutter web. No selection is made and listView shows am hovering over an item above the one am actually hovering.
Below is the dialog, in this case the mouse pointer is actually below 'FIN' in the listView. I am using the typeAhead field in a dialog.
This is the code below.
TypeAheadFormField(
//initialValue: 'bleh',
textFieldConfiguration: TextFieldConfiguration(
controller: _typeAheadController, //this.
decoration: InputDecoration(
hintText: 'Programme(required)' //label
)),
suggestionsCallback: (pattern) {
return programme
.where((String dc) => dc
.toLowerCase()
.contains(pattern.toLowerCase()))
.toList(); //|| dc.toLowerCase().contains(other.toLowerCase())).toList();
},
itemBuilder: (context, String suggestion) {
return ListTile(
title: Text(suggestion),
);
},
transitionBuilder:
(context, suggestionsBox, controller) {
return suggestionsBox;
},
onSuggestionSelected: (String suggestion) {
_typeAheadController.text = suggestion; //this
print(suggestion + ' selected bith');
},
validator: (value) {
if (value.isEmpty ||
programme.indexOf(value) == -1) {
return 'Please select a course offered in the university you selected!';
}
},
onSaved: (value) => this._selectedCity =
value, //<--------- upload value
)
'programme' is the list of strings returned in which string 'dc' is found. 'print(suggestion + ' selected bith');' does not print a thing to show I never actually have onSelection run at all. Anyone know a work around? thank you.
Dialog:
You can use 2 methods to make it workable:
Method 1:
Use GestureDetector inside itemBuilder as below.
itemBuilder: (context, String suggestion) {
return GestureDetector(
onPanDown: (_) {
print(suggestion);
},
child: ListTile(
dense: true,
title: Text(suggestion),
),
);
},
by doing this, you still need the 'onSuggestionSelected' method, but you can leave it blank.
Method 2:
itemBuilder: (context, String suggestion) {
return Listener(
child: Container(
color: Colors.black, // <-- this gets rid of the highlight that's not centered on the mouse
child: ListTile(
title: Text(suggestion),
),
),
onPointerDown: () {
print(suggestion);
// Do what you would have done in onSuggestionSelected() here
},
);
},
I got these answers from following link onSuggestionSelected not called in Web

What is the correct way to use PopUpMenuItem onTap/onPessed in Flutter?

What is the correct way to call a function in Flutter when PopupMenuItem is tapped? Because inherently the widget does not have a onTapped property. The only thing close to it is setting the value of the PopupMenuItem widget. So the way I approached it is to set the state in the onSelected parameter in the PopupMenuButton. I did not find anyone talking about this situation on the internet so I thought it is worth to get opinions from other. Is this the proper way to do this?
I have tried to use a FlatButton as the child of the PopupMenuButton, but it did not work. It seemed that the application did not record the onTapped function of the FlatButton.
PopupMenuButton<Choice>(
onSelected: (Choice result) {
setState(() {
_selection = result;
if (_selection == Choice.SIGN_OUT) {
_signOut();
print('[home.dart] _signOut()');
}
});
},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<Choice>>[
PopupMenuItem(
child: Text(
'Sign Out',
style: TextStyle(color: Colors.black),
),
value: Choice.SIGN_OUT,
),
],
),
The expected result is to call a function when a PopupMenuItem is tapped.
PopUpMenuItem invocation can be done in two ways now.
We can do it with the onTap method now.
PopupMenuItem(
value: 'share',
onTap: () {
print("hello world");
},
child: Text('Share'),
),
Or it can be done old school like the OP has mentioned.
onSelected: (value) {
switch (value) {
case ('subscribe'):
print('Subscribing');
break;
case ('edit'):
print('editing');
break;
case ('share'):
print('sharing');
break;
default:
return;
}
},