In documentation of Hive we have delete method for deleting something from database, but this method don't delete from database and it only do null on index of found data and it cause some problem when we want to listen to database changes or making ListView with null data,
another problem is .values that return non-nullable data and when we try to make a ListView we get null error
late Box<Sal> _sal;
useEffect((){
_sal = Hive.box<Sal>('sal') ;
});
// ...
ValueListenableBuilder(
valueListenable: _sal.listenable(),
builder: (_, Box<Sal> sal, __) => ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
itemBuilder: (context, index) {
return Container(
height: 50.0,
margin: EdgeInsets.symmetric(vertical: 0.0),
child: Card(
color: DefaultColors.$lightBrown,
child: Row(
children: [
CText(
text: _sal.get(index)!.salName,
color: Colors.white,
style: AppTheme.of(context).thinCaption(),
).pOnly(right: 16.0),
const Spacer(),
IconButton(
icon: Icon(
Icons.edit,
color: Colors.yellow,
),
onPressed: () => showGeneralDialog(
//...
),
),
IconButton(
icon: Icon(
Icons.delete,
color: Colors.white,
),
onPressed: () => showGeneralDialog(
//...
),
),
],
),
),
);
},
itemCount: _sal.values.length,
),
).pSymmetric(
h: 16,
),
//...
}
I found solution for this problem
late Box<Sal> _sal;
late List<Sal> _data;
useEffect(() {
_sal = Hive.box<Sal>('sal');
_data = _sal.values.toList();
});
//...
ValueListenableBuilder(
valueListenable: Hive.box<Sal>('sal').listenable(),
builder: (_, Box<Sal> sal, __) {
_data = _sal.values.toList();
return ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
itemBuilder: (context, index) {
return Container(
height: 50.0,
margin: EdgeInsets.symmetric(vertical: 0.0),
);
},
itemCount: _data.length,
);
},
),
//...
Related
as of the picture down below, I would like to make listview, where it is possible to add more lines(red) under each listview card.
I have implemented the overall listview(green), with the button that should add a list inside the list. Code is at the bottom
The picture is taken from the Strong app
My design right now is as follows:
Expanded(
// ignore: unnecessary_new
child: new ListView.builder(
itemCount: litems.length,
itemBuilder: (BuildContext ctxt, int Index) {
return Card(
child: Padding(
padding: EdgeInsets.all(10),
child: ExpansionTile(
initiallyExpanded: true,
title: Text(
litems[Index],
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
children: <Widget>[
ElevatedButton(
onPressed: () {
litems.add('hei');
setState(() {});
},
child: const Text('Add Set')),
SizedBox(height: 5),
],
leading: IconButton(
icon: const Icon(
Icons.close,
color: Colors.red,
),
onPressed: () {
litems.removeAt(Index);
setState(() {});
},
),
)));
})),
ElevatedButton(
onPressed: () {
litems.add('hei');
setState(() {});
},
child: const Text('Add Exercises')),
Try my code:
List<List<String>> parent = [];//init Parent
//Parent(Exercises) layout
Column(
children: [
ListView.builder(
itemCount: parent.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return _buildList(parent[index]);
}),
TextButton(
onPressed: () {
parent.add([]);
setState(() {});
},
child: Text("Add Parent"))
],
)
//build children
_buildList(List<String> list) {
return Column(
children: [
ListView.builder(
itemCount: list.length,
shrinkWrap: true,
padding: EdgeInsets.all(0),
physics: const NeverScrollableScrollPhysics(),
itemExtent: 50,
itemBuilder: (context, index) {
return Container(
color: Colors.red.withOpacity((index * 5) / 100),
margin: EdgeInsets.symmetric(vertical: 0),
child: Text('Item'),
);
},
),
TextButton(
onPressed: () {
list.add("value");
setState(() {});
},
child: Text("Add Item"))
],
);
}
I was testing the "tap function" for items within a ListView, but it does not seem to work. The print function does not work when I tap upon the list.
return Scaffold(
appBar: AppBar(
// App Bar
title: Text(
"ListView On-Click Event",
style: TextStyle(color: Colors.grey),
),
elevation: 0,
backgroundColor: Colors.white,
),
// Main List View With Builder
body: ListView.builder(
itemCount: imgList.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
print("button pressed");
print(index);
},
child: Container(
margin: const EdgeInsets.symmetric(
vertical: 2.0,
horizontal: 8.0,
),
child: Stack(
children: <Widget>[
cardDesign,
cardImage,
],
),
),
); // gesturedetector
}));
Where am I going wrong?
Try to used Column instead of Stack
ListView.builder(
shrinkWrap: true,
itemCount: 10,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
print("button pressed");
print(index);
},
child: Container(
margin: const EdgeInsets.symmetric(
vertical: 2.0,
horizontal: 8.0,
),
child: Column(
children: <Widget>[
Text(index.toString()),//put your widgets here
],
),
),
); // gesturedetector
}),
you can use ListTile inside ListView,because ListTile have onTap function, same here :
ListView.builder(
itemCount: data.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: ListTile(
title: Text('TextHere'),
onTap: () {
log('on tap');
},
),
);
});
In a list of expansion tile widgets, I'm trying to build a list (200+ items) when any expansion tile is opened. When i open the expansion tile it builds all the 200 items at once, giving a jank. I'm using Listview.builder so I'm not expecting this behavior. Here's a code snippet.
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: 100,
itemBuilder: (context, i) {
final _expansionTileKey = GlobalKey();
return ExpansionTile(
initiallyExpanded: false,
textColor: Colors.black,
key: _expansionTileKey,
onExpansionChanged: (value) =>
widget.onExpansionChanged(_expansionTileKey),
trailing: Icon(
Icons.keyboard_arrow_down,
),
subtitle: Text(
"$i - $i",
),
title: Text(
'$i',
),
children: <Widget>[
StreamBuilder<List<T>>(
stream: _bloc.stream,
builder: (context, snapshot) {
return ListView.separated(
shrinkWrap: true,
itemCount: _bloc.length,
itemBuilder: (_, index) {
return Container(
color: Colors.white,
child: Text("$index"),
);
},
separatorBuilder: (_, i) => Padding(
padding: const EdgeInsets.only(left: 8, right: 8),
child: const Divider(
height: 1,
),
),
);
},
)
],
);
},
),
First of all, I have class CheckList, in it I have list checkLists and many other variablse like name,position and others, in this list i have CheckList objects.
So in Dismissible key i pass CheckList.checkLists[index] but i got this error
The argument type 'CheckList' can't be assigned to the parameter type 'Key'
Scaffold(
body: Container(
padding: EdgeInsets.all(14.0),
child: ListView.separated(
itemCount: CheckList.checkLists.length,
itemBuilder: (BuildContext Context, int index){
return Dismissible(
key: CheckList.checkLists[index],
child: InkWell(
),
);
},
separatorBuilder: (BuildContext context, int index) {
return Container(
height: 14,
);
}),
),
);
what i need to pass into key?
Second question
Item in ListView must looks like this. This is item from other ListView in my app but i need same with other data in new ListView item
Will my Dismissble item dismiss normaly with this type of code?
Scaffold(
body:
Container(
padding: EdgeInsets.all(14.0),
child: ListView.separated(
itemCount: CheckList.checkListtemplateXmlList.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: (){
CheckList checkList = CheckList();
CheckList.addCheckList(index,checkList);
showDialog(context: context, builder: (BuildContext context){
return AlertDialog(
title: Text('Добавить описание'),
content: TextField(
onChanged: (String value) async{
checkList.description = value;
},
),
actions: [
ElevatedButton(onPressed: () async{
await checkList.writeToFile();
setState(() {
CheckList.checkLists.add(checkList);
});
Navigator.pushNamedAndRemoveUntil(context, '/',(route) => false );
},
child: Text('Добавить'))
],
);
});
},
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Color.fromARGB(255, 141, 166, 255), width: 1),
borderRadius: BorderRadius.circular(10)),
width: 50,
height: 80,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${CheckList.checkListTempaltexmlNameList[index]}",
style: TextStyle(fontSize: 40),
)
],
),
),
);
},
separatorBuilder: (BuildContext context, int index) {
return Container(
height: 14,
);
}),
),
);
The key parameter needs a Key object.
You can either pass
UniqueKey() which will generate a unique key automatically for you
ValueKey(dynamic value) if you want to generate one from some variable. In you case that would be ValueKey(CheckList.checkLists[index]).
I have a simple json parser and listing the news and their categories
now I am trying to do some optimisations on ListTile because I would like to use the news Images bigger and put the news title under but ListTile provide only trailing which it is unusable for me. But I can't add any styling in whole code (new child, Row, etc gives error.) Is it possible to do that in this structure or should I make a customListTile on another page and link the current mechanism to new page?
any help would be really nice
body: Container(
padding: const EdgeInsets.all(
10.0,
),
child: FutureBuilder<Articles>(
future: _futureArticles,
builder: (BuildContext context, AsyncSnapshot<Articles> snapshot) {
if (snapshot.hasData) {
final articles = snapshot.data?.data;
return ListView.builder(
padding: const EdgeInsets.all(
10.0,
),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: articles!.length,
itemBuilder: (BuildContext context, int index) {
return Card(
elevation: 4.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: ListTile(
title: Text(
'Title: ${articles[index].title}',
),
subtitle:
Text('Category: ${articles[index].category?.name}'),
trailing: Image.network(articles[index].imageUrl!),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NewsViewDetail(
id: articles[index].id!,
),
fullscreenDialog: true,
),
);
},
),
);
},
);
} else if (snapshot.hasError) {
return NewsError(
errorMessage: '${snapshot.hasError}',
);
} else {
return const NewsLoading(
text: 'Loading...',
);
}
},
),
),
);
}
}
Try below answer hope its help to you ,use GridView.builder() instead of ListView.builder()
Container(
padding: EdgeInsets.all(10),
child: GridView.builder(
itemCount: 5,//use your length here(articles!.length)
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 1),
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade200),
),
margin: EdgeInsets.all(5),
padding: EdgeInsets.all(5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Image.network(
'your network image here',
fit: BoxFit.fill,
),
),
SizedBox(
height: 15,
),
Text(
'Your headline here',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
],
),
);
},
),
);
your screen look like ->