Solved: Flutter adding items dynamically to ListView in Stateless Widget

Question

Asked by user467566 on December 20, 2021 (source).

I'm creating an Flutter application. And I'm 3-th day can't to add items to ListView manually with 'Add' button.

I'm tried to use setState, but it doesn't work in Stateless widget. Because I have a route from Stateful widget to Stateless. I'm using Navigator.push(...).

Then I'm tried to use Cubit, but it doesn't work. Flutter - BloC Cubit function doesn't emitting state

What can I do?

[Code is so large. I'm uploaded the neccessary part]

Home Page (Stateful Widget)

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

State of Stateful Widget

class _MyHomePageState extends State<MyHomePage> {
 @override
  Widget build(BuildContext context) {
   return Scaffold(
      appBar: AppBar(
       title: 'List App',
       actions: [
          IconButton(
              onPressed: () {
                Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => SearchPage())
                );
                }
           ])
})

SearchPage (With ListView)

class SearchPage extends StatelessWidget {
  const SearchPage({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      child: Builder(builder: (BuildContext context) {
        final TabController tabController = DefaultTabController.of(context)!;
        tabController.addListener(() {
          if (!tabController.indexIsChanging) {
          }
        });
return Scaffold(
body: (context, items) => TabBarView(
children: [
Container(
child: FutureBuilder(
                      future: items_client.getItems(),
                      builder: (BuildContext context, AsyncSnapshot<List<Item>> snapshot) {
                        if (snapshot.hasData) {
                          items = snapshot.data!;

return ListView(
                                children: items.asMap()
                                    .map(
                                      (i, item) => MapEntry(i, 
Column(
    children: [
      Text('${item.name'})
    ]

))
)
}
}
)
]
)
)
  }
}

Answer

Question answered by Sagar A (source).

So as far from your code i have created an example for you please check the example

MainPage:

import 'package:demo_stack/search_page.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('List app'),
        actions: [
          IconButton(
              onPressed: () {
                Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (context) => const SearchPage()));
              },
              icon: const Icon(Icons.six__ft_apart_rounded))
        ],
      ),
    );
  }
}

Search widget.

import 'package:flutter/material.dart';

class SearchPage extends StatefulWidget {
  const SearchPage({Key? key}) : super(key: key);

  @override
  State<SearchPage> createState() => _SearchPageState();
}

// Using the statefull widget to change the index of tab bars
class _SearchPageState extends State<SearchPage> {
  var tabIndex = 0;

  @override
  Widget build(BuildContext context) {
    var childList = [
      const FirstPage(),
      Container(color: Colors.red),
      Container(color: Colors.yellow),
      Container(color: Colors.cyan),
    ];

    return Scaffold(
      body: DefaultTabController(
        length: 4,
        initialIndex: tabIndex,
        child: Scaffold(
          appBar: AppBar(),
          body: childList[tabIndex],
          bottomNavigationBar: TabBar(
            onTap: (index) {
              setState(() {
                tabIndex = index;
              });
            },
            labelColor: Colors.black,
            tabs: const <Widget>[
              Tab(text: 'First Page'),
              Tab(text: 'Red'),
              Tab(text: 'Yellow'),
              Tab(text: 'Cyan'),
            ],
          ),
        ),
      ),
    );
    ;
  }
}

class FirstPage extends StatelessWidget {
  const FirstPage({Key? key}) : super(key: key);

  Future<List<Item>> getItems() async {
    await Future.delayed(const Duration(seconds: 3));

    return [Item("one"), Item("two"), Item("three")];
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<Item>>(
        future: getItems(),
        builder: (BuildContext context, snapshot) {
          
          //This is to check currently in which state the app is 
          // there are four states none,waiting,active,done
          // you can add the check accordingly
          
          print(snapshot.connectionState);
          
          return snapshot.data == null
              ? const Center(
                  child: CircularProgressIndicator(),
                )
              : ListView.builder(
                  itemCount: snapshot.data!.length,
                  itemBuilder: (context, index) {
                    var item = snapshot.data![index];
                    return Padding(
                      padding: const EdgeInsets.all(15.0),
                      child: Text(item.name),
                    );
                  });
        });
  }
}

class Item {
  final String name;

  Item(this.name);
}


This is the search page

If you still face any issue then check the futurebuilder states and add checks accordinly it will work.

Thanks.

ANDROID BLOC FLUTTER
SHARE: