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
Related
Flutters!
I need to recreate this layout in Flutter to be displayed as items in a ListView.
Both layouts (Emma & Tonny) are the same.. the only difference is the colors that depend on some other data/status, something that I will decide programmatically later.
I already have the ListView.builder as follow:
ListView.builder(
itemCount: WeeklyList.contacts.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () => onTapMe(WeeklyList.contacts[index]),
child: TripItemCard(index, WeeklyList.contacts[index]));
})
and.... the main missing guy:
Widget TripItemCard(int index, Info info) {
return SizedBox(
height: 116,
child: Card(
//.... Card Layout.....
)
);
NOTE: I wrapped the Card with a SizedBox to be able to have a Height specified for all cards.
There are 8 widgets in total:
1- The Card
2- Picture
3- Fullname
4- Role
5- PickUp Label
6- PickUp Time
7- DropOff Label
8- DropOff Time
Lastly and Very Important Things
1- Please be advised that there are 2 TEXTs (Name and DropOff Status) who have BACKGROUND and TEXT color... and both of them... fully expanded (width). This is very important to maintain the horizontal color balance.
2- Also PickUp and DropOff are aligned to the right where the PickUp and DropOff Time/Status respectively are aligned to the left.
PLEASE.Help();
thanks.dart
The basic layout should look like this and you can add the details to it.
Row(children: [
Image.asset(name),
Column(
children: [
Container(
color: const color,
child: const Text(data),
),
Text(data),
Text(data),
Text(data),
],
),],),
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.
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
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')
),
);
}),
);
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.