распространять состояние виджета с состоянием на дочерний - PullRequest
0 голосов
/ 29 января 2019

Я создаю панель поиска, и мне нужно передать состояние виджета с состоянием его дочернему элементу.
При поиске некоторой строки отредактированный текст должен быть передан дочернему виджету, который реализует ListView.

Это родительский виджет:

import ...

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final TextEditingController _filter = new TextEditingController();

  Widget _appBarTitle = new Text('My App');
  bool _searching = false;
  String _searchText = "";

  @override
  void initState() {
    super.initState();

    _filter.addListener(() {
      if (_filter.text.isEmpty) {
        setState(() {
          _searchText = "";
        });
      } else {
        setState(() {
          _searchText = _filter.text;
        });
      }
    });
  }

  void _onSearchBackPressed() {
    setState(() {
      _searching = !_searching;
      _appBarTitle = _buildAppBar();
    });
  }

  Widget _buildBackIcon() {
    if (_searching) {
      return IconButton(
        icon: Icon(Icons.arrow_back),
        onPressed: _onSearchBackPressed,
      );
    } else {
      return null;
    }
  }

  Widget _buildAppBar() {
    if (_searching) {
      return TextField(
        controller: _filter
      );
    } else {
      return Text('My App');
    }
  }

  List<Widget> _buildActions() {
    if (_searching) {
      return null;
    } else {
      return <Widget>[
        IconButton(
          icon: Icon(Icons.search),
          tooltip: 'Search',
          onPressed: _onSearchBackPressed,
        ),
      ];
    }
  }

  @override
  Widget build(BuildContext context) {
    return StoreConnector<AppState, AppState>(
      converter: (store) => store.state,
      builder: (context, appState) {
        return DefaultTabController(
          length: 3,
          child: Scaffold(
            appBar: AppBar(
                title: _appBarTitle,
                leading: _buildBackIcon(),
                actions: _buildActions()
            ),
            body: new DefaultTabController(
              length: 1,
              child: new Column(
                children: <Widget>[
                    ChildWidget(appState: appState, filter: _searchText), // <-- HERE I NEED TO PROPAGATE THE PARENT STATE
                ],
              ),
            ),
          ),
        );
      },
    );
  }
}

Как вы можете видеть прямо сейчас, я просто передаю значение _searchText в ChildWidget дочерний конструктор.

Это хороший способ или я делаю не так?
Когда _searchText изменяется ChildWidget правильно перестроен?

...