Dynamically added widget works only after route change - flutter

I am using the flutter Slidable widget inside a SliverList, where the list elements are pulled from an array. I use setState to update the list.
The problem I am having is that after the list update, I can see all new elements correctly, but the slidable functionality doesn't work. However, after entering a new page with push and leaving with pop, the slidable functionality starts working.
Why is this happening?
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Card(
child: InkWell(
child: Slidable(
key: Key(_fileList[index].key),
actionPane: SlidableDrawerActionPane(),
child: Container(
child: ListTile(
onTap: () {
...
},
title: Text(_fileList[index].subtitle),
subtitle: Text(_fileList[index].subtitle),
),
),
secondaryActions: <Widget>[
IconSlideAction(
caption: 'Delete',
color: Colors.red,
icon: Icons.delete,
onTap: () {
...
}
),
],
),
),
),
childCount: _fileList.length,
),
);
Updating is done like this:
setState(() {
_fileList = newFileList;
});

i think you may try not to test on hot reload
just type in terminal : flutter run

Never mind, i accidentally disabled and then re-enabled the SlidableController.

Related

How to show phone icon when a phone number text is selected?

I have a SelectableText Widget with a string which is a phone number
Starts with +
Has 12 digits
When the text is selected, the option to call it doesn't appear.
If I open the same text for example in a google search as below, I can see the option to call it. How can I make that in Flutter?
You may use the contextMenuBuilder property for this.
It will help you creating a different context menu depending on the current state of the user's selection:
More info: see contextMenuBuilder property in SelectableText widget doc
SelectableText(
'data to show',
contextMenuBuilder: (_, textState) => Row(
children: [
if (isPhoneNumber(textState.textEditingValue.text))
Container(), //Widget to make the phone call here
],
),
),
bool isPhoneNumber(String selection) {
if (!selection.startsWith('+')) return false;
return RegExp(r'^[0-9]+$').hasMatch(selection.substring(1));
}
I solved it by looking at the example pointed out by #Luis Utrera
Solution:
contextMenuBuilder: (context, EditableTextState editableTextState) {
return AdaptiveTextSelectionToolbar(
anchors: editableTextState.contextMenuAnchors,
children: [
Padding(
padding: const EdgeInsets.all(10),
child: IconButton(
icon: Icon(Icons.call),
onPressed: () {
// TODO: launch call app
},
),
),
...editableTextState.contextMenuButtonItems
.map((ContextMenuButtonItem buttonItem) {
return CupertinoButton(
borderRadius: null,
onPressed: buttonItem.onPressed,
padding: const EdgeInsets.all(10.0),
pressedOpacity: 0.7,
child: Text(
CupertinoTextSelectionToolbarButton.getButtonLabel(
context,
buttonItem,
),
),
);
})
.toList()
.cast(),
],
);
},

have search bar handle one tap and two taps differently

I am pretty new to flutter/dart, so this might be a silly question...
I wanted to have a search bar, that when tapped the first time, displays a series of listview tiles (like pre-canned search terms). I wanted a subsequent tap to then open the soft keyboard for user input. As it stands now, a single tap opens the listview tiles, and also opens the soft keyboard.
After some looking around, I am thinking I would need to wrap the searchbar in a GestureDetector, and handle the tap / double-tap gestures through that. What I can't quite figure out, is how to tie the GestureDetector gestures, ontap and ondoubletap, to the child widget actions... I think when the searchbar gets focus (onTap), the soft keyboard opens, so not sure if that behavior can be (easily) uncoupled...
The flutter cookbook example uses this:
ScaffoldMessenger.of(context).showSnackBar(snackBar);
but the API docs say this only manages snackbars and MaterialBanners:
"Manages SnackBars and MaterialBanners for descendant Scaffolds."
Here is the framework I have so far:
Widget searchBar() {
//final FloatingSearchBarController searchBarController = FloatingSearchBarController();
return
GestureDetector(
onTap: () =>{},
onDoubleTap: () => {},
child: FloatingSearchBar(
controller: searchBarController,
hint: "search",
openAxisAlignment: 0.0,
width: 600,
axisAlignment: 0.0,
scrollPadding: const EdgeInsets.only(top: 16, bottom: 20),
elevation: 4.0,
onQueryChanged: (query) {
},
builder: (BuildContext context, Animation<double> transition) {
return ClipRRect(
child: Material(
color: Colors.white,
child: Container(
color: Colors.white,
child: Column(
children: [
ListTile(
title: const Text('Item 1'),
onTap: () {},
),
ListTile(
title: const Text('Item 2'),
onTap: () {},
),
ListTile(
title: const Text('Item 3'),
onTap: () {},
),
],
),
),
)
);
},
)
);
Any thoughts would be greatly appreciated!

How to make a Widget come from below and stack itself on top of current screen?

In Duolingo's app, there is an element that comes animated from the bottom and display some text everytime you unswer a question (see image bellow).
How to replicate that feature with Flutter?
You can use showModalBottomSheet widget. Here is a simple usage of this widget:
showModalBottomSheet(
context: context,
builder: (BuildContext bc){
return Container(
child: new Wrap(
children: <Widget>[
new ListTile(
leading: new Icon(Icons.music_note),
title: new Text('Music'),
onTap: () => {}
),
new ListTile(
leading: new Icon(Icons.videocam),
title: new Text('Video'),
onTap: () => {},
),
],
),
);
}
);
You can read an article about how to use Bottom sheets here
I hope this will help you.

Alert Dialogue Box inside column in Flutter

In my app users are required to submit their government ID's for verification to keep using the app. On the basis of the condition "isIDverified" it displays a text "Verified" or if it's under review it displays "Under Review". Inside the verified condition I want to put a popup which will say "Your account is under review" along with the text somewhere around this green empty block.
My code:
if (isIDVerified) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Verified',
style: kAppBarTitleTextStyle.copyWith(color: primaryColor),
),
SizedBox(
width: _screenUtil.setWidth(10),
),
Icon(
Icons.verified_user,
size: kPreferredIconSize,
color: Colors.green,
),
],
);
} else if (isIDUnderReview) {
return
Text(
'ID Under Review',
style: kAppBarTitleTextStyle.copyWith(color: primaryColor),
);
As far as I understand your question, I would like to answer it.
For displaying popups, you can make use of AlertDialogs.
You can do something like this.
void informUser() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text("Under Review"),
content: Column(
children: [ LIST OF WIDGETS ]
),
actions: <Widget>[
new FlatButton(
child: new Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
You can put your widgets in the Column widget of AlertDialog's content.

How to display a list of items inside a column using a ListTile in Flutter

staff.ulogin is a list returned from a web service. If there is more than one item returned, I need to display of list of those items (displaying the company name). I can get the first item displaying, but I'm not sure how to display the entire list.
I also need the user to be able to tap an item so I can setup that company for use, so I'll need to know what item they chose. Thanks for any help.
if (staff.ulogin.length > 1) {
Alert(
context: context,
title: 'Choose Company',
content: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//how to display all the items
ListTile(
title: Text(staff.ulogin[0].company),
onTap () {}, // <--- how to get the index of the item tapped
),
],
),
),
buttons: [
DialogButton(
child: Text('Cancel', style: TextStyle(color: Colors.white, fontSize: 20)),
color: kMainColor,
onPressed: () {
Navigator.of(context).pop();
},
),
],
).show();
} else
I believe that the correct way of display a list o items is using a ListView. For this case you can use a ListView.builder like this:
Container(
height: 300.0, // Change as you wish
width: 300.0, // Change as you wish
child: ListView.builder
(
itemCount: staff.ulogin.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(staff.ulogin[index].company),
onTap () {
someFunction(staff.ulogin[index]);
},
),
}
)
)