Home > other >  How to make a separate view if there is no item in Dart Flutter listTile?
How to make a separate view if there is no item in Dart Flutter listTile?

Time:03-09

I have an application:

enter image description here

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.

enter image description here

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:

enter image description here

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();
      }
...
  • Related