簡體   English   中英

(顫振)TextFormField 在焦點上更改標簽顏色

[英](Flutter) TextFormField Change labelColor on Focus

我試圖在聚焦時更改我的labelText顏色。 我可以更改文本顏色,但不能在聚焦時更改。

我已經嘗試了所有提示文本顏色和標簽文本顏色,但沒有任何幫助。

Container(
  padding: EdgeInsets.fromLTRB(15, 10, 15, 0),
  child: TextFormField(
    cursorColor: Colors.lightGreen,
    keyboardType: TextInputType.phone,
    decoration: InputDecoration(
      labelText: 'Phone Number',
      hintText: 'Enter a Phone Number',
      focusedBorder: OutlineInputBorder(
        borderSide: BorderSide(
          color: Colors.lightGreen
        )
      ),
      border: OutlineInputBorder(
        borderSide: BorderSide()
      ),
    )
  ),
),

以下是正在發生的事情的圖片:

在此處輸入圖像描述

在此處輸入圖像描述

你需要有一種方法來確定它的焦點狀態,然后根據它為它的顏色創建一個條件。 這是focusNode有用的地方。 從小部件創建中構造一個新的FocusNode ,將其用作TextFormField中的focusNode屬性。 然后在TextFormFieldTextStyle屬性的顏色屬性中,您可以添加如下內容:

FocusNode myFocusNode = new FocusNode();

...

  return TextFormField(
    focusNode: myFocusNode,
    decoration: InputDecoration(
      labelText: 'test',
      labelStyle: TextStyle(
        color: myFocusNode.hasFocus ? Colors.blue : Colors.black
      )
    ),
  );

編輯:只是一個簡短的說明,您可能需要確保它在StatefulWidget中,然后將偵聽器添加到您創建的focusNode並在該focusNode上的任何事件上調用setState 否則你不會看到任何變化。

摘要

您可能想查看Flutter Cookbook 的焦點和文本字段配方。

本質上,我們必須:

  1. 創建一個FocusNode屬性。
  2. 為其添加初始化和處置。
  3. 將其添加到TextFormField
  4. 每次點擊TextFormField時添加一個焦點請求。

1. 創建一個FocusNode屬性

class CustomTextFormFieldState extends State<CustomTextFormField> {
  FocusNode _focusNode;
  ...

2.為其添加初始化和處置

@override
void initState() {
  super.initState();
  _focusNode = FocusNode();
}

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

3. 將其添加到TextFormField

@override
Widget build(BuildContext context) {
  return TextFormField(
    focusNode: _focusNode,
    ...

4. 每次點擊TextFormField時添加一個焦點請求

不要忘記使用setState

void _requestFocus(){
  setState(() {
    FocusScope.of(context).requestFocus(_focusNode);
  });
}

將該方法添加到TextFormFieldonTap屬性:

@override
Widget build(BuildContext context) {
  return TextFormField(
    focusNode: _focusNode,
    onTap: _requestFocus,
    ...

使用主題,這只需要在中心位置完成一次:

inputDecorationTheme: InputDecorationTheme(
      floatingLabelStyle: TextStyle(color: Colors.blue),
    ),

一個快速的解決方案是從 Widget MaterialApptheme更改primarySwatch 唯一的缺點是需要Material Color

在焦點文本字段圖像上

在此處輸入圖像描述

我用 Focus 小部件解決了這個問題。 首先,我為每個字段定義了一個顏色變量:

final _lowColor = Colors.amber[50];   // use your own colors
final _highColor = Colors.amber[200];

Color _field1Color = _lowColor;
Color _field2Color = _lowColor;
...

然后我用 Focus Widget 包裝每個 TextFormField 並更改 fieldColor:

child: Focus(
  onFocusChange: (hasFocus) {
    setState(() => _field1Color = hasFocus ? _highColor : _lowColor);
  },
  child: TextFormField(
    ...
      color: _field1Color,
    ...
    ),
  ), 
),

這是一種不使用有狀態小部件的快速方法

 return Theme( // 1) wrap with theme widget
   data: Theme.of(context).copyWith(primaryColor: //2) color you want here)
   child: TextFormField(
     focusNode: myFocusNode,
     decoration: InputDecoration(
    labelText: 'test',      
    ),
   ),
  );

更新

正如Guilherme在評論中提到的,Flutter的后期版本使用不同的邏輯來獲取顏色

Color _getActiveColor(ThemeData themeData) {
  if (isFocused) {
    return themeData.colorScheme.primary;
  }
  return themeData.hintColor;
}

資源

您現在需要從colorScheme設置它

ThemeData.dark().copyWith(
  colorScheme: ColorScheme.dark(
    primary: activeColor,
  ),
)

原始答案

在挖掘了用於確定標簽顏色的InputDecorator的源代碼之后,這就是我發現的。

TextStyle _getFloatingLabelStyle(ThemeData themeData) {
  final Color color = decoration.errorText != null
    ? decoration.errorStyle?.color ?? themeData.errorColor
    : _getActiveColor(themeData);
  final TextStyle style = themeData.textTheme.subtitle1.merge(widget.baseStyle);
  return style
    .copyWith(color: decoration.enabled ? color : themeData.disabledColor)
    .merge(decoration.labelStyle);
}

Color _getActiveColor(ThemeData themeData) {
  if (isFocused) {
    switch (themeData.brightness) {
      case Brightness.dark:
        return themeData.accentColor;
      case Brightness.light:
        return themeData.primaryColor;
    }
  }
  return themeData.hintColor;
}

簡而言之,要更改標簽顏色,請將primaryColor淺色主題或accentColor設置為深色主題。

另一個提示:要在未聚焦時更改標簽顏色,請設置hintColor

ThemeData.dark().copyWith(
  primaryColor: Colors.red,
  accentColor: Colors.white,
  hintColor: Colors.pink,
)

https://api.flutter.dev/flutter/material/InputDecoration/labelStyle.html

labelStyle: MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
          final Color color = states.contains(MaterialState.focused)
              ? Colors.pink
              : Colors.orange;
          return TextStyle(color: color);
        }),

當文本字段處於焦點並且文本字段錯誤(由於未遵循驗證引起)時,您還可以使用 labelStyle

labelText: 'Password',
     labelStyle: TextStyle(
        color: Colors.black54,
          ),
//when error has occured
     errorStyle: TextStyle(
       color: Colors.black,
         ),

我使用StatefulWidgetFocus小部件解決了這個問題。 我使用 StatefulWidget 因為您需要使用 setState 來通知焦點輸入時的顏色變化

在此處輸入圖像描述

class InputEmail extends StatefulWidget {
  @override
  _InputEmailState createState() => _InputEmailState();
}

class _InputEmailState extends State<InputEmail> {
  Color _colorText = Colors.black54;

  @override
  Widget build(BuildContext context) {
    const _defaultColor = Colors.black54;
    const _focusColor = Colors.purple;

    return Container(
      padding: EdgeInsets.symmetric(vertical: 15),
      child: Focus(
        onFocusChange: (hasFocus) {
          // When you focus on input email, you need to notify the color change into the widget.
          setState(() => _colorText = hasFocus ? _focusColor : _defaultColor);
        },
        child: TextField(
          // Validate input Email
          keyboardType: TextInputType.emailAddress,
          
          decoration: InputDecoration(
            hintText: 'example@domain.com',
            labelText: 'Email',
            labelStyle: TextStyle(color: _colorText),
            
            // Default Color underline
            enabledBorder: UnderlineInputBorder(
              borderSide: BorderSide(color: Colors.black26),
            ),

            // Focus Color underline
            focusedBorder: UnderlineInputBorder(
              borderSide: BorderSide(color: Colors.purple),
            ),
            icon: Icon(
              Icons.mail,
              color: Colors.deepPurpleAccent,
            ),
          ),
        ),
      ),
    );
  }
}

一種更簡潔的使用樣式的方法(您可以將樣式添加到主題並用於暗\亮模式)

TextFormField(
  decoration: InputDecoration(
    labelText: "some label",
    labelStyle: const TextStyle(color: Colors.grey),
    floatingLabelStyle: const TextStyle(color: Colors.blueAccent),
  ),),

在此處輸入圖像描述

如果你想改變原色。 只需簡單定義添加 Widget MaterialApp 的primaryColor

const appPrimaryColor = Color(0xFF746DF7);
ThemeData theme() {
  return ThemeData(
    scaffoldBackgroundColor: Colors.white,
    fontFamily: "Inter",
    appBarTheme: appBarTheme(),
    textTheme: textTheme(),
    inputDecorationTheme: inputDecorationTheme(),
    visualDensity: VisualDensity.adaptivePlatformDensity,
    primaryColor: appPrimaryColor // <------ HERE
  );
}

MaterialApp(
   title: 'Flutter Demo',
   theme: theme(), // <------ HERE
   home: SplashScreen(),
   routes: routes,
)

在此處輸入圖像描述

您可以使用Theme包裝文本字段並將原色設置為您希望標簽顏色為的任何顏色

'decoration'中有一個'lableStyle',就像:

labelText: 'Description',
labelStyle: TextStyle(
  color: Colors.lightBlueAccent,
)),

活動/點擊

floatingLabelStyle: TextStyle(color: Colors.yellow),

對於非活動

labelStyle: TextStyle(color: Colors.black),

下面是完整的例子

TextField(
         decoration: InputDecoration(
            hintText: 'Verify Password',
            focusColor: appColor,
            labelText: "Verify Password",
            labelStyle: TextStyle(color: Colors.black),
            floatingLabelStyle: TextStyle(color: appColor),
            floatingLabelBehavior: FloatingLabelBehavior.always
         ),
         cursorColor: appColor,
)

InputDecoration中有一個floatingLabelStyle參數,可以這樣使用:

decoration: InputDecoration(
    labelText: "label",
    hintText: "hint",
    labelStyle: GoogleFonts.roboto(
      color: color.labelColor,
    ),
    floatingLabelStyle: GoogleFonts.roboto(
      color: color.defaultGreen,
    ),),

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM