Вам когда-нибудь приходилось вызывать функцию из другого виджета? Я сделал. Много раз. Но я долгое время не знал, как это сделать правильно.
Мой наиболее часто используемый случай — это в основном обновление изменений для предыдущего виджета. Что я имею в виду? Позвольте мне использовать простой пример. Список автомобилей в гараже. Когда вы открываете автомобиль, вы можете внести некоторые изменения, изменить цвет, номерной знак и т. д. Когда вы сделаете эти изменения и сохраните их, вы можете обновить предыдущий список, чтобы показать эти изменения. Это только один пример, вариантов использования, когда это необходимо, очень много.
Для простоты понимания и универсального использования наш пример кода будет очень упрощенной версией этого.
Начнем с простого списка в нашем основном виджете:
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(() {}); },)), ); }, );
И это все люди! Если вы хотите увидеть все это в деталях, видеоверсия здесь:
Большое спасибо за чтение, и увидимся в следующем!