如何在文本字段上方显示提示文本

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

我正在尝试在文本字段顶部显示提示文本。我尝试过使用 Labeltext 但我无法让它做到这一点。这是我的代码:

@override
Widget build(BuildContext context) {
return TextFormField(
  keyboardType: textInputType,
  controller: controller,
  obscureText: obscureText,
  autocorrect: false,
  autofocus: autofocus,
  textAlign: TextAlign.center,
  cursorColor: BPColor.black,
  style: TextStyle(
    color: textColor,
    fontSize: 16,
  ),
  decoration: InputDecoration(
    hintText: hintText,
    fillColor: color,
    filled: true,
    hintStyle: TextStyle(color: textColor),
    contentPadding: EdgeInsets.all(10),
    enabledBorder: OutlineInputBorder(
      borderSide: BorderSide(color: Colors.white),
      borderRadius: BorderRadius.circular(0),
    ),
    focusedBorder: OutlineInputBorder(
      borderSide: BorderSide(color: Colors.white),
      borderRadius: BorderRadius.circular(0),
    ),
    errorBorder: OutlineInputBorder(
      borderSide: BorderSide(color: Colors.white),
      borderRadius: BorderRadius.circular(0),
    ),
    disabledBorder: OutlineInputBorder(
      borderSide: BorderSide(color: Colors.white),
      borderRadius: BorderRadius.circular(0),
    ),
  ),
);
}

这是我的 TextField 代码的输出:

我需要在文本字段框之外显示电子邮件提示。有办法做到这一点吗?或者我是否必须在文本字段之外创建一个标签?

当我添加 LabelText 时:

显示如下:

显示不正确。

flutter dart flutter-layout
4个回答
4
投票

如果要将标签放在文本字段之外,您可以使用

Column
并将
Text
TextField
作为小部件放在那里。使用以下代码作为参考。

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('blahf blahh'),
        TextFormField(
          keyboardType: textInputType,
          controller: controller,
          obscureText: obscureText,
          autocorrect: false,
          autofocus: autofocus,
          textAlign: TextAlign.center,
          cursorColor: BPColor.black,
          style: TextStyle(
            color: textColor,
            fontSize: 16,
          ),
          decoration: InputDecoration(
            hintText: hintText,
            fillColor: color,
            filled: true,
            hintStyle: TextStyle(color: textColor),
            contentPadding: EdgeInsets.all(10),
            enabledBorder: OutlineInputBorder(
              borderSide: BorderSide(color: Colors.white),
              borderRadius: BorderRadius.circular(0),
            ),
            focusedBorder: OutlineInputBorder(
              borderSide: BorderSide(color: Colors.white),
              borderRadius: BorderRadius.circular(0),
            ),
            errorBorder: OutlineInputBorder(
              borderSide: BorderSide(color: Colors.white),
              borderRadius: BorderRadius.circular(0),
            ),
            disabledBorder: OutlineInputBorder(
              borderSide: BorderSide(color: Colors.white),
              borderRadius: BorderRadius.circular(0),
            ),
          ),
        )
      ],
    );
  }

2
投票

这有什么问题:

TextFormField(
  decoration: InputDecoration(labelText: 'Your hint'),
)

1
投票

此处缺少 labelText,这就是为什么您在上部找不到此文本。

labelText: "Email address"

在输入装饰下添加这个labelText


0
投票

我已经实现了自己的 TextField,标题位于表单顶部,基于 sm_sayedi Answer 以及 flutter 提供的来源 input_decorator.dart

import 'package:flutter/material.dart';

class LabelTextWidget extends StatefulWidget {
  final TextEditingController? controller;
  final String? initialValue;
  final FocusNode? focusNode;
  final InputDecoration decoration;
  final TextInputType? keyboardType;
  final TextStyle? style;
  final bool autofocus;
  final bool readOnly;
  final int? maxLines;
  final int? minLines;
  final void Function(String)? onChanged;
  final TapRegionCallback? onTapOutside;
  final bool? enabled;

  const LabelTextWidget({
    super.key,
    this.controller,
    this.initialValue,
    this.focusNode,
    this.decoration = const InputDecoration(),
    this.keyboardType,
    this.style,
    this.autofocus = false,
    this.readOnly = false,
    this.maxLines = 1,
    this.minLines,
    this.onChanged,
    this.onTapOutside,
    this.enabled,
  });

  @override
  State<LabelTextWidget> createState() => _LabelTextWidgetState();
}

class _LabelTextWidgetState extends State<LabelTextWidget> with SingleTickerProviderStateMixin {
  static const Duration _kTransitionDuration = Duration(milliseconds: 167);
  static const Curve _kTransitionCurve = Curves.fastOutSlowIn;

  late final FocusNode _focusNode;
  late final TextEditingController _controller;

  @override
  void initState() {
    super.initState();
    _controller = widget.controller ?? TextEditingController();
    _focusNode = widget.focusNode ?? FocusNode();

    _focusNode.addListener(() {
      setState(() {});
    });
  }

  bool get _isEmpty => _controller.value.text.isNotEmpty;

  bool get _labelShouldWithdraw => _isEmpty || (_focusNode.hasFocus && decoration.enabled);

  bool get _floatingLabelEnabled {
    return decoration.floatingLabelBehavior != FloatingLabelBehavior.never;
  }

  Set<MaterialState> get materialState {
    return <MaterialState>{
      if (!decoration.enabled) MaterialState.disabled,
      if (_focusNode.hasFocus) MaterialState.focused,
    };
  }

  InputDecoration? _effectiveDecoration;

  InputDecoration get decoration =>
      _effectiveDecoration ??= widget.decoration.applyDefaults(Theme.of(context).inputDecorationTheme);

  TextStyle get labelStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
        final ColorScheme colors = Theme.of(context).colorScheme;
        final TextTheme textTheme = Theme.of(context).textTheme;
        final TextStyle textStyle = textTheme.bodyLarge ?? const TextStyle();
        if (states.contains(MaterialState.disabled)) {
          return textStyle.copyWith(color: colors.onSurface.withOpacity(0.38));
        }
        if (states.contains(MaterialState.focused)) {
          return textStyle.copyWith(color: colors.primary);
        }
        return textStyle;
      });

  @override
  Widget build(BuildContext context) {
    final ThemeData themeData = Theme.of(context);
    InputDecorationTheme defaults = themeData.inputDecorationTheme;

    final Widget? label = decoration.labelText == null && decoration.label == null
        ? null
        : AnimatedOpacity(
            duration: _kTransitionDuration,
            curve: _kTransitionCurve,
            opacity: _labelShouldWithdraw ? 1.0 : 0.0,
            child: AnimatedDefaultTextStyle(
              duration: _kTransitionDuration,
              curve: _kTransitionCurve,
              style: _getInlineLabelStyle(
                themeData,
                defaults.labelStyle ?? labelStyle,
              ),
              child: decoration.label ??
                  Text(
                    decoration.labelText!,
                    overflow: TextOverflow.ellipsis,
                    textAlign: ([FloatingLabelAlignment.start, null].contains(
                      decoration.floatingLabelAlignment,
                    ))
                        ? TextAlign.start
                        : TextAlign.center,
                  ),
            ),
          );

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
        if (_floatingLabelEnabled && label != null) label,
        TextFormField(
          controller: _controller,
          initialValue: widget.initialValue,
          focusNode: _focusNode,
          decoration: decoration.copyWith(
            floatingLabelBehavior: FloatingLabelBehavior.never,
          ),
          keyboardType: widget.keyboardType,
          style: widget.style,
          autofocus: widget.autofocus,
          readOnly: widget.readOnly,
          maxLines: widget.maxLines,
          minLines: widget.minLines,
          onChanged: widget.onChanged,
          onTapOutside: widget.onTapOutside,
          enabled: widget.enabled,
        ),
      ],
    );
  }

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

  TextStyle _getInlineLabelStyle(ThemeData themeData, TextStyle labelStyle) {
    final TextStyle defaultStyle = MaterialStateProperty.resolveAs(labelStyle, materialState);
    final TextStyle? style = MaterialStateProperty.resolveAs(decoration.labelStyle, materialState) ??
        MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.labelStyle, materialState);

    return themeData.textTheme.titleMedium!.merge(defaultStyle).merge(style).copyWith(height: 1);
  }
}

演示.png

© www.soinside.com 2019 - 2024. All rights reserved.