Can you please tell me if it is possible to create a ListView but always have 1 fixed item at the end of the list, thus allowing a new card to be added. As shown in the screenshot below. There is a regular list of cards and at the end a card with an Add New Point button, when clicked, an action occurs (adding a new element to the end of the list).
If you know how to implement such an element as Add New Poynt, please tell me, I will be grateful.
Very simple, use [...oldList] to create a new List and add your fixed item after it like [...oldList, fixedItem].
Example:
Example with ListView:
You can increase itemLength by 1 and while check if the index is last one, provide your fixed widget.
ListView.builder(
itemCount: itemLength + 1,
itemBuilder: (context, index) {
if (index == itemLength) {
return Text("last Item");
}
return Text("item $index");
},
),
This is only logic please try it your own widget. Because I have not laptop.
**This code has syntax error please chaeck it because i have not laptop **
int howManyWidgetDraw = 5;
ListView.builder(
itemCount: howManyWidgetDraw,
itemBuilder: (BuildContext context,int
index){
if(howManyWidgetDraw==index.length){
return InkWell(
onTap(){
howManyWidgetDraw=howManyWidgetDraw+1;
//Call setstate method.
},
child: Text("last element print"));
}
else{
return Text("first four element");
}
}
),
);
Have any issue please ask me?
Try to use ListView.separated:
ListView.separated(
itemCount: _myList.length,
itemBuilder: (context, index){
return /* Your list item widget here */;
},
separatorBuilder: (context, index){
if(index == _myList.length-1) {return Text('Add New Poynt');}
else {return SizedBox();}
}
),
Related
// Build the whole list of todo items
Widget _buildTodoList() {
return new ListView.builder(
itemBuilder: (context, index) {
// itemBuilder will be automatically be called as many times as it takes for the
// list to fill up its available space, which is most likely more than the
// number of todo items we have. So, we need to check the index is OK.
if (index < _todoItems.length) {
return _buildTodoItem(_todoItems[index], index);
}
},
);
}
Attempting to run a simple widget inside my program but receive the
"body_might_complete_normally" error.
How can I correct this?
itemBuilder only return on (index < _todoItems.length), you need to make sure return widget on every case.
Widget _buildTodoList() {
return ListView.builder(
itemCount:_todoItems.length, // your list length
itemBuilder: (context, index) {
if (index < _todoItems.length) {
return _buildTodoItem(_todoItems[index], index);
}
return Text("default case");// if above condtions dont meet, return this
},
);
}
I got a list of questions. When the user doesn't like the question, it can be added to a hidden list. Now I would like list all the questions which have been added to the hidden list.
The Firestore IDs are added to an array within a provider (setting).
When I build the ListView I want to fetch the question documents by document id and pass those document fields to the HiddenList widget.
I've tryied using StreamBuilder, Future,.. unfortunately nothing worked so far..
Any pointers?
Code:
var questions = FirebaseFirestore.instance.collection('questions');
if (setting.hidden.length == 0) {
return Text('Empty');
} else {
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: setting.hidden.length,
itemBuilder: (context, index) {
return new StreamBuilder(
stream: questions.doc('${setting.hidden[index]}').snapshots(),
builder: (context, docSnapshot) {
if (!docSnapshot.hasData) {
return Center(child: CircularProgressIndicator());
} else {
var data = docSnapshot.data!;
return HiddenList(
de_du: data['de_du'],
de_sie: data['de_sie'],
de_ich: data['de_ich'],
en: data['en'],
id: setting.hidden[index],
);
}
});
},
);
}
Trying to use StreamBuilder to build out a ListView, but it is showing one item in each row of the ListView. I am using StreamBuilder broadcast. I use add(data).
child: StreamBuilder<GoogleAddress>(
stream: pickupStreamController.stream,
builder: (context, snapshot) => ListView.builder(
itemCount: 8,
itemBuilder: (context, index) {
print('Render $index');
if (snapshot.data != null) {
print("${snapshot.data.address}");
return _createListItem(
icon: Icons.location_on,
googleplace: snapshot.data,
onTap: () {
print("${snapshot.data.address}");
});
} else {}
},
),
),
Here is the StreamController code where I add to the stream. It is adding different GoogleAddress data on each iteration.
GoogleAddress addy = GoogleAddress.fromJsonMap(map);
if (sc != null) {
sc.add(addy);
}
StreamBuilder will use the latest value from the stream. To pass a list to StreamBuilder you would need to pass a list to add.
Which means to grow a list over time, you have to keep a regular list and pass it to add after modifying it.
final addresses = [];
GoogleAddress addy = GoogleAddress.fromJsonMap(map);
addresses.add(addy);
controller.add(addresses);
What I want to do is to add an extra LisTile to the last of ListView but I still don't figure it out.
My current code is like this.
child: ListView.builder(
itemBuilder: (context, index) {
if (index == 0) {
// Add an extra item to the start
return ListTile(
...
);
}
index -= 1;
final item = _items[index];
// I want to an extra item here as well
if (index == _items.length) {
return ListTile();
}
return ListTile(
...
);
},
itemCount: _items.length + 2,
I've already tried the way above, but it doesn't work. There is an error.
Invalid value: not in range 0..4, inclusive 5
When I changed itemCount to _items.length + 1, it doesn't show the extra ListTile I want to add to the end.
If you want to add to the beginning and the end as well check below
child: ListView.builder(
itemBuilder: (context, index) {
if (index == 0) {
// Add an extra item to the start
return ListTile(
...
);
}
if (index == _items.length + 1) {
return ListTile();
}
index -= 1;
final item = _items[index];
return ListTile(
...
);
},
itemCount: _items.length + 2,
your bug is here:
itemCount: _items.length + 2,
you should increase it by one
because you added 2 elements and for the last call you get index = list.length + 1, and then you subtract 1 from it, and you end up 1 over your length.
ex lets say your list have 5 elements, because you have
itemCount: _items.length + 2
Listview will call your func 7 times, and in 7th call your index is 6 and you are doing index =-1, which equals to 5, and 5 is over your range. (you have form 0 to 4)
I am new to Flutter and facing an issue with StreamBuilder & ListView.builder.
I am making a network call on click of a button(Apply Button) available in the list of the card, based on that other buttons are displayed.
the issue I am facing is that widgets are not updated after successful network call but, when I refresh the page I am getting updated result.
What I am doing wrong?
I am not Using any State into this. Do I need to use it?
Widget Code
StreamBuilder(
initialData: [],
stream: dataBoc.ListData,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemBuilder: (BuildContext context, index) {
return InkWell(
key: Key(snapshot.data[index]["lid"]),
child: DataCard(
DataModel(snapshot.data[index]),
),
onTap: () {
Navigator.pushNamed(context, "/detailPage",
arguments: snapshot.data[index]["id"]);
},
);
},
itemCount: snapshot.data.length,
);
}
},
),
Bloc Code
//Here is how I am adding data to the stream
if (res.statusCode == 200) {
var data = json.decode(res.body);
if (data['status'] == true) {
// listDataStream.sink.add(data['result']);
listDataStream.add(data['result']);
} else {
listDataStream.sink.addError("Failed to Load");
}
}
Expected result: When I make Network call and if it succeeds then based on network result other buttons must be displayed on the appropriate card.
I have fixed this issue. The issue was my widget tree was not well structured and it was breaking the Widget build process.