如何在点击 TextField 时仅显示 ListView

问题描述 投票:0回答:1

我默认在屏幕上显示建议列表,我想让建议列表仅在单击文本字段时显示。

我尝试将 listView 放在 setState 旁边,但没有成功。我也尝试制作一个控制器监听器,但也没有成功。我应该用按钮包装 listView 吗?

请帮忙!

这是我的代码

class MySearchBar extends StatefulWidget {
  const MySearchBar({super.key});

  @override
  State<MySearchBar> createState() => _MySearchBarState();
}

class _MySearchBarState extends State<MySearchBar> {
  final myController = TextEditingController();
  static List<RestaurantProfiles> searchList = mySearchList;

  List<RestaurantProfiles> display_list = List.from(searchList);

  // this is the function that will update the suggestion list while searching
  void searchUpdate(String value) {
    setState(() {
      display_list = searchList
          .where((element) => element.restaurantName
              .toLowerCase()
              .contains(value.toLowerCase()))
          .toList();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(40),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const SizedBox(
            height: 20,
          ),
          TextField(
            onChanged: (value) => searchUpdate(value),
            style: const TextStyle(
              color: Colors.black,
            ),
            decoration: InputDecoration(
              filled: true,
              fillColor: Colors.white,
              isDense: true,
              contentPadding: const EdgeInsets.all(10),
              border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(30),
                borderSide: BorderSide.none,
              ),
              hintText: "Add Restaurants",
              hintStyle: const TextStyle(
                color: Colors.black26,
              ),
              prefixIcon: const Icon(Icons.search),
              prefixIconColor: Colors.black,
            ),
          ),
          const SizedBox(
            height: 5,
          ),
          SizedBox(
            height: 250,
            child: Expanded(
              child: display_list.isEmpty
                  ? const Center(
                      child: Text(
                        "oops... No Results Found!",
                        style: TextStyle(
                          fontSize: 20,
                        ),
                      ),
                    )
                  : Container(
                      decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(10),
                          color: Colors.white70),
                      child: ListView.builder(
                        itemCount: display_list.length,
                        itemBuilder: (context, index) => ListTile(
                          contentPadding: const EdgeInsets.all(8),
                          title: Text(display_list[index].restaurantName),
                          leading: Image(
                            image: AssetImage(display_list[index].img),
                            fit: BoxFit.cover,
                            height: 50,
                            width: 50,
                          ),
                          trailing: const Icon(Icons.add),
                        ),
                      ),
                    ),
            ),
          ),
        ],
      ),
    );
  }
} 
flutter listview textfield
1个回答
0
投票

我根据您的代码创建了一个示例。我希望这能解决这个问题。

class MySearchBar extends StatefulWidget {
  const MySearchBar({super.key});

  @override
  State<MySearchBar> createState() => _MySearchBarState();
}

class _MySearchBarState extends State<MySearchBar> {
  final myController = TextEditingController();
  // static List<RestaurantProfiles> searchList = mySearchList;
  final mySearchList = ['abc', 'xyz', 'cvb'];
  List display_list = [];

  // this is the function that will update the suggestion list while searching
  void searchUpdate(String value) {
    setState(() {
      display_list = mySearchList
          .where(
              (element) => element.toLowerCase().contains(value.toLowerCase()))
          .toList();
    });
  }

  FocusNode node = FocusNode();
  @override
  void initState() {
    super.initState();

    node.addListener(() {
      showList = node.hasFocus;
      setState(() {});
    });
  }

  TextEditingController textEditingController = TextEditingController();
  bool showList = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(40),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const SizedBox(
              height: 20,
            ),
            TextField(
              controller: textEditingController,
              focusNode: node,
              onChanged: (value) => searchUpdate(value),
              style: const TextStyle(
                color: Colors.black,
              ),
              decoration: InputDecoration(
                filled: true,
                fillColor: Colors.white,
                isDense: true,
                contentPadding: const EdgeInsets.all(10),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(30),
                  borderSide: BorderSide.none,
                ),
                hintText: "Add Restaurants",
                hintStyle: const TextStyle(
                  color: Colors.black26,
                ),
                prefixIcon: const Icon(Icons.search),
                prefixIconColor: Colors.black,
              ),
            ),
            const SizedBox(
              height: 5,
            ),
            SizedBox(
              height: 250,
              child: Expanded(
                child: showList || textEditingController.text.isNotEmpty
                    ? display_list.isEmpty
                        ? const Center(
                            child: Text(
                              "oops... No Results Found!",
                              style: TextStyle(
                                fontSize: 20,
                              ),
                            ),
                          )
                        : Container(
                            decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(10),
                                color: Colors.white70),
                            child: ListView.builder(
                              itemCount: display_list.length,
                              itemBuilder: (context, index) => ListTile(
                                contentPadding: const EdgeInsets.all(8),
                                title: Text(display_list[index]),
                                // leading: Image(
                                //   image: AssetImage(display_list[index].img),
                                //   fit: BoxFit.cover,
                                //   height: 50,
                                //   width: 50,
                                // ),
                                trailing: const Icon(Icons.add),
                              ),
                            ),
                          )
                    : Text('Search for restaurant'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.