Display checkbox in listView flutter - flutter

Please help !
I have two checkbox in table row. First checkBox is clickable but the second are not clickable.
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: widget.checklist['sections'].length,
itemBuilder: (context, index) {
final item = widget.checklist['sections'][index];
String s = item['applicable'];
var a = s.split(",");
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Table(
columnWidths: {
0: FixedColumnWidth(
250.0), // fixed to 100 width
1: FlexColumnWidth(),
2: FlexColumnWidth(), //fixed to 100 width
},
defaultColumnWidth: FixedColumnWidth(120),
border: TableBorder.all(),
children: [
TableRow(children: [
TableCell(
child: Container(
color: Colors.grey.shade300,
child: Padding(
padding: EdgeInsets.all(10),
child: Text(item['name'])))),
for (var i in a)
TableCell(
child: Container(
color: Colors.grey.shade300,
child: Padding(
padding: EdgeInsets.all(10),
child: Text(i))))
]),
...item['questions']
.asMap()
.entries
.map((items) {
print(items.key);
return TableRow(children: [
Padding(
padding: EdgeInsets.all(10),
child: Text(items.value['name'])),
Checkbox(
tristate: true,
value: true,
onChanged: (bool value) {
setState(() {
widget.checklist['sections']
[items.keys] = value;
});
},
),
Checkbox(onChanged: null, value: false)
]);
}).toList()
])
]);
// );
})
But I get this error
'package:flutter/src/material/checkbox.dart': Failed assertion: line 76 pos 15: 'tristate || value != null': is not true.

Based on your error, which states that either tristate is not true (which is correct since it defaults to false and you did not set it on your own) or value == null (which will most likely be the case here).
Your Checkbox implementation used this as the value:
Checkbox(
value: values[items.key],
...
),
Your values map does not have one of the items.key as a key. I would recommend you to debug this part or actually set tristate to true and see where your checkbox does indeed have the extra state (will be displayed as "-" in the box).
From there you might figure out which key is not part of your values map!

Try this CheckboxListTile from flutter itself
https://api.flutter.dev/flutter/material/CheckboxListTile-class.html

Related

TextField stops after writing 1 letter flutter

I am trying to modify a TextField inside an ExpansionTile title and when I modify the text I want to update data in my database firestore, this part works fine. The problem is when I write something in my TextField I can only write one letter and then I have to select the TextField again.Initial text field value
Second text field value
In the second picture after writing the number 2 in test the 'blue mark' exits the TextField and if I want to write in the TextField again I have to select the text field again.
This is the TextField code inside the expansion tile, all this code is inside a stream where each list tile is an entry from the database:
return SizedBox(
width: double.infinity,
child: SingleChildScrollView(
child: Column(
children: [
Column(
children: [
ListView.builder(
physics: const ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: widget.shoppingListsCart.length,
itemBuilder: (BuildContext context, int index) {
String shoppingCartListName =
widget.shoppingListsCart.elementAt(index).name;
final shoppingListId =
widget.shoppingListsCart.elementAt(index).shoppingListId;
TextEditingController _textEditingControllerShoppingListName = TextEditingController();
_textEditingControllerShoppingListName.text = shoppingCartListName;
_textEditingControllerShoppingListName.addListener(() {
widget.firebaseCloudStorage.updateShoppingListName(
widget.shoppingCartListId, shoppingListId, _textEditingControllerShoppingListName.text);
});
return Column(
children: [
ExpansionTile(
backgroundColor: Colors.indigo,
title: SizedBox(
child: Row(
children: [
SizedBox(
width: 220,
child: TextField(
decoration: const InputDecoration(
border: InputBorder.none,
counterText: '',
),
controller: _textEditingControllerShoppingListName,
maxLength: 35,),
), ),
Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
IconButton(onPressed: (){
}, icon:Icon(Icons.edit,)),
IconButton(onPressed: () {}, icon: Icon(Icons.delete)),
],
),
]),
),
children: [
ProductsInShoppingListView(
shoppingListName: shoppingCartListName,
shoppingCartId: widget.shoppingCartListId,
shoppingListId: shoppingListId,
firebaseCloudStorage: widget.firebaseCloudStorage,
),
]),
],
);
},
),
Column(
children: [
ProductsInCartView(
shoppingCartId: state.shoppingCartId),
],
),
],
),],
),
),
);
I tried using a Future in the text field and changing from a stateless widget to a stateful widget, the error is something like this TextField accepts only one letter and loses focus after each letter but since I am using flutter that solution didn't work for me. I don't know what is the error because the console doesn't say anything. Please help, thank you.
did you try it? It's TextFormField. Here I fixed the value 1, we can make it a dynamic value. But I hope this will be helpful to think about next.
TextFormField(
onChanged: (value) {
if (value.length == 1) {
FocusScope.of(context).nextFocus(); //whatever you want to do
}
},
inputFormatters: [
LengthLimitingTextInputFormatter(1)
],
),

Fill the available space in Listtile

I am new to the flutter and trying to fill the empty space in the listtile. I tried to use dense and visualDensity but with that, I am not getting the required result. Any support and suggestions will be appreciated.
here is my code and output:
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
SizedBox(
height: isLargeScreen ? 300 : 200,
child: ListView.builder(
physics: const ScrollPhysics(),
shrinkWrap: true,
itemCount: tags.length,
itemBuilder: (context, index) {
return CheckboxListTile(
value: tempSelectedTags.contains(tags[index].id),
onChanged: (e) {
setState(() {
if (tempSelectedTags.contains(tags[index].id)) {
tempSelectedTags.remove(tags[index].id);
} else {
tempSelectedTags.add(tags[index].id);
}
});
},
title: Text(
tags[index].name,
style: !tempSelectedTags.contains(tags[index].id)
? theme.textTheme.labelMedium?.copyWith(
color: ThemeConfig.colorTertiary)
: theme.textTheme.titleSmall?.copyWith(
color: ThemeConfig.colorTertiary),
),
);
}),
),
const Spacer(),
Padding(
padding: const EdgeInsets.only(bottom:sdPaddingMedium),
child: SdPrimaryButton(
title: appLocalizations.btnApply,
onPressed: () {
viewModel.setTags(tempSelectedTags);
Navigator.pop(context);
},
),
),
],
)
Output can be seen here
There are two important things that determine the vertical layout in your column.
The whole box has a fixed size
SizedBox(
height: isLargeScreen ? 300 : 200,
There is a flexible space between the checkbox options and the bottom-right button
const Spacer(),
So if you want to remove the space, you can either
reduce the overall box size or
replace the const Spacer with a constant spacing like
SizedBox(height: 50) and also remove the SizedBox, so that the whole box will be content-sized

Flutter Xlider - setState - value remains 0 and snaps back

This might be just a simple problem but I can't figure it out somehow right now. I am using the Flutter xslider https://pub.dev/packages/flutter_xlider vertically with values from 0 to 90. When I am dragging the slider it repaints a line depending on the value of the slider and simultaneously it changes the numeric value in a TextField. This once worked but after adding the TextField and updating all the components (Flutter. Dart. Packages. AndroidStudio) I have the following problem:
because of the line setState(() { }); in onDragging the value of the slider always remains 0 and snaps back after the dragging is finished. if I leave out the setState method the slider works however my line gets of course not painted. what am I doing wrong? does it has something to do with the surrounding components while building? or is there another reason?
UPDATE: i found the solution. I now update the values property by myself such as values: [sliderValue] whereas sliderValue is a double initialized once and then updated within the onDragging. its strange that this is never suggested inside the documentation
body: Column(
children: [
new Padding(
padding: new EdgeInsets.all(15.0),
),
angleTextQuestion,
new Padding(
child: Column(children:[ TextField( controller: txtAngleC,
keyboardType: TextInputType.number,
onChanged: (text) {
double angle = double.parse(text);
if(angle >= 0 && angle <= 90) {
_angleAirplane = double.parse(text);
setState(() {});
}
},),
Text("(type in a value between 0 - 90)")
]),
padding: new EdgeInsets.all(15.0),
),
Expanded( child: new Row( children: [
new Padding(
padding: new EdgeInsets.all(20.0),
),
Expanded( child: new SizedBox(
height: 250,
width: 50,
child: FlutterSlider(
values: [0],
rangeSlider: false,
max: 90,
min: 0,
rtl: true,
step: FlutterSliderStep(step: 1.0),
axis: Axis.vertical,
tooltip: FlutterSliderTooltip(
textStyle: TextStyle(fontSize: 14, color: Colors.lightBlue),
),
onDragging: (handlerIndex, lowerValue, upperValue) {
_angleAirplane = lowerValue;
txtAngleC.text = _angleAirplane.toString();
setState(() { });
},
))),
Text(_angleAirplane.toString()),
new Padding(
padding: new EdgeInsets.all(10.0),
),
Expanded( child: new CustomPaint(
foregroundPainter: new AnglePainter(
angle: _angleAirplane
)))
]
)),
]
),
```
change values:[0] to this
values: [_angleAirplane]
this happens because there is a setState inside your onDragging method and redraw the slider with 0 value.

How to use item count in ListView.Builder?

Click Here for Image! Click here to see error when i input 'itemCount' I want to ask, I am having trouble using the List.builder () feature. where I can't limit the data contained in the list so that it will display an error message about the error range. Here is the source code that I gave.
_sort = <Sort>[
Sort(
category: 'By Games',
item: new Container(
height: 200,
child: new Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
//itemCount: allGames['games'].length,
itemBuilder: (context, index) {
return Container(
child: Padding(
padding: const EdgeInsets.all(15),
child: Text(allGames['games'][index]['game_title'].toString(), style: new TextStyle(color: Colors.white)),
),
);
},
)))),
and here i call the 'Category' and 'Item'. I wrap it in a wrap widget. then for categories, I did divide it into 3 parts. then every part in the category I named 'items' and the problem is the items here have excess capacity so that the data displayed is leftover and not on target.
child: Wrap(
children: <Widget>[
ListView.builder(
shrinkWrap: true,
itemCount: 3,
itemBuilder: (context, index) {
context = context;
if (index < 2) {
final sort = _sort[index];
return ExpansionTile(
title: ListTile(
title: Text(
sort.category,
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
),
children: <Widget>[
ListTile(
title: sort.item,
)
],
);
} else {
),
You're accessing allGames["games"] and it says that you're trying to use [] on null.
Seems like allGames is null, so put an eye on that.
Other than that, your use of itemCount is fine!
You can add some null awareness by doing something like this:
itemCount = allGames != null ? (allGames["games"]?.length ?? 0) : 0
I think when the build method runs at the first time, your allGames is null. So, try to add a default value, for example:
itemCount: allGames['games'].length ?? 0

Flutter GridView.builder is Generating Unwanted Extra Space

I am trying to display a row of buttons. Since the number of buttons depends on the number of elements in a List, I have to use GridView.builder to dynamically create the right amount of buttons. Unfortunately it seems that GridView.builder is taking up alot of unnecessary space. Anyone know what is wrong here?
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// Dice buttons
Flexible(
child: GridView.builder(
itemCount: dices.length,
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: dices.length,
),
itemBuilder: (BuildContext context, int index) {
return new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ButtonTheme(
minWidth: 50.0,
height: 50.0,
child: RaisedButton(
child: Text(
dices[index].toString(),
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
color: usedDices[index] || !expectNum
? Colors.grey
: Colors.black,
onPressed: () {
if (!usedDices[index] && expectNum) {
setState(() {
numUsed[turn] = dices[index].toString();
numUsedIndex[turn] = index;
});
expectNum = false;
usedDices[index] = true;
}
},
),
),
]);
})),
Link to Pic: https://drive.google.com/file/d/1_Jr4rz9GJ-D8-Xjxs2w8Sn8lOdnBBqTc/view?usp=sharing
As you can see are lots of unnecessary space here and it seems to be the reuslt of GridView.builder
That space is the result of Flexible, which fills the available space. You will see that if you replace it with a Container and give it a height, it won't produce that much space below.
Just had this problem, top SliverPadding is set to 20.0 by default. Looking at docs I see:
/// By default, [ListView] will automatically pad the list's scrollable
/// extremities to avoid partial obstructions indicated by [MediaQuery]'s
/// padding. To avoid this behavior, override with a zero [padding] property.
So,
GridView.builder(
// shrinkWrap: true,
padding: EdgeInsets.zero,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 1,
mainAxisSpacing: 1,
crossAxisCount: 3,
),
itemBuilder: (context, index) {
return Container(
color: Colors.black,
);
},
itemCount: 10,
),
or
If you put a widget before the ListView, you should wrap the ListView with a
MediaQuery.removePadding widget (with removeTop: true)