Giovanni
Giovanni

Reputation: 595

how to build a IOS style list with listview builder in Flutter?

I was wondering how to build a Cupertino list like that, with a listView.builder I did it with the CupertinoFormSection, but when i add the listView.builder inside the form, the list does not show. So, right now i put the CupertinoFormSection after the listView, but the result is not what I want.

desired UI

This is my code:

body: Padding(
    padding: const EdgeInsets.all(8.0),
    child: Container(
      child: ListView.builder(
        itemCount: entries.length,
        itemBuilder: (context, i) {
          return GestureDetector(
            onTap: () {
              setState(() async {
                index = i;
                if (i == 0){
                  await context.setLocale(Locale('en','US'));
                }
                else if (i == 1){
                  await context.setLocale(Locale('fr','FR'));
                }
                else {
                  await context.setLocale(Locale('it','IT'));
                }
              });
            },
            child: CupertinoFormSection(
              children: [
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children:[
                      Text(entries[i]),
                      index == i
                          ? Icon(Icons.check_outlined, color: Colors.blue,)
                          : Icon(null),
                    ],
                  ),
                ),
              ],
            ),
          );
        },
      ),

This is the output:

enter image description here

Upvotes: 3

Views: 3297

Answers (1)

lepsch
lepsch

Reputation: 10319

What you're looking for is the standard widgets CupertinoFormSection and the CupertinoFormRow. They are made specific for this kind of UI.

Check it out (also the live demo on DartPad).

Screenshot

import 'package:flutter/cupertino.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 CupertinoApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

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

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

class Item {
  final String prefix;
  final String? helper;
  const Item({required this.prefix, this.helper});
}

const items = [
  Item(prefix: 'Italiano', helper: 'Italiano'),
  Item(prefix: 'English (US)', helper: 'Inglese (USA)'),
  Item(prefix: 'Español (EE. UU.)', helper: 'Spagnolo (USA)'),
  Item(prefix: 'Italiano (Italia)', helper: 'Italiano (Italia)'),
  Item(prefix: 'Italiano (Svizzera)', helper: 'Italiano (Svizzera)'),
  Item(prefix: 'English', helper: 'Inglese'),
];

class _MyHomePageState extends State<MyHomePage> {
  var _selectedIndex = 0;
  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      child: Container(
        color: const Color.fromARGB(255, 242, 242, 247),
        child: Center(
          child: Container(
            width: 250,
            padding: const EdgeInsets.symmetric(vertical: 16),
            child: SingleChildScrollView(
              child: CupertinoFormSection.insetGrouped(
                children: [
                  ...List.generate(
                    items.length,
                    (index) => GestureDetector(
                      onTap: () => setState(() => _selectedIndex = index),
                      child: buildCupertinoFormRow(
                        items[index].prefix,
                        items[index].helper,
                        selected: _selectedIndex == index,
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  Widget buildCupertinoFormRow(
    String prefix,
    String? helper, {
    bool selected = false,
  }) {
    return CupertinoFormRow(
      prefix: Text(prefix),
      helper: helper != null
          ? Text(
              helper,
              style: Theme.of(context).textTheme.bodySmall,
            )
          : null,
      child: selected
          ? const Icon(
              CupertinoIcons.check_mark,
              color: Color.fromARGB(255, 45, 118, 234),
              size: 20,
            )
          : Container(),
    );
  }
}

Upvotes: 2

Related Questions