I have dynamic lists inside the dynamic list, My need is to save option with their attributes. I tried so many ways to show drop down of attributes for every option but DropDownMenuitem Widgets does not handle dynamic list in the stable version of flutter, so I have to use Expandable List for this purpose. When I select an attribute of an option then how can I reflect the selection of a particular option in the header or how can I save the selection of dynamic attribute
This is how i build my list
ListView.builder(
shrinkWrap: true,
itemCount: opAtrrList.length>0?opAtrrList.length:0,
itemBuilder: (context, i) {
return ExpansionTile(
title:optionTitle(width,height,opAtrrList[i].groupname,selectedAttr),
children: <Widget>[
new Column(
children: _buildExpandableContent(opAtrrList[i]),
),
],
);
},
),
This is my expandable item Attribute selectedAttr;
_buildExpandableContent(OptionAttribute oa) {
List<Widget> columnContent = [];
for(int i=0;i<oa.attrlist.length;i++){
columnContent.add(
new ListTile(
onTap: (){
setState(() {
selectedAttr=oa.attrlist[i];
});
},
title: new Text(oa.attrlist[i].attributename, style: TextStyle(fontFamily: 'medium',color: MyColors.colorPrimaryDark)),
),
);
}
return columnContent;
}
Please see the below gif.
Related
I have some data from API and I want to fetch data like this design, how to make it?
and how to custom ListView to view this shape
I got to try this but the shape of ListView is fixed
You might want to base your Row() alignment on the parity of the index of said Row().
One way to implement this is by using the ListView.builder() widget:
ListView.builder(
itemCount: _yourItemCount,
shrinkWrap: true,
itemBuilder: (context, index) {
List<Widget> children = [
yourWidget()
];
if (index % 2 != 0 && index != 0) {
// Checking the parity of the index
children.add(yourWidget());
}
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: children));
}),
You can read more about it here.
As to how to make the level widget design, you could use image assets, combined with a CustomPaint() widget (for the outside circle).
Hello I'm still learning but cant find it for some reason,
My question is: I want to make a button that on press creates a new container and organizes it in a listview widget, how do I do that? do you have a tutorial or article about it that can help me?
Create a list:
List<Widget> widgets = [
widget1,
widget2,
],
Change the ListView's children to widgets:
ListView(
children: widgets,
),
Make a button that when pressed creates a new Container:
TextButton(
onPressed: () {
widgets.add(Container(child: child));
},
child: Text("Create a new container"),
),
You have to initialize list of type Widget
List<Widget> widget=<Widget>[];
On Button Tap call the following method:
void addContainer(){
setState(() {
widgetList.add(Padding(
padding: const EdgeInsets.all(8.0),
child: Container(height: 20,width: 30,color: Colors.red,),
));
});
}
Add Following code for create your list:
ListView.builder(
itemCount: widgetList.length,
itemBuilder: (BuildContext context, int index) {
return
widgetList.isNotEmpty?
widgetList.elementAt(index):SizedBox();
},
),
Without example I would say the easier way would be to have an array with the widget you want in your listview, then on click add an element in your list with setState.
List<Widget> views = [Text("test"), Text("test2")];
then
ListView(children: views)
and final a function to call with your button
void addContainer()
{
setState((){
views.add(Container(color: Colors.red));
});
}
I did not try it so it might contain some typos, but you get the logic.
Im very new to flutter, Im trying to do scrolling vertically and show horizontal cuisines and vertical restaurants list, for horizontal list it works fine but I don't know how to do this for the vertical list, please advice me with which is the best way to do it if I will have a huge number of restaurants in this list
SliverToBoxAdapter(//horizontal list
child: RestaurantsSlide(title: 'Featured Restaurants',),
),
SliverList(
delegate: SliverChildListDelegate(
[
//How to call the list here
],
),
),
this is the function to return the list of restaurants
void restaurantCardList() {
List<dynamic> restaurantsList = RESTAURANT_DATA;
List<Widget> listItems = [];
restaurantsList.forEach((restaurant) {
listItems.add(
Padding(
padding: const EdgeInsets.only(left: 10.0, right: 10, bottom: 25),
child: RestaurantCard(restaurant: restaurant),
)
);
}
);
}
I've been designing an App where the User searches a term and a GridView is displayed containing all the images related to that term. All of these images are made Draggable.
In another GridView on the same page, I have placed 40 Dragtargets. So the user can Drag a searched up image and place it in one of the DragTargets, thus being able to select 40 images.
The issue is that when I drag one image to the Dragtarget grid, all 40 of the dragtargets are filled up with the same image. I think this is because every Dragtarget has the same key since it was generated in an itemBuilder. But i don't know how to set a different key to each Dragtarget while generating it. Would appreciate alternative solutions in implementing the same scenarios as well !
The code for Draggable Images:
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 350,
mainAxisSpacing: 10,
crossAxisSpacing: 10),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
child: LongPressDraggable<String>(
data: imageLinks[index],
feedback: Image(
image: NetworkImage(imageLinks[index])),
child: Image(
image: NetworkImage(imageLinks[index])),
onDragStarted: () {
panelController.close();
},
),
);
The Code of GridView and DragTargets :
GridView.builder(
itemCount: 40,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5,),
itemBuilder: (context,index){
return Container(
padding: EdgeInsets.only(top:5,right:5,bottom:5,left:5),
child: DragTarget<String>(
builder: (context, List<String> candidateData, rejectedData) {
if (dragged == true) {
return Container(
height: 50.0,
width: 50.0,
child: Image(
image: NetworkImage(draggedImage),
),
);
} else {
return Container(
height: 50.0,
width: 50.0,
color: Colors.yellow,
);
}
},
onWillAccept: (data) {
return true;
},
onAccept: (data) {
setState(() {
dragged = true;
draggedImage = data;
//panelController.open();
});
}
),
);}
),
The problem is that you are using single variable for all dragtarget elements.
Let Me Explain in code.
onAccept: (data) {
setState(() {
dragged = true;
draggedImage = data;
//panelController.open();
});
}
In above code you set dragged value true and draggedImage value true, so every widget build with same value.
I hope i clear issue.
Solution:
To solve this issue, you can create a list of bool(if you want to keep that bool value different for all the dragtarget element also) and List of draggedImage while hold the draggedImage for each individual element, so all will not change when you change one.
I use a ListView.builder in my class to add dynamically contents to the list. I use a controller to keep the bottom focus with controller.jumpTo(controller.position.maxScrollExtent); But I dont know why, it doesn't focus the last item but the one before the last...
here is my fonction that add an item to the list
if(numTeam == 1){
_listAnnonceTeam1.add(nbrPoints);
_controllerAnnonceT1.jumpTo(_controllerAnnonceT1.position.maxScrollExtent);
}
and here is my ListView.builder :
child: ListView.builder(
controller: _controllerAnnonceT2,
itemCount: _listAnnonceTeam2.length,
itemBuilder: (BuildContext context, int index){
return new Text(_listAnnonceTeam2[index].toString(), textAlign: TextAlign.center, style:
TextStyle(color: textColor),);
},
),
do you have any idea why ?
You need to do the jump in a post-frame callback to make sure the item will be included in the list:
SchedulerBinding.instance.addPostFrameCallback((_) {
_controllerAnnonceT1.jumpTo(_controllerAnnonceT1.position.maxScrollExtent);
});