Hiểu về ListView.builder

Aug 18 2020

Được rồi, vì vậy tôi nghĩ rằng tôi đang mắc kẹt với trình xây dựng cánh quạt một chút.

Tôi đã tạo một ứng dụng đơn giản, chỉ để làm cho câu hỏi của tôi dễ dàng hơn:

Tôi có một lớp dữ liệu:

    class DataLists {
  List<ListTile> lists = [
    ListTile(
      leading: Text('Tile Leading 1'),
      title: Text('Tile Title 1'),
      subtitle: Text('Tile Subtitle 1'),
      trailing: Text('Tile Trailing 1'),
    ),
    ListTile(
      leading: Text('Tile Leading 2'),
      title: Text('Tile Title 2'),
      subtitle: Text('Tile Subtitle 2'),
      trailing: Text('Tile Trailing 2'),
    ),
    ListTile(
      leading: Text('Tile Leading 3'),
      title: Text('Tile Title 3'),
      subtitle: Text('Tile Subtitle 3'),
      trailing: Text('Tile Trailing 3'),
    ),
    ListTile(
      leading: Text('Tile Leading 4'),
      title: Text('Tile Title 4'),
      subtitle: Text('Tile Subtitle 4'),
      trailing: Text('Tile Trailing 4'),
    ),
    ListTile(
      leading: Text('Tile Leading 5'),
      title: Text('Tile Title 5'),
      subtitle: Text('Tile Subtitle 5'),
      trailing: Text('Tile Trailing 5'),
    ),
  ];
}

Và tệp phi tiêu chính:

import 'package:flutter/material.dart';
import 'package:learning/data.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TestTile(),
    );
  }
}

class TestTile extends StatefulWidget {
  @override
  _TestTileState createState() => _TestTileState();
}

class _TestTileState extends State<TestTile> {
  DataLists dataLists = DataLists();
  TextEditingController leadingController = TextEditingController();
  TextEditingController titleController = TextEditingController();
  TextEditingController subtitleController = TextEditingController();
  TextEditingController trailingController = TextEditingController();
  Future<String> createDialog(BuildContext context) {
    return showDialog(context: context, builder: (context) {
      return SimpleDialog(
        title: Text('Input data: '),
        children: [
          TextField(
            controller: leadingController,
          ),
          TextField(
            controller: titleController,
          ),
          TextField(
            controller: subtitleController,
          ),
          TextField(
            controller: trailingController,
          ),
          MaterialButton(
            child: Text('Submit'),
            onPressed: () {
              Navigator.of(context).pop(leadingController.text);
              setState(() {
                List<ListTile> tempList = dataLists.lists;
                if (titleController.text.isNotEmpty && leadingController.text.isNotEmpty && subtitleController.text.isNotEmpty && trailingController.text.isNotEmpty) {
                  tempList.add(
                    ListTile(
                      leading: Text(leadingController.text),
                      title: Text(titleController.text),
                      subtitle: Text(subtitleController.text),
                      trailing: Text(trailingController.text),
                    ),
                  );
                  dataLists.lists = tempList;
                } else {
                  print('Null values');
                }
                leadingController.clear();
                titleController.clear();
                subtitleController.clear();
                trailingController.clear();
              });
            },
          ),
        ],
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Test Tile'),
      ),
      body: Container(
        child: SafeArea(
          child: ListView(
            children: <ListTile>[
              for (ListTile e in dataLists.lists)
                e
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          createDialog(context);
          setState(() {

          });
        },
        child: Icon(Icons.add),
        backgroundColor: Colors.blue,
      ),
    );
  }
}

Vấn đề là: Tôi không thể làm cho nó hoạt động theo cách khác. Ai đó có thể thay đổi triển khai của tôi thành ListView.builder không? Tôi hơi mắc kẹt một chút :( Mục tiêu chính:

Ý tưởng: Bấm vào nút -> biểu mẫu xuất hiện -> sau khi bạn bấm nút gửi danh sách sẽ được cập nhật ngay lập tức, mình sẽ thêm chức năng xóa sau, chỉ học tài liệu thôi, không cần gì nữa.

Ai đó có thể xem lại mã của tôi và, nếu không quan tâm, cố gắng viết lại cùng một ý tưởng, nhưng bằng cách sử dụng ListView.builder?

Tôi đã thử nhiều lần, nhưng không thể lấy các thuộc tính một cách chính xác từ biểu mẫu và cập nhật danh sách bằng trình tạo, cần trợ giúp

Chúc mừng!

Trả lời

2 Alok Aug 18 2020 at 01:11

ListView.builder yêu cầu chiều cao tĩnh, vì vậy hãy theo dõi chiều cao đó. Bây giờ, đến với câu hỏi mà bạn muốn sử dụng ListView.builder. Bạn có thể làm thông qua điều này

Container(
  height: give_your_height,
  child: ListView.builder(
    shrinkWrap: true,
    itemCount: dataLists.lists.length,
    itemBuilder: (context, index) {
      return dataLists.lists[index];
    }
  )
)
1 ShriHari Aug 18 2020 at 01:03

Hãy thử điều này, nó có thể giải quyết vấn đề của bạn.

ListView(
   children: [
        for (ListTile e in dataLists.lists)
          Card(child: e)
     ],
  ),

Hoặc với ListView.builder()

ListView.builder(
  itemCount: dataLists.lists.length,
  itemBuilder: (context, index) {
    return dataLists.lists[index];
  },
);

Tham khảo thêm: https://api.flutter.dev/flutter/material/ListTile-class.html