I want to show filter list in a container but it is opening as a new screen in flutter - flutter

This code is working, but I am not getting the output I want. I want to show this screen in a container but it's not working.
It's not opening in a container but instead directly opening as a different page.
I am using the flutter filter_list: ^1.0.2 plugin in this code.
I want to show this search bar with a list in a container on the same page.
List<SelectProjectData?> _selectProjectData = [];
openFilterDelegate() async {
await FilterListDelegate.show<SelectProjectData?>(
context: context,
list: _selectProjectData,
selectedListData: _selectedProjectData,
onItemSearch: (user, query) {
return user!.projectName!.toLowerCase().contains(query.toLowerCase());
},
tileLabel: (user) => user!.projectName,
emptySearchChild: const Center(child: Text('Data not found')),
// enableOnlySingleSelection: true,
searchFieldHint: 'Search Here..',
onApplyButtonClick: (list) {
setState(() {
_selectedProjectData = list!;
});
},
);
}
Try to call this in the column:- here you can find the code
Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(20),
color: AppColor.WHITE,
child:
Column(
children: [
openFilterDelegate(),
],
),
);
The final result is this:-

Based on https://pub.dev/packages/filter_list, you want to use the FilterWidget instead of the FilterDelegate. FilterDelegate opens a new window every time. FilterWidget is a widget that you can put inside a container just like any other widget.
Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(20),
color: AppColor.WHITE,
child:
Column(
children: [
FilterWidget(
<set up widget here>
),
],
),
);

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(),
],
);
},

Is there any way to List the list views size in flutter?

I am new to flutter and trying to develop a version updation software. I need to show the version in a radio list. Is there any way to contain the list view in a container? Currently the list view is overflowing through the other widgets. I need to contain the list view between the text and the button. Is there any way to do it.The code the screenshot is given below
[![screenshot][1]][1]
Widget _createVersionRadioTiles(List<String> versions) {
var radioTiles = <Widget>[];
for (var version in versionList) {
var tile = Padding(
padding: const EdgeInsets.all(8.0),
child: RadioListTile<String>(
selected: selectedVersion == version,
tileColor: colorDarkGray,
// selectedTileColor: Colors.white,
value: version,
groupValue: selectedVersion,
onChanged: (String? value) {
setState(() {
selectedVersion = value!.toString();
});
},
title: Text(version),
),
);
radioTiles.add(tile);
}
return Column(
children: [
SizedBox(
height: 500,
width: 500,
child: ListView(children: radioTiles),
)
],
);
} ```
[1]: https://i.stack.imgur.com/qQxns.jpg
Wrap the RadioListTile with a Card widget. It will contain the ListTile in the container.
You can replace SizedBox with Container, and use clipBehavior: Clip.hardEdge to remove the overflows. see code below:
return Column(
children: [
Container(
height: 500,
width: 500,
clipBehavior: Clip.hardEdge,
child: ListView(children: radioTiles),
)
],
);

How can i create a conditional dialog that's not dismissible in the dashboard of my flutter app

I have a view, dashboard.dart, and in this file i have conditional views in which i created a different file for the individual views i'm rendering.
How do i render a conditional dialog that fills the whole screen instead of a widget?
I tried creating a widget that uses showGeneralDialog and then pass the widget to my dashboard.dart file but it seem i don't know how to go about it.
I need ideas or help
I have a snippet of my dashboard.dart file which at the end checks if the user is subscribed or not:
Widget content(context) {
return Obx(() => Column(
children: [
Expanded(
child: ListView(
padding: const EdgeInsets.only(
top: 40, left: 20, right: 20, bottom: 20),
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
AppLocalizations.of(context)!.welcome +
" ${user.firstName}",
style: const TextStyle(fontSize: 20)),
if (user.userType == "player")
InkWell(
onTap: () {
CustomSnackBar().show(
'${user.profileViews ?? "0"} profile views');
},
child: InkWell(
onTap: () {
playersController.fetchPlayerInfo(
context, user.id);
TabRouting()
.pushScreen(context, const PlayerInfo());
},
child: CircleAvatar(
backgroundImage: NetworkImage(
"${dotenv.env['BACKEND_URL']}${user.photo?.replaceAll("public", "storage")}"),
),
),
)
],
),
///SHOW SUBSCRIPTION STATUS
if (servicesController.subscription.isEmpty &&
!servicesController.loading &&
user.userType != "club_official")
const SubscriptionNotice(),
And the widget i'm returning is SubcriptionNotice().
What i'm asking is how do i show a dialog if the user is not subscribed and pass it to that condition?
If i can use a widget, how do i configure this widget?
I tried using showGeneralDialog in my SubscriptionNotice widget but i can't seem to go about it.
You can use simple switch something like
showDialog ?? dialogWichYouWantToShow: OtherWidget
You eneter this screen and will see OtherWidget
When condition showDialog changes (use setState or something) it should display dialogWichYouWantToShow

Building widgets with Hive box data

I was building my Widgets from a list that was predefined in a file of MyClass I created. This worked but I wanted to be able to store persisted data for adding a Boolean favorite field.
I created the Hive Types/Fields for my class, generated the type adapters, and successfully loaded the Hive box on first run of the app, and I can print values to the console, so I know the data is all there and correct.
In the class I have, name, image url path to asset image and a favorite field.
Before when I was using the list to get my data I was able to get the image URL like this:
Expanded(child: Image.asset(widget.MyClass.imageURL)),
Now I want to get this from the Hive box
Box<MyClass> box = Hive.box<MyClass>('myClassBox');
//This is where I am stuck
Expanded(child: Image.asset(box.???)),
I tried box.values.where and box.get() to then get to imageURL field. But get requires a key, which I don't have to pass it from
Widget build(BuildContext context)
And I then have the same issue when trying to access the favorite field, which I am using the Favorite Button package (favorite_button 0.0.4). And I will then update the true/false value based on the button being tapped.
If someone can point me in the right direction that would be great.
Thanks.
Edit:
Here is the Widget:
Widget build(BuildContext context) => GestureDetector(
onTap: () => Navigator.of(context).push(MaterialPageRoute(
builder: (context) => TaskPage(job: widget.job), //Need to get data from Hive now
)),
child: Container(
padding: const EdgeInsets.all(16),
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
),
child: Row(
children: [
Expanded(flex: 3, child: buildText()),
Expanded(child: Image.asset(widget.job.imageUrl)),//Need to get data from Hive now
GestureDetector(
child: Icon(
widget.job.fav ? Icons.favorite : Icons.favorite_border, //Need to get data from Hive now
),
onTap: () {
// add/remove from favorites list
}
),
],
),
),
);
Second Edit: Here is the same code after implementing the suggestion given
Widget build(BuildContext context) => GestureDetector(
onTap: () => Navigator.of(context).push(MaterialPageRoute(
builder: (context) => TaskPage(job: Hive.box<Job>('jobBox').get(context)), //This bit is still broken so I need to look at this
)),
child: Column(
children:
Hive.box<Job>('jobBox').values.toList().map(
(elementList) => Container(
padding: const EdgeInsets.all(16),
height: 100,
decoration: BoxDecoration(
color: white,
borderRadius: BorderRadius.circular(16),
),
child: Row(
children: [
Expanded(flex: 3, child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
elementList.name,
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20),
),
SizedBox(height: 10),
//Text('Num tasks in job'),
],
)),
Expanded(child: Image.asset(elementList.imageURL)),
GestureDetector(
child: Icon(
elementList.fav
? Icons.favorite
: Icons.favorite_border,
color: elementList.fav ? Colors.red.shade200 : Colors.grey,
),
onTap: () {
//To do
}
// )
),
],
),
),
)
.toList(),
),
);
Assuming that you have only 1 data in the box, you can access that stored data like this.
Box<MyClass> box = Hive.box<MyClass>('myClassBox');
if(box.isNotEmpty) {
final data = box.values.first;
// use data
} else {
// empty state
}
Hive values could have keys, depending on how you use it. If you used box.put(key, value), you can use box.get(key) to work with keys and values.
If you used box.add(value), it stores the data with auto assigned indexes starting from 0. So you can usebox.getAt(index) to get a data with index.

Flutter async method keeps running even after the corresponding widget is removed

I have a list of image paths and I am using the List.generate method to display images and a cross icon to remove image from list. Upload method is called on each image and when I remove the image from the list the method still keeps running until the image is uploaded. The behavior I am expecting is when I remove the image from the list the method should also stop running. I am using a future builder to display the circular progress bar and error icons while uploading an image.
What should I be doing to make sure the future method associated to the current widget also stops when I remove the widget from the list?
This is the code where I am creating a list
List.generate(
files.length,
(index) {
var image = files[index];
return Container(
height: itemSize,
width: itemSize,
child: Stack(
children: <Widget>[
Container(
getImagePreview(image, itemSize)
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
uploadHandler(image, field),
InkWell(
onTap: () => removeFileAtIndex(index, field),
child: Container(
margin: EdgeInsets.all(3),
decoration: BoxDecoration(
color: Colors.grey.withOpacity(.7),
shape: BoxShape.circle,
),
alignment: Alignment.center,
height: 22,
width: 22,
child: Icon(Icons.close, size: 18, color: Colors.white),
),
),
],
),
],
),
);
},
)
This is Upload Handler method.
Widget uploadHandler(file, field) {
return FutureBuilder(
future: upload(file),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data.statusCode == 201) {
return doneUpload();
} else {
logger.d(snapshot.error);
return error();
}
} else {
return uploading();
}
},
);
}
The lifecycle of the widget isn't attached to the async functions invoked by the widget.
You can check the mounted variable to check if the widget still mounted from your async function.