admin管理员组

文章数量:1200423

I am trying to create e dropdown textfield which can accept a custom input and add it to its dropdown history. For that dropdown_textfield package comes in use. I manage to create the actual textfield and have values in its dropdown, however I'm unable to add custom values to it. I have only the search option, which search through existing dropdown elements. Here is how it looks now:

When I search here, Im unable to add a new element..

Here is my code:

import 'package:dropdown_textfield/dropdown_textfield.dart';
import 'package:flutter/material.dart';
import 'package:local_network_monitoring/utils/constants.dart';
import 'package:shared_preferences/shared_preferences.dart';

class HistoryTextField extends StatefulWidget {
  final String fieldType;
  final String hintText;
  final SingleValueDropDownController controller;

  const HistoryTextField(
      {super.key,
      required this.fieldType,
      required this.hintText,
      required this.controller});

  @override
  State<HistoryTextField> createState() => _HistoryTextFieldState();
}

class _HistoryTextFieldState extends State<HistoryTextField> {
  List<DropDownValueModel> _dropdownList = [];

  @override
  void initState() {
    super.initState();
    // Load history from storage
    _loadHistory();

    // Listener for shared preferences changes
    SharedPreferences.getInstance().then((prefs) {
      prefs.reload().then((_) => _loadHistory());
    });
  }

  @override
  void dispose() {
    widget.controller.dispose();
    super.dispose();
  }

  Future<void> _saveValues() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    List<String> values = _dropdownList.map((item) => item.name).toList();
    prefs.setStringList(widget.fieldType, values);
  }

  void _addNewValue(dynamic newValue) {
    // Handle value types
    if (newValue is DropDownValueModel) {
      newValue = newValue.value;
    }

    // Check if the value already exists
    if (!_dropdownList
        .any((item) => item.name.toLowerCase() == newValue.toLowerCase())) {
      setState(
        () {
          // Add the new value to the list
          _dropdownList
              .add(DropDownValueModel(name: newValue, value: newValue));
          widget.controller.dropDownValue =
              DropDownValueModel(name: newValue, value: newValue);
        },
      );
      _saveValues();
    }
  }

  void _loadHistory() async {
    // Load history from storage
    final preferences = await SharedPreferences.getInstance();

    var historyValues = preferences.getStringList(widget.fieldType) ?? [];

    if (historyValues.isEmpty) {
      if (widget.fieldType == "communityField" && _dropdownList.isEmpty) {
        _dropdownList.add(
            const DropDownValueModel(name: "public", value: defaultCommunity));
      } else if (widget.fieldType == "oidField" && _dropdownList.isEmpty) {
        _dropdownList.add(
            const DropDownValueModel(name: "defaultOID", value: defaultOID));
      } else if (widget.fieldType == "ipField" && _dropdownList.isEmpty) {
        _dropdownList
            .add(const DropDownValueModel(name: "defaultIp", value: defaultIp));
      }
    } else {
      for (var value in historyValues) {
        if (!_dropdownList.any(
            (element) => element.name.toLowerCase() == value.toLowerCase())) {
          setState(
            () {
              _dropdownList.add(DropDownValueModel(name: value, value: value));
              widget.controller.dropDownValue =
                  DropDownValueModel(name: value, value: value);
            },
          );
        }
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: Theme.of(context).scaffoldBackgroundColor,
        border: Border.all(color: Theme.of(context).dividerColor),
        borderRadius: BorderRadius.circular(5),
      ),
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
      child: Expanded(
        child: DropDownTextField(
          textFieldDecoration: InputDecoration(
              hintText: widget.hintText,
              border: InputBorder.none,
              hintStyle: const TextStyle(
                overflow: TextOverflow.ellipsis,
                fontSize: 9,
                fontWeight: FontWeight.bold,
              )),
          dropDownList: _dropdownList,
          controller: widget.controller,
          onChanged: (value) {
            if (value != null && value is String) {
              _addNewValue(value);
            }
          },
          enableSearch: true,
          dropDownItemCount: 5,
        ),
      ),
    );
  }
}

Here is how I am trying to use my widget

class CommunitySelection extends StatelessWidget {
  const CommunitySelection({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<CommunityCubit, CommunityState>(
      builder: (context, state) {
        return Row(
          children: [
            const Text("Community: ",
                style: TextStyle(fontWeight: FontWeight.bold)),

            const SizedBox(height: 20),

            // Community text field
            SizedBox(
              width: 200,
              child: HistoryTextField(
                fieldType: "communityField",
                hintText: "Community",
                controller: statemunityController,
                // borderColor: Colors.red,
              ),
            ),
          ],
        );
      },
    );
  }
}

本文标签: dartDropdown textfield which can accept custom input using flutter dropdowntextfield packageStack Overflow