Search code examples
flutterflutter-listview

Flutter How can I pass more than 2 values to another screen on ListView?


I am making a bookmark app that you can add title and URL from a dialog and listed on the screen. I am trying to pass values from 2 textfields on Dialog to ListView on the last screen but I could not make it. On the dialog, there are 2 textfields (Title and URL) and I would like to pass these texts to ListView on last screen. I'v tried to use pop method but it doesn't work. Could anyone help me please? Here is the whole codes.

main.dart

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

class BookmarkApp extends StatelessWidget {
  const BookmarkApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Bookmark App',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      home:  BookmarkListPage(text: '', url: '',),
    );
  }
}

class BookmarkListPage extends StatefulWidget {
  BookmarkListPage({super.key, title, required this.text, required this.url});

  String text;
  String url;

  final String title = 'Bookmark List';

  @override
  State<BookmarkListPage> createState() => _BookmarkListPageState();
}

class _BookmarkListPageState extends State<BookmarkListPage> {

  List<String> bookmarkList = [];
  List<String> bookmarkUrl = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        title: Text(widget.title),
        bottom: PreferredSize(
          child: Container(
            height: 1,
            color: Colors.black,
          ),
          preferredSize: Size.fromHeight(1),
        ),
      ),
      body: ListView.builder(
        itemCount: bookmarkList.length,
        itemBuilder: (context, index) {
          return Card(
            child: ListTile(
              title: Text(bookmarkList[index]),
              subtitle: Text(bookmarkUrl[index]),
            ),
          );
        },
      ),

      // show dialog to add a bookmark
      floatingActionButton: FloatingActionButton(
        shape: const CircleBorder(),
        backgroundColor: Colors.blue,
        onPressed: () async {
          final newBookmarkList = await showDialog(
              context: context,
              builder: (_) {
                return BookmarkDialog();
              });

          if (newBookmarkList != null) {
            setState(() {
              bookmarkList.add(newBookmarkList);
              bookmarkUrl.add(newBookmarkList);
            });
          }
        },
        child: const Icon(
          Icons.add,
          color: Colors.white,
        ),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

dialog.dart

class BookmarkDialog extends StatefulWidget {
  const BookmarkDialog({super.key});

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

class BookMarkDialogState extends State<BookmarkDialog> {
  String bookmarkTitle = "";
  String bookmarkUrl = "";

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: const Text('Add Bookmark'),
      content: Column(
        children: [
          Text('Title'),
          TextField(onChanged: (value) {
            setState(() {
              bookmarkTitle = value;
            });
          }),
          Text('URL'),
          TextField(
            onChanged: (value) {
              setState(() {
                bookmarkUrl = value;
              });
            },
          )
        ],
      ),
      actions: <Widget>[
        GestureDetector(
          child: const Text('Cancel'),
          onTap: () {
            Navigator.pop(context);
          },
        ),
        GestureDetector(
          child: const Text('Add'),
          onTap: () {
            Navigator.of(context).pop(bookmarkTitle);
          },
        )
      ],
    );
  }
}

Solution

  • If you are using Dart version of at least 3.0, you can use Record.

    Navigator.of(context).pop((bookmarkTitle, bookmarkUrl));
    

    You can then read the values by using pattern variable declaration:

    final (newBookmarkTitle, newBookmarkUrl) = await showDialog(
      context: context,
      builder: (_) {
        return BookmarkDialog();
    });