表单小部件的全局样式

时间:2020-06-08 12:19:21

标签: flutter

我想知道如何在flutter中将全局样式应用于表单字段。我发现自己不得不重复代码来更改: 1.背景色 2.文字颜色 3.边界半径 4.边框厚度 5.盒子阴影

所以我决定创建一个这样的自定义小部件:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class CustomTextField extends StatefulWidget {
  final String title;
  final String labelText;
  final String hintText;
  final IconData icon;
  final TextInputType keyboardType;
  final bool isPasswordField;
  final TextEditingController controller;
  final bool enabled;
  final int maxLines;
  final Function onTap;
  final bool readOnly;
  final bool isOutlineBorder;
  final List<TextInputFormatter> inputFormatters;
  final String Function(String) validator;

  const CustomTextField({
    Key key,
    this.title,
    this.labelText,
    this.hintText,
    this.icon,
    this.keyboardType = TextInputType.text,
    this.isPasswordField = false,
    this.controller,
    this.enabled = true,
    this.maxLines = 1,
    this.onTap,
    this.readOnly = false,
    this.isOutlineBorder = true,
    this.inputFormatters,
    this.validator,
  }) : super(key: key);

  @override
  _CustomTextFieldState createState() => _CustomTextFieldState();
}

class _CustomTextFieldState extends State<CustomTextField> {
  bool _obscureText = true;

  @override
  Widget build(BuildContext context) {
    final outlineBorder = OutlineInputBorder(
      borderRadius: BorderRadius.circular(30.0),
      borderSide: BorderSide(
        color: Colors.grey.withOpacity(0.4),
      ),
    );

    final underlineBorder = UnderlineInputBorder(
      borderSide: BorderSide(
        color: Colors.grey.withOpacity(0.4),
      ),
    );

    return Container(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          _buildTitle(),
          TextFormField(
            validator: widget.validator,
            decoration: InputDecoration(
              labelText: widget.labelText,
              labelStyle: TextStyle(
                fontWeight: FontWeight.w600,
                color: Colors.grey.withOpacity(0.5),
              ),
              hintText: widget.hintText,
              prefixIcon: widget.icon != null
                  ? Icon(
                      widget.icon,
                      color: Colors.grey.withOpacity(0.4),
                    )
                  : null,
              enabledBorder:
                  widget.isOutlineBorder ? outlineBorder : underlineBorder,
              border: widget.isOutlineBorder ? outlineBorder : underlineBorder,
              suffixIcon: widget.isPasswordField
                  ? _buildPasswordFieldVisibilityToggle()
                  : null,
              contentPadding: EdgeInsets.symmetric(
                vertical: 15.0,
                horizontal: 10.0,
              ),
            ),
            keyboardType: widget.keyboardType,
            style: TextStyle(
              fontWeight: FontWeight.w600,
              color: Colors.black38,
            ),
            cursorColor: Theme.of(context).primaryColor,
            obscureText: widget.isPasswordField ? _obscureText : false,
            controller: widget.controller,
            enabled: widget.enabled,
            maxLines: widget.maxLines,
            onTap: widget.onTap ?? null,
            readOnly: widget.readOnly ?? false,
            inputFormatters: widget.inputFormatters ?? null,
          ),
        ],
      ),
    );
  }

  Widget _buildPasswordFieldVisibilityToggle() {
    return IconButton(
      icon: Icon(
        _obscureText ? Icons.visibility_off : Icons.visibility,
      ),
      onPressed: () {
        setState(() {
          _obscureText = !_obscureText;
        });
      },
    );
  }

  Widget _buildTitle() {
    return widget.title == null
        ? Container()
        : Text(
            widget.title,
            style: TextStyle(
              color: Colors.grey,
              fontSize: 15.0
            ),
          );
  }
}

但是,由于我是新手,所以我想知道是否存在一种为表单字段设置全局样式以更改这些属性的方法:

background color
text color
border radius
border thickness
box shadow

无需我创建这样的自定义窗口小部件类。还是我将如何声明可以分配给任何TextFormField小部件的InputDecoration类?

1 个答案:

答案 0 :(得分:0)

您可以创建ThemeData来将属性属性设置为所有TextFormField输入装饰的主页,如下所示:

return MaterialApp(...
theme: ThemeData(
  primarySwatch: Colors.blue,
  accentColor: main_color_orange,
textTheme: TextTheme(
   bodyText2: TextStyle(
   // defualt all text widget
   color: Colors.white,
   fontSize: 16.0,
   fontFamily: 'Iranian'),
              ),
  // fill back inside all TextFormField
  inputDecorationTheme: InputDecorationTheme(
    fillColor: Colors.black,
    filled: true,
  ),

使用textTheme,您可以制作自己的样式并在这样的ure代码中使用:

child: Text("Social POSH Music Network",
       textAlign: TextAlign.center,
       style: Theme.of(context).textTheme.bodyText1),
),