I have an application:
The listTile
items here come from the database.
Codes:
Container(
child: Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 40),
child: Column(
children: [
SizedBox(height: 15,),
Text("Profile", style: TextStyle(fontSize: 27),),
Divider(thickness: 1, color: Colors.black,),
SizedBox(height: 5),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Solved Tests:",style: TextStyle(fontSize: 19)),
],
),
SizedBox(height: 20,),
Container(
width: double.infinity,
height: 200,
child: Expanded(
child: FutureBuilder(
future: listUpload(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
late List<String?> items;
if (snapshot.connectionState == ConnectionState.waiting) {
items = [];
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
items = snapshot.data as List<String?>;
} else {
items = [];
}
return Scrollbar(
isAlwaysShown: true,
controller: _scrollContreller,
scrollbarOrientation: ScrollbarOrientation.right,
child: ListView.builder(
controller: _scrollContreller,
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(bottom: 20, left: 10, right: 10),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10),
),
child: ListTile(
title: Text(
items[index].toString(),
style: TextStyle(fontSize: 20),
),
),
),
);
},
),
);
})),
),
Calling items from database:
dynamic listUpload() async {
final prefences = await SharedPreferences.getInstance();
final getTests = prefences.getStringList("tests"); // get item
debugPrint(getTests.toString());
return Future.value(getTests);
}
If there is no data in the database, I want the listTile
to say "not found" in its footprint.
For example, I want to make the system in the picture above. You already understand the system, if there is no data from the database, listTile
will say not found in its place.
The listTile
in my app looks like this when there is no data:
How can I do that? Thanks in advance for the help.
CodePudding user response:
I think you can just have a check for empty data.
if (!snapshot.hasData){
return myEmptyWidget
}
CodePudding user response:
please try:
items.isEmpty ? const SizedBox() : View(),
Code:
Container(
child: Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 40),
child: Column(
children: [
SizedBox(height: 15,),
Text("Profile", style: TextStyle(fontSize: 27),),
Divider(thickness: 1, color: Colors.black,),
SizedBox(height: 5),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Solved Tests:",style: TextStyle(fontSize: 19)),
],
),
SizedBox(height: 20,),
Container(
width: double.infinity,
height: 200,
child: Expanded(
child: FutureBuilder(
future: listUpload(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
late List<String?> items;
if (snapshot.connectionState == ConnectionState.waiting) {
items = [];
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
items = snapshot.data as List<String?>;
} else {
items = [];
}
return Scrollbar(
isAlwaysShown: true,
controller: _scrollContreller,
scrollbarOrientation: ScrollbarOrientation.right,
child: items.isEmpty ? const SizedBox() : ListView.builder(
controller: _scrollContreller,
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(bottom: 20, left: 10, right: 10),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10),
),
child: ListTile(
title: Text(
items[index].toString(),
style: TextStyle(fontSize: 20),
),
),
),
);
},
),
);
})),
),
CodePudding user response:
You're facing this issue because you're not fully using the power of the FutureBuilder !
It'll "emit" states during Load and Success/Error. Whenever a state is emitted, it'll redraw the widget.
Therefore, you can return a Widget matching every state of your FutureBuilder like this
...
child: FutureBuilder(
future: listUpload(),
builder:
(BuildContext context, AsyncSnapshot snapshot) {
late List<String?> items;
if (snapshot.connectionState ==
ConnectionState.waiting) {
return YourLoaderWidget();
} else if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
items = snapshot.data as List<String?>;
if (items.isEmpty) {
return YourEmptyWidget();
} else {
return YourScrollBar();
}
} else {
return YourErrorWidget();
}
...