使用GlobalKey从父窗口小部件中调用子窗口小部件中的方法

时间:2020-01-05 20:57:17

标签: flutter flutter-widget

我正在使用全局键从父级的子级小部件调用方法。我在这里的方法2中找到了这种方法。 https://medium.com/flutter-community/flutter-communication-between-widgets-f5590230df1e

以下不是确切的代码,而是正在使用的代码段。 chid中的搜索方法即使从父级调用也不会被调用。

class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
  TabController _tabController;
  bool showFab = true;
  SearchState searchState = SearchState.SHOW_MENU;

  TextEditingController _searchQuery;
  bool _isSearching = false;
  String searchQuery = "Search query";

  GlobalKey<CustomersScreenState> _customerScreenState1 = GlobalKey();


  void updateSearchQuery(String newQuery) {
    setState(() {
      searchQuery = newQuery;
    });
    print("search query " + newQuery); //This is getting printed
    _customerScreenState1.currentState.search(newQuery); //Nothing happening here. not getting called
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          elevation: 0.7,
          leading: _isSearching ? const BackButton() : null,
          title: _isSearching ? _buildSearchField() : _buildTitle(context),
          actions: _buildActions(),
          bottom: TabBar(
            controller: _tabController,
            indicatorColor: Colors.white,
            tabs: <Widget>[
              Tab(icon: Icon(Icons.camera_alt)),
              Tab(text: "CHATS"),
              Tab(
                text: "STATUS",
              ),
              Tab(
                text: "CALLS",
              ),
            ],
          )),
      body: TabBarView(
        controller: _tabController,
        children: <Widget>[
          CustomersScreen(key: _customerScreenState1)
        ],
      ),

}


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

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

class CustomersScreenState extends State<CustomersScreen> {
  Firestore fireStore;
  List<Customer> customers = [];

  bool isLoading = false; // track if products fetching
  bool hasMore = true; // flag for more products available or not
  int documentLimit = 10; // documents to be fetched per request
  DocumentSnapshot
      lastDocument; // flag for last document from where next 10 records to be fetched
  ScrollController _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    fireStore = Firestore.instance;

    _scrollController.addListener(() {
      double maxScroll = _scrollController.position.maxScrollExtent;
      double currentScroll = _scrollController.position.pixels;
      double delta = MediaQuery.of(context).size.height * 0.20;
      if (maxScroll - currentScroll <= delta) {
        getCustomers();
      }
    });
    getCustomers();
  }

  void search(Sting query){
    //This method is not getting called.
  }
}

编辑1:

void updateSearchQuery(String newQuery) {
    setState(() {
      searchQuery = newQuery;
      print("search query " + newQuery);
      _customerScreenState1.currentState.search(newQuery); //moved inside setState still not working
    });
  }

2 个答案:

答案 0 :(得分:0)

我已将答案更改为您要执行的工作示例。我看到的与您的代码之间的唯一区别是,您的chid小部件没有构建功能,我想知道这是否会干扰您的状态。

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  GlobalKey<_ChildWidgetState> _childKey = GlobalKey<_ChildWidgetState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ChildWidget(key: _childKey),
            RaisedButton(
              onPressed: () => callChildFunction(),
              child: Text('Print'),
            )
          ],
        ),
      ),
    );
  }

  void callChildFunction(){
    _childKey.currentState.changeChildText();
  }
}

class ChildWidget extends StatefulWidget {
  ChildWidget({Key key}): super(key: key);

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

class _ChildWidgetState extends State<ChildWidget> {
  String text = 'Child widget';

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(text),
    );
  }

  void changeChildText(){
    setState(() {
      text = 'called function';
    });
  }
}

答案 1 :(得分:0)

很难只说一句。我认为search方法是使用您的方法触发的,但是您可能没有在UI中看到任何差异,因为您没有在search方法运行后触发build方法。 只需尝试在_customerScreenState1.currentState.search(newQuery);类的setState回调内调用_HomeState

void updateSearchQuery(String newQuery) {
setState(() {
  searchQuery = newQuery;
   _customerScreenState1.currentState.search(newQuery);
  });
  print("search query " + newQuery); //This is getting printed
}