skip to Main Content

My goal is to achieve a textbox, which has a dropdown arrow, with a history so the user can select a previous input.. However.. I’ve came up to a point, where I wanted to shrink that textbox, because it was taking unnecessary space. The problem is that, when a history value occurs, it takes all the space of the textbox and items inside the dropdown appear too big..
Dropdown with history

This is how it appears before having a value inside the history data:
No history data dropdown

What I want to achieve is, have the textfield width of an IP address, the one on the second photo works and the dropdown to have smaller elements of previous inputs, so the user can select them..

Here is the HistoryTextField code:

import 'package:flutter/material.dart';

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

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

class _HistoryTextFieldState extends State<HistoryTextField> {
  final TextEditingController _controller = TextEditingController();
  final List<String> _history = [];
  String? _selectedHistory;

  @override
  void initState() {
    super.initState();
    // Load history from storage (if applicable)
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _addToHistory(String text) {
    if (text.isNotEmpty && !_history.contains(text)) {
      _history.insert(0, text);
      // Save history to storage (if applicable)
    }
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          child: TextField(
            controller: _controller,
            onChanged: (value) {
              setState(() {
                _selectedHistory = null;
              });
            },
            onSubmitted: (value) {
              _addToHistory(value);
              _controller.clear();
            },
          ),
        ),
        DropdownButton<String>(
          value: _selectedHistory,
          onChanged: (String? newValue) {
            setState(() {
              _selectedHistory = newValue;
              _controller.text = newValue!;
            });
          },
          items: _history.map<DropdownMenuItem<String>>((String value) {
            return DropdownMenuItem<String>(
              value: value,
              child: Text(value),
            );
          }).toList(),
        ),
      ],
    );
  }
}

And how I’ve been using the widget itself:

Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    Text("IP Address: "),
                    SizedBox(width: 200, child: HistoryTextField())
                  ],
                )

2

Answers


  1. If you want the DropdownButton to have a fixed size, you can use a SizedBox to define its width and avoid placement issues.

    SizeBox(
    width: 150,
    child: DropdownButton<String>(
    isExpanded: true
    value: _selectedHistory,
    onChanged: (String? newValue) {
                setState(() {
    --
    --
       });
          }
    
    Login or Signup to reply.
  2. Inside the SizedBox, you can use TextAlign.left to align the text properly within the dropdown.

    DropdownButton<String>(
      value: selectItem,
      items: items.map((String value) {
         return DropdownMenuItem<String>(
          value: value,
           width: 200, // MATCH THIS WIDTH TO THE TEXTFIELD
             child: Text (
               value,
                      textAlign: TextAlign.left,
    ),
    ),
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search