简体   繁体   English

如何在 Dart/Flutter 中单击按钮时更改小部件中的文本?

[英]How to change text in widget on button click in Dart/Flutter?

I need to change the text in this widget when the button is clicked.单击按钮时,我需要更改此小部件中的文本。

That is, every time I click on the button, the text changes to what is in the first column of my lit.也就是说,每次我单击按钮时,文本都会更改为我点亮的第一列中的内容。 First the first line, then the second line, and so on until the end.首先是第一行,然后是第二行,以此类推,直到最后。

Here is the code:这是代码:

// CSV Experiment route
class CSVExperimentRoute extends StatelessWidget {
  const CSVExperimentRoute({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'CSV Experiment',
      home: ListFromCSV(),
    );
  }
}

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

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

class _ListFromCSVState extends State<ListFromCSV> {
  List<List<dynamic>> _data = [];

  // This function is triggered when my button is pressed
  void _loadCSV() async {
    final _rawData = await rootBundle.loadString("files/Text.csv");
    List<List<dynamic>> _listData =
    const CsvToListConverter().convert(_rawData);
    setState(() {
      _data = _listData;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("My CSV Attempt"),
      ),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              const SizedBox(height: 30),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Container(
                        decoration: const BoxDecoration(
                          gradient: LinearGradient(
                            colors: <Color>[
                              Color(0xFF0D47A1),
                              Color(0xFF1976D2),
                              Color(0xFF42A5F5),
                            ],
                          ),
                        ),
                      ),
                    ),
                    TextButton(
                      style: TextButton.styleFrom(
                        padding: const EdgeInsets.all(16.0),
                        primary: Colors.white,
                        textStyle: const TextStyle(fontSize: 20),
                      ),
                      onPressed: _loadCSV,
                      child: const Text('Click me to change Text'),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 30),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Container(
                        decoration: const BoxDecoration(
                          gradient: LinearGradient(
                            colors: <Color>[
                              Color(0xFF0D47A1),
                              Color(0xFF1976D2),
                              Color(0xFF42A5F5),
                            ],
                          ),
                        ),
                      ),
                    ),
                    TextButton(
                      style: TextButton.styleFrom(
                        padding: const EdgeInsets.all(16.0),
                        primary: Colors.white,
                        textStyle: const TextStyle(fontSize: 20),
                      ),
                      onPressed: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(builder: (context) => const YetAnotherRoute()),
                        );
                      },
                      child: const Text('Button 2'),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 30),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Container(
                        decoration: const BoxDecoration(
                          gradient: LinearGradient(
                            colors: <Color>[
                              Color(0xFF0D47A1),
                              Color(0xFF1976D2),
                              Color(0xFF42A5F5),
                            ],
                          ),
                        ),
                      ),
                    ),
                    TextButton(
                      style: TextButton.styleFrom(
                        padding: const EdgeInsets.all(16.0),
                        primary: Colors.white,
                        textStyle: const TextStyle(fontSize: 20),
                      ),
                      onPressed: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(builder: (context) => const CSVRoute()),
                        );
                      },
                      child: const Text('Button 3'),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 30),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Container(
                        decoration: const BoxDecoration(
                          gradient: LinearGradient(
                            colors: <Color>[
                              // Color(0xFF0D47A1),
                              // Color(0xFF1976D2),
                              // Color(0xFF42A5F5),
                            ],
                          ),
                        ),
                      ),
                    ),
                    Text(
                      'Item from CSV',
                      textAlign: TextAlign.center,
                      overflow: TextOverflow.ellipsis,
                      style: const TextStyle(fontWeight: FontWeight.bold),
                    )
                  ],
                ),
              ),

            ],
          ),
        )
      // Display the contents from the CSV file
      // body: ListView.builder(
      //   itemCount: _data.length,
      //   itemBuilder: (_, index) {
      //     return Card(
      //       margin: const EdgeInsets.all(3),
      //       color: index == 0 ? Colors.amber : Colors.white,
      //       child: ListTile(
      //         leading: Text(_data[index][0].toString()),
      //         // title: Text(_data[index][1]),
      //         // trailing: Text(_data[index][2].toString()),
      //       ),
      //     );
      //   },
      // ),
    );
  }
}

And here is a schematic representation of what I want:这是我想要的示意图:

截屏

Thanks in advance for your help.在此先感谢您的帮助。

Edit1.编辑1。 If added to text如果添加到文本中

Text(
                      _data[0].toString() != null ? 
                      _data[0].toString() : '',
                      textAlign: TextAlign.center,
                      overflow: TextOverflow.ellipsis,
                      style: const TextStyle(fontWeight: FontWeight.bold),
                    )

, then I get the following error: ,然后我收到以下错误:

在此处输入图像描述

Edit2.编辑2。 Here is a sample of how the .csv file looks like for testing purposes.以下是用于测试目的的 .csv 文件外观示例。 This is a list of lists.这是一个列表列表。

Example 例子

Edit3.编辑3。 Given that I was not working correctly with the list of lists, I made the changes that Ghilherme wrote about.鉴于我没有正确使用列表列表,因此我进行了 Ghilherme 所写的更改。 And now I get a blank screen.现在我得到一个空白屏幕。 在此处输入图像描述

Edit4.编辑4。 Ghilherme's code is absolutely correct: Ghilherme 的代码是绝对正确的:

class CSVExperimentRoute extends StatelessWidget {
  const CSVExperimentRoute({key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'CSV Experiment',
      home: ListFromCSV(),
    );
  }
}

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

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

class _ListFromCSVState extends State<ListFromCSV> {
  List<List<dynamic>> _data = [
    [""]
  ];
  int _listCount = 0;
  bool _isFirstLoad = true;

  // This function is triggered when my button is pressed
  void _loadCSV() async {
    List<dynamic> test = ["First", "Second", "Third", "Fourth"];
    List<List<dynamic>> _listData = [];
    _listData.add(test);

    setState(() {
      _data = _listData;
      _listCount < test.length - 1
          ? _isFirstLoad
              ? _isFirstLoad = false
              : _listCount++
          : _listCount;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("My CSV Attempt"),
        ),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              const SizedBox(height: 30),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Container(
                        decoration: const BoxDecoration(
                          gradient: LinearGradient(
                            colors: <Color>[
                              Color(0xFF0D47A1),
                              Color(0xFF1976D2),
                              Color(0xFF42A5F5),
                            ],
                          ),
                        ),
                      ),
                    ),
                    TextButton(
                      style: TextButton.styleFrom(
                        padding: const EdgeInsets.all(16.0),
                        primary: Colors.white,
                        textStyle: const TextStyle(fontSize: 20),
                      ),
                      onPressed: _loadCSV,
                      child: const Text('Click me to change Text'),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 30),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Container(
                        decoration: const BoxDecoration(
                          gradient: LinearGradient(
                            colors: <Color>[
                              Color(0xFF0D47A1),
                              Color(0xFF1976D2),
                              Color(0xFF42A5F5),
                            ],
                          ),
                        ),
                      ),
                    ),
                    TextButton(
                      style: TextButton.styleFrom(
                        padding: const EdgeInsets.all(16.0),
                        primary: Colors.white,
                        textStyle: const TextStyle(fontSize: 20),
                      ),
                      onPressed: () {},
                      child: const Text('Button 2'),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 30),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Container(
                        decoration: const BoxDecoration(
                          gradient: LinearGradient(
                            colors: <Color>[
                              Color(0xFF0D47A1),
                              Color(0xFF1976D2),
                              Color(0xFF42A5F5),
                            ],
                          ),
                        ),
                      ),
                    ),
                    TextButton(
                      style: TextButton.styleFrom(
                        padding: const EdgeInsets.all(16.0),
                        primary: Colors.white,
                        textStyle: const TextStyle(fontSize: 20),
                      ),
                      onPressed: () {},
                      child: const Text('Button 3'),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 30),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Container(
                        decoration: const BoxDecoration(
                          gradient: LinearGradient(
                            colors: <Color>[
                              // Color(0xFF0D47A1),
                              // Color(0xFF1976D2),
                              // Color(0xFF42A5F5),
                            ],
                          ),
                        ),
                      ),
                    ),
                    Text(
                      _data[0][_listCount],
                      textAlign: TextAlign.center,
                      overflow: TextOverflow.ellipsis,
                      style: const TextStyle(fontWeight: FontWeight.bold),
                    )
                  ],
                ),
              ),
            ],
          ),
        )
        // Display the contents from the CSV file
        // body: ListView.builder(
        //   itemCount: _data.length,
        //   itemBuilder: (_, index) {
        //     return Card(
        //       margin: const EdgeInsets.all(3),
        //       color: index == 0 ? Colors.amber : Colors.white,
        //       child: ListTile(
        //         leading: Text(_data[index][0].toString()),
        //         // title: Text(_data[index][1]),
        //         // trailing: Text(_data[index][2].toString()),
        //       ),
        //     );
        //   },
        // ),
        );
  }
}

The only problem is that I make a mistake when I try to change his test list to my list of lists from csv.唯一的问题是,当我尝试将他的测试列表更改为我的 csv 列表列表时,我犯了一个错误。 As a result, when the button is clicked, I see the first entry, but subsequent clicks do not show the text at all.:结果,当单击按钮时,我看到了第一个条目,但随后的单击根本不显示文本。:

// This function is triggered when my button is pressed
  void _loadCSV() async {
    // List<dynamic> test = ["First", "Second", "Third", "Fourth"];
    final _rawData = await rootBundle.loadString("files/Text.csv");
      // List<List<dynamic>> _listData = [];
    List<List<dynamic>> _listData =
    const CsvToListConverter().convert(_rawData);
    // _listData.add(test);

    setState(() {
      _data = _listData;
      _listCount < _data.length - 1 //_data instead of test
          ? _isFirstLoad
          ? _isFirstLoad = false
          : _listCount++
          : _listCount;
    });
  }

If I understand it right you can simply access the list on index 0 if this is your correct data.如果我理解正确,如果这是您的正确数据,您可以简单地访问索引 0 上的列表。

Text(
                      _data[0].toString() != null ? 
                      _data[0].toString() : '',
                      textAlign: TextAlign.center,
                      overflow: TextOverflow.ellipsis,
                      style: const TextStyle(fontWeight: FontWeight.bold),
                    )

You are accessing List of List in the wrong way.您以错误的方式访问列表列表。 The correct way would be something like this: _data[0][_listCount];正确的方法是这样的: _data[0][_listCount];

A better approach would be: (EDIT: I have put all the code now) EDIT2: I am putting all code to use with CSV load file.更好的方法是:(编辑:我现在已经放置了所有代码) EDIT2:我将所有代码与 CSV 加载文件一起使用。

class CSVExperimentRoute extends StatelessWidget {
  const CSVExperimentRoute({key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'CSV Experiment',
      home: ListFromCSV(),
    );
  }
}

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

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

class _ListFromCSVState extends State<ListFromCSV> {
  List<List<dynamic>> _listData = [
    [""]
  ];
  int _listCount = 0;
  bool _isFirstLoad = true;

  @override
  initState() {
    _loadCSV();
  }

  // This function is only triggered at init, so we only load csv once
  void _loadCSV() async {
    String _rawData = await rootBundle.loadString("dummy.csv");
    _listData = const CsvToListConverter().convert(_rawData);
  }

  // This function is triggered when my button is pressed
  void _nextCSV() {
    setState(() {
      _listData = _listData;
      _listCount < _listData[0].length - 1
          ? _isFirstLoad
              ? _isFirstLoad = false
              : _listCount++
          : _listCount;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("My CSV Attempt"),
        ),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              const SizedBox(height: 30),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Container(
                        decoration: const BoxDecoration(
                          gradient: LinearGradient(
                            colors: <Color>[
                              Color(0xFF0D47A1),
                              Color(0xFF1976D2),
                              Color(0xFF42A5F5),
                            ],
                          ),
                        ),
                      ),
                    ),
                    TextButton(
                      style: TextButton.styleFrom(
                        padding: const EdgeInsets.all(16.0),
                        primary: Colors.white,
                        textStyle: const TextStyle(fontSize: 20),
                      ),
                      onPressed: _nextCSV,
                      child: const Text('Click me to change Text'),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 30),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Container(
                        decoration: const BoxDecoration(
                          gradient: LinearGradient(
                            colors: <Color>[
                              Color(0xFF0D47A1),
                              Color(0xFF1976D2),
                              Color(0xFF42A5F5),
                            ],
                          ),
                        ),
                      ),
                    ),
                    TextButton(
                      style: TextButton.styleFrom(
                        padding: const EdgeInsets.all(16.0),
                        primary: Colors.white,
                        textStyle: const TextStyle(fontSize: 20),
                      ),
                      onPressed: () {},
                      child: const Text('Button 2'),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 30),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Container(
                        decoration: const BoxDecoration(
                          gradient: LinearGradient(
                            colors: <Color>[
                              Color(0xFF0D47A1),
                              Color(0xFF1976D2),
                              Color(0xFF42A5F5),
                            ],
                          ),
                        ),
                      ),
                    ),
                    TextButton(
                      style: TextButton.styleFrom(
                        padding: const EdgeInsets.all(16.0),
                        primary: Colors.white,
                        textStyle: const TextStyle(fontSize: 20),
                      ),
                      onPressed: () {},
                      child: const Text('Button 3'),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 30),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Container(
                        decoration: const BoxDecoration(
                          gradient: LinearGradient(
                            colors: <Color>[
                              // Color(0xFF0D47A1),
                              // Color(0xFF1976D2),
                              // Color(0xFF42A5F5),
                            ],
                          ),
                        ),
                      ),
                    ),
                    Text(
                      _listData[_listCount][0],
                      textAlign: TextAlign.center,
                      overflow: TextOverflow.ellipsis,
                      style: const TextStyle(fontWeight: FontWeight.bold),
                    )
                  ],
                ),
              ),
            ],
          ),
        ));
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM