Vintage appMaker의 Tech Blog

[Flutter] Autocomplete 커스텀 본문

Source code or Tip/Flutter & Dart

[Flutter] Autocomplete 커스텀

VintageappMaker 2022. 7. 22. 23:09
 

Autocomplete class - material library - Dart API

A widget for helping the user make a selection by entering some text and choosing from among a list of options. The user's text input is received in a field built with the fieldViewBuilder parameter. The options to be displayed are determined using options

api.flutter.dev


 

 

[전체소스]

import 'package:flutter/material.dart';

void main() => runApp(const AutocompleteExampleApp());

class AutocompleteExampleApp extends StatelessWidget {
  const AutocompleteExampleApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Autocomplete 예제'),
        ),
        body: const Center(
          child: AutocompleteBasicUserExample(),
        ),
      ),
    );
  }
}

class Search {
  const Search({
    required this.keyword,
  });

  final String keyword;
}

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

  @override
  State<AutocompleteBasicUserExample> createState() =>
      _AutocompleteBasicUserExampleState();
}

class _AutocompleteBasicUserExampleState
    extends State<AutocompleteBasicUserExample> {
  String _displayText = "";
  String _displayStringForOption(Search word) => word.keyword;
  List<Search> _searchData = <Search>[
    Search(keyword: 'animal'),
    Search(keyword: 'bird'),
    Search(keyword: 'cheese'),
  ];

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: [
          Text(
            _displayText,
            style: TextStyle(fontSize: 30),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Flexible(
                  child: TextButton(
                      child: Text("+search"),
                      onPressed: () {
                        _searchData.add(Search(keyword: "${_displayText}"));
                      })),
              Expanded(
                child: Container(
                  padding: EdgeInsets.all(10),
                  child: getAutoTextWidget(),
                ),
              )
            ],
          ),
        ],
      ),
    );
  }

  Autocomplete<Search> getAutoTextWidget() {
    return Autocomplete<Search>(
        displayStringForOption: _displayStringForOption,
        optionsBuilder: (TextEditingValue textEditingValue) {
          setState(() {
            _displayText = textEditingValue.text;
          });

          // 아래코드를 구현시, 입력이 없을경우, 보여주지 않는다.
          //if (textEditingValue.text == '') {
          //  return const Iterable<Search>.empty();
          //}
          return _searchData.where((Search option) {
            return option.keyword.contains(textEditingValue.text.toLowerCase());
          });
        },
        onSelected: (Search selection) {
          _displayText = '${_displayStringForOption(selection)} 선택';
        },
        optionsViewBuilder: (BuildContext context,
            AutocompleteOnSelected<Search> onSelected,
            Iterable<Search> options) {
          return Align(
              alignment: Alignment.topLeft,
              child: Material(
                  child: Container(
                      child: SingleChildScrollView(
                child: Expanded(
                  child: ListView.builder(
                    primary: false,
                    shrinkWrap: true,
                    padding: const EdgeInsets.all(5.0),
                    itemCount: options.length,
                    itemBuilder: (BuildContext context, int index) {
                      final Search option = options.elementAt(index);

                      return GestureDetector(
                        onTap: () {
                          onSelected(option);
                        },
                        child: ListTile(
                          leading: CircleAvatar(child: Icon(Icons.search)),
                          title: Text(option.keyword,
                              style: const TextStyle(
                                  color: Color.fromARGB(255, 0, 0, 0))),
                        ),
                      );
                    },
                  ),
                ),
              ))));
        });
  }
}

 

Comments