Building dynamic widgets in Flutter - flutter

Could you please help with how we can build a dynamic list of widgets instead of building cards(containers or widgets) for example one by one manually? Using the ListView.build or other methods? What is the best way?
I spent a day trying and researching. Instead of adding 3 cards(or other objects with multiple properties), I am trying to build a method or a function that will build each card(object) based on the list(and length) and then insert all the card built automatically in the [].
I've been trying to achieve it, but when I add it to [] there are some problems, probably because of the wrong types or maybe I am doing something horribly wrong? And not sure if it's the best(if correct at all) way of doing it?
List entries = ['one', 'two', 'three3'];
Widget buildListView() {
return ListView.builder(
padding: EdgeInsets.all(8),
itemCount: entries.length,
itemBuilder: (BuildContext context, int index) {
return new Container(
height: 50,
color: Colors.lightBlue,
child: Center(child: Text('Entry ${entries[index]}')),
);
});
}

Here you go.
///construct the list of dynamic widgets as per your requirement.
final listWidgets = [Text("one"), Text("two"), Text("three")];
///pass the widgets to the listview builder.
return ListView.builder(
padding: EdgeInsets.all(8),
itemCount: listWidgets.length,
itemBuilder: (BuildContext context, int index) {
return new Container(
height: 50,
color: Colors.lightBlue,
child: listWidgets[index],
);
});
});

Related

how to use two future builder in one page in flutter

In my Flutter app, I need to display two lists that are coming from the database, but I am having trouble getting both lists to display on the same screen. I am using two FutureBuilder widgets, but the first list is displaying correctly while the second list is still loading.
Here is the code I am using:
var future1 = FutureBuilder<List<QuranTextModel>>(
future: database.getQuranText(),
builder: (context, snapshot) {
if(snapshot.hasData){
return ScrollablePositionedList.builder(
itemScrollController: scrollToIndex,
itemCount: snapshot.data!.length,
initialScrollIndex: widget.position,
itemBuilder: (context, index) {
// Build the list item widget here
});
}else{
return const Center(child: CircularProgressIndicator(),);
}
}
);
var future2 = FutureBuilder<List<UrduTextModel>>(
future: database.getUrduTranlation(),
builder: (context, snapshot) {
if(snapshot.hasData){
return ScrollablePositionedList.builder(
itemScrollController: scrollToIndex,
itemCount: snapshot.data!.length,
initialScrollIndex: widget.position,
itemBuilder: (context, index) {
// Build the list item widget here
});
}else{
return const Center(child: CircularProgressIndicator(),);
}
}
);
Column(
children: [
SizedBox(
height: 200,
child: future1,
),
SizedBox(
height: 200,
child: future2,
),
],
)
The first FutureBuilder is used to build a list of QuranTextModel objects, and the second FutureBuilder is used to build a list of UrduTextModel objects. I am using a Column widget to display both lists, with each list contained within a SizedBox widget to give it a fixed height.
The issue I am having is that only the first list is displaying correctly, while the second list is still loading. How can I get both lists to display on the same screen?
Thank you for any help you can provide!
SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: 200,
child: future1),
SizedBox(height: 200,child: future2,)
],
),
),
Try this.
also you have to check your future status before populate you can check that by using
if (snap.connectionState == ConnectionState.done) { your code. you can check does snpa has data in it. }
connection state has deferent states that can help you to make your UI more interactive

Expected a value of type 'int', but got one of type 'String'

I am working with this api: https://api.jikan.moe/v4/anime what I want is to obtain both the movies (images) and their titles. before I was just displaying the images inside a horizontal listview.builder and everything was going great. but when wanting to put their respective titles under each image I got the error mentioned in the title.
final list = data['data'] as List;
//final list = data['data']["title"] as List;
//return list.map((e) => DataApi(image: e)).toList();
return list
.map((e) => DataApi(
image: e["images"]["jpg"]["image_url"],
title: e["titles"]["title"]))
.toList();
the way I intend to display them.
if (snapshot.hasData) {
final lista = snapshot.data!;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: Container(
width: double.infinity,
height: 200,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: lista.length,
itemBuilder: (BuildContext context, int index) {
return Column(
children: [
Image.network(
lista[index].image,
),
Text(lista[index].title),
],
);
},
),
As I said, what I intend is to put each name of the movie under its image. Please, I would really appreciate it. Thank you
titles are inside an array , that's why you need to acces each item on it
Change
title: e["titles"]["title"]
to
title: e["titles"][0]["title"] // this will get you "Cowboy Bebop"

listview ripple effect in flutter

i have a simple listview in flutter
final List<String> entries = <String>['A', 'B', 'C'];
final List<int> colorCodes = <int>[600, 500, 100];
ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: entries.length,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 50,
color: Colors.amber[colorCodes[index]],
child: Center(child: Text('Entry ${entries[index]}')),
);
}
);
when i click/tap on it, there is a circle ripple effect that then expand to the rest of the element i clicked in the list. i would like to change this behavior and remove the circle ripple effect. instead when someone click on an element of the list, i want that element to highlight and fade away for the whole element. one examples is whatsapp app. when you click on a conversation, you will see that the element you click in the list will flash with ripple effect of the full element. you will see a rectangle ripple effect not a circle ripple effect where you click and then expands to the rest of the element
how can i change the default behavior on listview in flutter? if im not clear, let me know
thanks in advance
In the 8 number line in your code snippet
return the InkWell() class instead of Container()
like this
child: ListView.builder(
itemCount: list.length,
itemBuilder: (context, i) {
return InkWell(
onTap: (){},
child: Container(
height: 50,
color: Colors.amber[colorCodes[index]],
child: Center(child: Text('Entry ${entries[index]}')),
);
);
},
),
For more information visit flutter.dev Documentation

How to pass a listview.builder in flutter_slidable (Slidable)

This is just a simple todo list app. I want to implement a feature which lets me mark a task as complete when swiping right and delete the task when swiping left. This app uses a database and stores an added task in a list of type database (List<TodoItem> Itemlist= <TodoItem>[];).
Is it possible to use flutter_slidable?.
I have tried using Dismissible but i could only get it to delete the task.
List<TodoItem> Itemlist= <TodoItem>[];
SingleChildScrollView(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: Itemlist.length,
itemBuilder: (BuildContext context, int index){
String item = Itemlist[index].toString();
return Dismissible(
key: Key(UniqueKey().toString()),
onDismissed: (direction){
setState((){
deleteItem(Itemlist[index].id, index);
}
);
},
background: Container(
child: Icon(Icons.delete),
color: Colors.red,
alignment: Alignment.centerLeft,
),
child: Itemlist[index],
);
}
),
)
I want to get the same result as below but am unsure on how to pass the listview.builder in Slidable.
Wrap your tile widget with Slidable
Setup "actionPane" and "actions" parameters for Slidable

ListView.builder show anything

AlertCardWidget is a widget that i wrote. I return it in itemBuilder but nothing shown. Here is my code:
Flexible(
child: Padding(
child: SingleChildScrollView(
child: ListView.builder(
itemCount: state.data.length,
itemBuilder: (BuildContext context, int index) {
state.data["datas"].map<Widget>((f) {
return AlertCardWidget(
positionId: "${f["8020074"]}",
shipowner: "${f["8020076"]}",
customer: "${f["8020170"]}",
salesRepresenter: "${f["8020176"]}",
operationRepresenter: "${f["8020177"]}",
textContentFontColor:
AppTheme(Theme.of(context).brightness)
.cardFontBackgroundColor,
textfont: Colors.redAccent,
);
}).toList();
},
),
),
),
),
No error to show.
I have items that why I use ListView. The problom of using Listview instead ListView.builder is taking "Vertical viewport was given unbounded height error". The problem has solved when writing Listview like child of Expanded widget. Here is my code:
Expanded(
child: Padding(
padding: const EdgeInsets.all(4.0),
child: ListView(
children: state.data["datas"].map<Widget>((f) => AlertCardWidget(positionId: "${f["8020074"]}",
shipowner: "${f["8020076"]}",
customer: "${f["8020170"]}",
salesRepresenter: "${f["8020176"]}",
operationRepresenter: "${f["8020177"]}",
textContentFontColor: AppTheme(Theme.of(context).brightness).cardFontBackgroundColor,
textfont: Colors.redAccent,)).toList(),
),
),
),
Maybe a silly question, but why are you mapping a list into a ListView.builder?
Have you tried using the index for each iteration instead?
Because what I understand from that code is that every ["datas"] item you've got will generate the whole list for as many times as state.data.length has.
Maybe try this out:
Flexible(
child: Padding(
child: SingleChildScrollView(
child: ListView.builder(
itemCount: state.data.length,
itemBuilder: (BuildContext context, int index) {
return AlertCardWidget(
positionId: state.data[index]["datas"]["8020074"],
shipowner: state.data[index]["datas"]["8020076"],
customer: state.data[index]["datas"]["8020170"],
salesRepresenter: state.data[index]["datas"]["8020176"],
operationRepresenter: state.data[index]["datas"]["8020177"],
textContentFontColor:
AppTheme(Theme.of(context).brightness)
.cardFontBackgroundColor,
textfont: Colors.redAccent,
);
},
),
),
),
),
If that doesn't work, would you mind showing us which data are you trying to retrieve?
Your itemBuilder function does not return a value.
Edit: It should return a single Widget for every entry in your list.
Something like this should work.
Also, Padding Widget is missing the padding property.
Flexible(
child: Padding(
child: SingleChildScrollView(
child: ListView.builder(
itemCount: state.data.length,
itemBuilder: (BuildContext context, int index) {
final f = state.data[index];
return AlertCardWidget(
positionId: "${f["8020074"]}",
shipowner: "${f["8020076"]}",
customer: "${f["8020170"]}",
salesRepresenter: "${f["8020176"]}",
operationRepresenter: "${f["8020177"]}",
textContentFontColor:
AppTheme(Theme.of(context).brightness)
.cardFontBackgroundColor,
textfont: Colors.redAccent,
);
},
),
),
),
),