(Flutter) Select Effect on items in Grid View Builder - dart

I have items loaded in GridView.builder from sqflite database. Since the model class of it is not Stateful, ofcourse, I am not able to create Select effect on the items from there.
What i mean by select effect is this:
When users tap on an item, it is selected
GridView.builder(
gridDelegate:.....,
itemBuilder: (BuildContext context, int index) {
bool _selectItem = false;
return Stack(
children: <Widget>[
itemsList[index]), //====Actual Item=====//
InkWell(onTap: () { //===To create Select Effect====//
setState(() {
if (_selectItem == false) {
_selectItem = true;
print("Item Selected");
} else {
_selectItem = false;
print("Item UnSelected");
}
});
},
child: Opacity(
opacity: _selectItem == true ? 0.5 : 0.0,
child: Icon(Icons.select)
),]); },
itemCount: itemsList.length,
))
I am able to create a select effect, but it selects all items if I tap on any one item. How can create select effect for each individual item.
So how can I create select effect for each individual item?
P.S. I have written only relevant things in the code

Because of itemList index is not managed for selection and unselection,
Your items data loaded in GridView.builder from sqflite database,
you are manage selection manualy through the local variable into GridView,
Instead of local variable you need to insert selection field into item table,
when inset item into table first time default value item is false.
InkWell(onTap: () { //===To create Select Effect====//
setState(() {
itemList[index].selectItem = !itemList[index].selectItem
});
},
Then after onTap manage the item selection

Related

Select Item effect in a GridView Builder

I have items loaded in GridView.builder from sqflite database. Since the model class of it is not Stateful, ofcourse, I am not able to create Select effect on the items from there.
What i mean by select effect is this:
When users tap on an item, it is selected
GridView.builder(
gridDelegate:.....,
itemBuilder: (BuildContext context, int index) {
bool _selectItem = false;
return InkWell(
onTap: () {},
child: Stack(
children: <Widget>[
itemsList[index]), //====Actual Item=====//
InkWell(onTap: () { //===To create Select Effect====//
setState(() {
if (_selectItem == false) {
_selectItem = true;
print("Item Selected");
} else {
_selectItem = false;
print("Item UnSelected");
}
});
},
child: Opacity(
opacity: _selectItem == true ? 0.5 : 0.0,
child: Icon(Icons.select)
),]); },
itemCount: itemsList.length,
))
I am able to create a select effect, but it selects all items if I tap on any one item. How can create select effect for each individual item.
So how can I create select effect for each individual item?
P.S. I have written only relevant things in the code
Link to the original question: (Flutter) Select Effect on items in Grid View Builder
Okay I would suggest you wrap your stateless item into a GestureDetector
Then you can decide which gesture you want to detect and react to it, here's the doc
Hope it's help
You can try using the Hero widget for a simple animation, but if you're using custom animations you're going to have to change it to a stateful widget.
short video on hero widget: https://www.youtube.com/watch?v=Be9UH1kXFDw

Flutter bring up a list when a button is pressed, and close said list after an option is selected

I'm building an application for a building that can navigate a user, one of the ways I am doing this is by using a floor plan of the building and I want to draw a path between nodes in this floor plan to create a route. The user enters where they want to be and then route finding algorithm outputs a path, the way I want to build this path is by having a user select a source node and a target node from two seperate lists, I want them to press a button on the map view screen and have a list with these nodes appear but no matter what I try the list will not display.
I've tried using setState and having a ListView returned but that seems to be where it's failing as such as I have print statements to help verify where in the code I've reached, I don't know if it's the search terms I'm using but nothing I have found so far seems to be related to this kind of use case. This is similar to what I want but this is just a list already being displayed and then being updated.
Widget build(BuildContext context) {
//currently inside of a scaffold
bottomNavigationBar: BottomAppBar(
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.trip_origin),
onPressed: () {
setState(() {
_sourceList();
});
},
),
],
)),
//extra code as part of scaffold
}
Widget _sourceList() {
print("working1"); //this prints
return ListView.builder(
padding: const EdgeInsets.all(10.0),
itemBuilder: (context, i) {
print("working2"); //this does not
return _buildRow();
});
}
Widget _buildRow() {
return new ListTile(title: Text(a.name));
}
So basically I just want a list to display when the user presses a button, then have that list disappear after a selection is made. The actual result is I can press the button and nothing is displayed, I only reach working1 in the code not working2.

Flutter populate listview with list selection (drill down)

I need to "drill down" from a ListView, where, for example, selecting a State from a list should display a list of Zip Codes. Selecting a Zip Code should display a list of Cities, and so on.
I can find examples of selecting a list item and displaying detail about that item, but nothing about one listview selection creating another listview. In particular, is it preferable/possible to change the content of a single listview, or should there be a separate listview for each "level?"
This currently displays Zip Codes, based on a hard-coded State, but this is where I'm stuck.
#override
Widget build(BuildContext context) {
return ListView.builder(
//gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// crossAxisCount: 2,
//),
itemCount: zips.length,
itemBuilder: (context, index) {
return Text(zips[index].zip,
style: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 4.0),);
},
);
}
Thanks!

Remove Index wise CustomWidget from List<Widget> in Flutter

I have initially empty list of Widget in Column. Now on Other widget click I am adding new Custom Widget in _contactItems
Column(
children: _contactItems,
)
List<Widget> _contactItems = new List<CustomWidget>();
_contactItems.add(newCustomWidget(value));
Now Suppose I have 6 Records (6 Custom Widgets in Column). I am trying to remove index wise records (Example. I am removing 3rd record then 1st record. Column Widgets (dynamic widgets) should be updated as _contactItems updating in setState())
Now on CustomWidget click I am removing that particular CustomWidget from Column.
setState(() {
_contactItems.removeAt(index);
});
Also tried with
_contactItems.removeWhere((item) {
return item.key == _contactItems[index].key;
});
Try this (assuming that your Column widget keys have this format):
setState(() {
this._contactItems.removeWhere((contact) => contact.key == Key("index_$index"));
});
If this doesn't solve your issue, maybe we'll need more info.
If you want to manipulate a ListView or GridView it is important that you assign a Key to each child Widget of the List/GridView
In short Flutter compares widgets only by Type and not state. Thus when the state is changed of the List represented in the List/GridView, Flutter doesn't know which children should be removed as their Types are still the same and checks out. The only issue Flutter picks up is the number of items, which is why it only removes the last widget in the List/GridView.
Therefore, if you want to manipulate lists in Flutter, assign a Key to the top level widget of each child. A more detailed explanation is available in this article.
This can be achieved be adding
return GridView.count(
shrinkWrap: true,
crossAxisCount: 2,
crossAxisSpacing: 5.0,
mainAxisSpacing: 5.0,
children: List.generate(urls.length, (index) {
//generating tiles with from list
return GestureDetector(
key: UniqueKey(), //This made all the difference for me
onTap: () => {
setState(() {
currentUrls.removeAt(index); // deletes the item from the gridView
})
},
child: FadeInImage( // A custom widget I made to display an Image from
image: NetworkImage(urls[index]),
placeholder: AssetImage('assets/error_loading.png')
),
);
}),
);

ListView animation when item is deleted using Dismissible

I'm using Dismissible to dismiss the items, but when an item is dismissed I get default boring animation. Is there a way to change that animation like Gmail does?
Example:
My own animation (not smooth)
So, in my animation, you can see slight pause when the item is deleted and next item coming up on the screen taking up old item position.
That's the default animation of Dismissible.
List<String> content;
ListView.builder(
itemCount: content.length,
itemBuilder: (context, index) {
return Dismissible(
key: ValueKey(content[index]),
onDismissed: (_) {
setState(() {
content = List.from(content)..removeAt(index);
});
},
background: Container(color: Colors.green),
child: ListTile(
title: Text(content[index]),
),
);
},
)
Thanks to #RĂ©mi Rousselet for his efforts.
Finally I found the reason for that ugly animation. Never use itemExtent when you are planning to use Dismissible. I was mad, I used it.

Resources