skip to Main Content

I am trying to make a screen with filter, and a search buttons, but whenever i select a text field the screen start searching, even if i haven’t written anything yet, i am using a column with 2 textFields, none of them uses onChanged or onTap functions, after the textfields, there is a button, where i wanted to do the search, and after the button there’s a future builder, where the info is suposed to show.

Padding(
  padding: const EdgeInsets.all(8.0),
  child: TextFormField(
    controller: ctrl1,
    keyboardType: TextInputType.number,
    inputFormatters: [FilteringTextInputFormatter.digitsOnly],
    decoration: const InputDecoration(
      border: OutlineInputBorder(),
      fillColor: Colors.white,
      labelText: 'filter1',
      floatingLabelBehavior: FloatingLabelBehavior.always,
    ),
  ),
),
Padding(
  padding: const EdgeInsets.all(8.0),
  child: TextFormField(
    controller: ctrl2,
    decoration: const InputDecoration(
      border: OutlineInputBorder(),
      fillColor: Colors.white,
      labelText: 'filter2',
      floatingLabelBehavior: FloatingLabelBehavior.always,
    ),
  ),
)

Whenever i tap or change any of the text fields, apparently the state updates, forcing the search. How can i stop the textfields from updating the state of the Screen when tapped or changed?

3

Answers


  1. Chosen as BEST ANSWER
    class _WidgSttflState extends State<WidgSttfl> {
      TextEditingController ctrl1 = TextEditingController(),
          ctrl2 = TextEditingController();
      PageController _pgView = PageController(initialPage: 0);
      ExpansionTileController exp = ExpansionTileController();
    
      Future<dynamic> buildData(filter1, filter2) async {
        ...
      }
    
      Future<List<dynamic>?> search(filter1, filter2) async {
        return await buildData(filter1, filter2);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: 'title'
          ),
          body: PageView(
            controller: _pgView,
            physics: const NeverScrollableScrollPhysics(),
            children: [
              ...,
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Theme(
                    data: Theme.of(context).copyWith(
                      dividerColor: Colors.transparent,
                    ),
                    child: ExpansionTile(
                      title: const Text('Filters'),
                      controller: exp,
                      initiallyExpanded: true,
                      leading: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          IconButton(
                            onPressed: () => _pgView.previousPage(
                              duration: const Duration(seconds: 1),
                              curve: Curves.easeInOutCubicEmphasized,
                            ),
                            icon: const Icon(
                              Icons.arrow_back,
                              color: Colors.orange,
                            ),
                          ),
                          const VerticalDivider(
                            thickness: 1,
                            indent: 5,
                            endIndent: 5,
                            color: Colors.orange,
                          ),
                        ],
                      ),
                      trailing: const Icon(Icons.filter_alt),
                      children: [
                        Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: TextFormField(
                            controller: ctrl1,
                            keyboardType: TextInputType.number,
                            inputFormatters: [
                              FilteringTextInputFormatter.digitsOnly
                            ],
                            decoration: const InputDecoration(
                              border: OutlineInputBorder(),
                              fillColor: Colors.white,
                              labelText: 'filter1',
                              floatingLabelBehavior: FloatingLabelBehavior.always,
                            ),
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: TextFormField(
                            controller: ctrl2,
                            decoration: const InputDecoration(
                              border: OutlineInputBorder(),
                              fillColor: Colors.white,
                              labelText: 'filter2',
                              floatingLabelBehavior: FloatingLabelBehavior.always,
                            ),
                          ),
                        ),
                        ...,
                        SizedBox(
                          width: double.infinity,
                          child: Padding(
                            padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
                            child: ElevatedButton(
                              onPressed: () {
                                setState(() {
                                  search(filter1.text, filter2.text);
                                  exp.collapse();
                                });
                              },
                              child: const Text(
                                'Search',
                                style: TextStyle(
                                  color: Colors.white,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                  const Divider(thickness: 2),
                  Expanded(
                    child: FutureBuilder(
                      future: search(ctrl1.text, ctrl2.text),
                      builder: (context, snapshot) {
                        if (snapshot.connectionState == ConnectionState.waiting) {
                          return const Center(child: CircularProgressIndicator());
                        } else if (snapshot.hasData) {
                          if (snapshot.data.isNotEmpty) {
                            return ListView.separated(
                              itemCount: snapshot.data.length,
                              separatorBuilder: (context, index) =>
                                  const Divider(),
                              itemBuilder: (context, index) {
                                return ListTile(
                                  title: Text(''),
                                  subtitle: Text(''),
                                );
                              },
                            );
                          }
                        }
                      },
                    ),
                  ),
                ],
              ),
            ],
          ),
        );
      }
    }
    

  2. Show Your screen code, you need to set textformfield Above the searching function

    Login or Signup to reply.
  3. Don’t use addListener on TextEditingController. Use onChanged option for search.

     TextFormField(
      onChanged: (value) {
        // call your function here.
      },
    ),
    

    Bonus : Don’t forget to dispose your controllers to avoid memory leak.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search