dart 如何设置状态并重新呈现ModalRoute

gcuhipw9  于 2023-06-27  发布在  其他
关注(0)|答案(2)|浏览(137)

我有搜索模式弹出,用户可以搜索,并根据他们的搜索结果。但是,由于该类扩展了ModalRoute而不是StatefulWidget,因此调用setState不会重新呈现构建,搜索结果也不会显示在屏幕上。有没有一种方法可以更新状态或重新呈现屏幕,而不必将类转换为StatefulWidfet?

class JobSerachModal extends ModalRoute {
  List<dynamic>? searchResults;

  @override
  Duration get transitionDuration => const Duration(milliseconds: 250);

  @override
  bool get opaque => false;

  @override
  bool get barrierDismissible => false;

  @override
  Color get barrierColor => Colors.black;

  @override
  String? get barrierLabel => null;

  @override
  bool get maintainState => true;

  getSearch(String query) async {
    var result = await SearchService().getAllPaged(query: query);
    setState(() {
      searchResults = result;
    });
  }

  _onSearchChanged(String query) {
    getSearch(query);
  }

  @override
  Widget buildPage(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
  ) {
    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Expanded(
                    child: TextField(
                      onChanged: _onSearchChanged,
                      autofocus: true,
                    ),
                  ),
                  TextButton(
                      onPressed: () => Navigator.of(context).pop(),
                      child: const Text('Cancel'))
                ],
              ),
              const SizedBox(
                height: 20,
              ),
              ...searchResults.map(
                (search) {
                  return ListTile(
                    title: Text(search.title),
                  );
                },
              )
            ],
          ),
        ),
      ),
    );
  }
}
l5tcr1uw

l5tcr1uw1#

Flutters setState()方法仅在StatefulWidget中可用,用于在状态更改时重建小部件。你不能从ModalRoute调用setState()方法,因为它不存在。
您可以使用ValueNotifierValueListenableBuilder来实现您的目标。

验证码:

// Define a new class JobSearchModal that extends ModalRoute
class JobSearchModal extends ModalRoute {
  // Declare a ValueNotifier which will notify all the listeners whenever there's a change in search results
  final ValueNotifier<List<dynamic>> searchResults = ValueNotifier<List<dynamic>>([]);

  // Set duration of transition
  @override
  Duration get transitionDuration => const Duration(milliseconds: 250);

  @override
  bool get opaque => false;

  @override
  bool get barrierDismissible => false;

  @override
  Color get barrierColor => Colors.black;

  @override
  String? get barrierLabel => null;

  @override
  bool get maintainState => true;

  // Define this asynchronous function to get search results
  getSearch(String query) async {
    var result = await SearchService().getAllPaged(query: query);
    searchResults.value = result;
  }

  // Define a function that gets executed when a search query changes
  _onSearchChanged(String query) {
    getSearch(query);
  }

  @override
  Widget buildPage(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
  ) {
    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Expanded(
                    child: TextField(
                      onChanged: _onSearchChanged,
                      autofocus: true,
                    ),
                  ),
                  TextButton(
                      onPressed: () => Navigator.of(context).pop(),
                      child: const Text('Cancel'))
                ],
              ),
              const SizedBox(
                height: 20,
              ),
              ValueListenableBuilder(
                valueListenable: searchResults,
                builder: (context, value, child) {
                  return Column(
                    children: value.map(
                      (search) {
                        return ListTile(
                          title: Text(search.title),
                        );
                      },
                    ).toList(),
                  );
                },
              )
            ],
          ),
        ),
      ),
    );
  }
}
ogq8wdun

ogq8wdun2#

StatefulBuilder(
    builder: (BuildContext context, setState) {
      return ;
    },
  ),

使用StatefulBuilder
示例:

await showDialog<void>(
  context: context,
  builder: (BuildContext context) {
    int? selectedRadio = 0;
    return AlertDialog(
      content: StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return Column(
            mainAxisSize: MainAxisSize.min,
            children: List<Widget>.generate(4, (int index) {
              return Radio<int>(
                value: index,
                groupValue: selectedRadio,
                onChanged: (int? value) {
                  setState(() => selectedRadio = value);
                },
              );
            }),
          );
        },
      ),
    );
  },
);

相关问题