Вам когда-нибудь приходилось вызывать функцию из другого виджета? Я сделал. Много раз. Но я долгое время не знал, как это сделать правильно.

Мой наиболее часто используемый случай — это в основном обновление изменений для предыдущего виджета. Что я имею в виду? Позвольте мне использовать простой пример. Список автомобилей в гараже. Когда вы открываете автомобиль, вы можете внести некоторые изменения, изменить цвет, номерной знак и т. д. Когда вы сделаете эти изменения и сохраните их, вы можете обновить предыдущий список, чтобы показать эти изменения. Это только один пример, вариантов использования, когда это необходимо, очень много.

Для простоты понимания и универсального использования наш пример кода будет очень упрощенной версией этого.

Начнем с простого списка в нашем основном виджете:

class _MyHomePageState extends State<MyHomePage> {
List<String> cars = [
    "hatch",
    "wagon",
    "SUV"
  ];
@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView.builder(
        itemCount: cars.length,
        itemBuilder: (BuildContext context,int index){
          return ListTile(
            leading: Icon(Icons.car_rental),
            title:Text(cars[index])
            );
        }
      ),
    );
  }
}

Теперь давайте определим наш второй экран, где мы будем редактировать детали, поскольку мы используем список простых строк, это будет только одно текстовое поле, кнопка «Назад» и кнопка подтверждения.

Этот экран получит 3 параметра: название автомобиля, индекс автомобиля в списке строк и функцию, которую мы хотим вызвать.

Код экрана будет выглядеть следующим образом:

import 'package:flutter/material.dart';
class DetailPage extends StatefulWidget {
  DetailPage({Key? key, required this.carText, required this.updateList}) : super(key: key);
String carText;
  Function updateList;
@override
  State<DetailPage> createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
TextEditingController tcont = TextEditingController();
@override
  void initState() {
    tcont.text = this.widget.carText;
    super.initState();
  }
@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(child: Column(
        children: [
          TextField(controller: tcont,),
          ElevatedButton(onPressed: () {
            this.widget.updateList(tcont.text);
            Navigator.pop(context);
          }, child: Text("Update"))
        ],
      )),
    );
  }
}

Теперь нам нужно просто правильно открыть новый виджет при нажатии в списке с определенной функцией:

return ListTile(
   leading: Icon(Icons.car_rental),
   title:Text(cars[index]),
   onTap: () {
     Navigator.push(context,
     MaterialPageRoute(builder: (context) => 
        DetailPage(carText: cars[index], 
           updateList: (String newText) {
             cars[index] = newText;
             setState(() {});
           },)),
         );
    },
);

И это все люди! Если вы хотите увидеть все это в деталях, видеоверсия здесь:

Большое спасибо за чтение, и увидимся в следующем!