Ad

How Do I Make A Tab And Tab Bar View Dynamic In Flutter So That It Will Ha On The Response From An Api?

- 1 answer

I am trying to create a list, add data to the list based on received responses but it is not working.

I tried to loop through the database to check data exist before adding to the list. I seem not to be doing it well.

My challenge is to dynamically control the things I add to the list. so that it will change based on that.

    Updated the codes.
      //Defualt tab controller
       DefaultTabController(
        length: tabs.length,
       child: Column(
          children: [
            Container(
              child: TabBar(
                labelColor: HexColor("#006E40"),
                unselectedLabelColor: Colors.black,
                indicatorColor: HexColor("#006E40"),
                indicatorWeight: 3,
                indicatorPadding: (EdgeInsets.symmetric(horizontal: 
                10.0)),
                isScrollable: true,
              //  controller: _tabController,
                tabs: tabs ), // tabs List 
            ),
            SizedBox(height: 15),
            Container(
              margin: const EdgeInsets.only(bottom: 20.0),
              height: MediaQuery
                  .of(context)
                  .size
                  .height * 0.8,
              child: Padding(
                padding: const EdgeInsets.only(bottom: 28.0),
                child: TabBarView(
                  children: tabsItems ), // Tab Bar List
              ),}
 // Checking whether the item already exist then adding to the list 
 //  based on result
  Lsit<DatabaseItemsPastaSelf> databaseItemsPasta = [] 

  Future readPastaItems() async {
this.databaseItemsPasta = await 
  PastaDatabaseSelf.instance.readAllItems();
   for(int i = 0; i<databaseItemsPasta.length; i++){
    if (databaseItemsPasta.length != 0) {
     tabs.add(
      Padding(
        padding: const EdgeInsets.only(top: 20),
        child: Text(
          "Fruits",
          style: TextStyle(fontWeight: FontWeight.w700, fontSize: 
               14),
            ),
          ),
        );
        tabsItems.add(PastaAndNoodlesSelf());
        break;
        }
      }
      return databaseItemsPasta.length;
      }

    List<DatabaseItemsSugarSelf> databaseItemsSugar = [];

    Future readSugarItems() async {
    this.databaseItemsSugar = await 
    SugarDatabaseSelf.instance.readAllItems();
     for(int i = 0; i<databaseItemsSugar.length; i++){
       if (databaseItemsSugar.length != 0) {
       tabs.add(
         Padding(
          padding: const EdgeInsets.only(top: 20),
           child: Text(
           "Foods",
            style: TextStyle(fontWeight: FontWeight.w700, fontSize: 
          14),
        ),
      ),
    );
     tabsItems.add(SugarSelf());
       break;
  }
   }
   return databaseItemsSugar.length;
    }


   List<Widget> tabs = [];
  List<Widget> tabsItems = [];
  }

      
Ad

Answer

You can use the FutureBuilder, map function, and state management as following

FutureBuilder: listening to fetching data state. map function: to iterate throw data list. state management to update data list state.

please update the

readPastaItems()

to be

var tabIndex = 0;
bool isLoadingData = false;

List<dynamic> databaseItemsPasta = [];


Future readPastaItems() async {
  isLoadingData = true;
  await PastaDatabaseSelf.instance.readAllItems().then((records) {
    this.databaseItemsPasta = records;
    isLoadingData = false;
  });
}

and update the

DefaultTabController

to be wrapped with FutureBuilder

FutureBuilder(
future: Future.delayed(Duration.zero, () => readPastaItems()),
builder: (context, snapshot) {

  if(isLoadingData) return CircularProgressIndicator();
  if(snapshot.hasError) return Text('error');
  if(!snapshot.hasData || this.databaseItemsPasta.isEmpty) return Text('no data');

  if(this.databaseItemsPasta.length > 0)  return DefaultTabController(
    length: databaseItemsPasta?.length ?? 0,
    initialIndex: tabIndex,
    child: Scaffold(
      appBar: AppBar(),
      body: TabBarView(
        physics: NeverScrollableScrollPhysics(),
        children: databaseItemsPasta.map((databaseItem) =>
            Padding(padding: const EdgeInsets.only(top: 12, bottom: 12), child: Text('${databaseItem.toString()}')),
        ).toList(),
      ),
      bottomNavigationBar: TabBar(
        labelColor: Colors.black45,
        tabs: databaseItemsPasta.map((databaseItem) =>
            Padding(padding: const EdgeInsets.only(top: 12, bottom: 12), child: Text('${databaseItem.toString()}')),
        ).toList(),
      ),
    ),
  );

  return SizedBox();
}
)
Ad
source: stackoverflow.com
Ad