Функция запускается до нажатия кнопки, Трепещет

#flutter #flutter-layout

Вопрос:

Я написал функцию, которая вызывается при нажатии кнопки. Но этот код, который должен выполняться при нажатии кнопки, выполняется в сборке класса…

Это мой класс:

 class _home_ViewState extends State<EinkaufenView> {

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: RoundedButton(title: "PDF erstellen", colour: Colors.blue, onPressed: () {_createPDF();}
        ),
      ),
    );
  }
}
 

Это моя функция:

 Future<void> _createPDF () async {

  List<MaterialItem> liste = [
    MaterialItem(name: "Din A4 Heft", art: "Hefte", beschreibung: "Deine Mom", anzahl: 3, bildName: "")
  ];

  PdfDocument document = PdfDocument();
  final page = document.pages.add();

  for(MaterialItem item in liste){
    page.graphics.drawString(item.name, PdfStandardFont(PdfFontFamily.helvetica, 30));
  }

  List<int> bytes = document.save();
  document.dispose();

  saveAndLaunchFile(bytes, "PDF.pdf");
  print("Debug");
}
 

И это макет кнопки, который я использовал в классе:

 class RoundedButton extends StatelessWidget {
  RoundedButton(
      {required this.title, required this.colour, required this.onPressed});

  final Color colour;
  final String title;
  final Function onPressed;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.symmetric(vertical: 16.0),
      child: Material(
        elevation: 5.0,
        color: colour,
        borderRadius: BorderRadius.circular(30.0),
        child: MaterialButton(
          onPressed: onPressed(),
          minWidth: 200.0,
          height: 42.0,
          child: Text(
            title,
            style: TextStyle(
              color: Colors.white,
            ),
          ),
        ),
      ),
    );
  }
}
 

Я также встроил инструкцию print в свою функцию, которая также выполняется при появлении представления…

Ответ №1:

Как вы сказали, функция вызывается в build методе из-за способа onPressed обработки в build методе RoundedButton , () в MaterialButton.onPressed котором необходимо удалить, поскольку он вызывает функцию, где вы хотите ссылку на функцию.

Обновите код, чтобы он читался, как в примере ниже

  MaterialButton(
          onPressed: onPressed,
...
)
 

Вы также можете следовать тому же шаблону _home_ViewState , поскольку вам не нужно передавать какие-либо аргументы _createPDF , вы можете обновить код для чтения.

 onPressed: _createPDF
 

если вам действительно нужно передать данные в функцию, то вы используете () => _createPDF(data)

Ответ №2:

Все хорошо, но здесь только одна проблема в том, что линия тонкая

 onPressed: onPressed(),
 

вы вызываете метод вместо размещения его экземпляра.

Поэтому измените эту строку на

 onPressed: onPressed,
 

и это будет ужасно

 
class RoundedButton extends StatelessWidget {
  RoundedButton(
      {required this.title, required this.colour, required this.onPressed});

  final Color colour;
  final String title;
  final Function onPressed;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.symmetric(vertical: 16.0),
      child: Material(
        elevation: 5.0,
        color: colour,
        borderRadius: BorderRadius.circular(30.0),
        child: MaterialButton(
          // you must place the function like this
          onPressed: onPressed,
          minWidth: 200.0,
          height: 42.0,
          child: Text(
            title,
            style: TextStyle(
              color: Colors.white,
            ),
          ),
        ),
      ),
    );
  }
}