together_mobile/lib/screens/common_widgets.dart

179 lines
4.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:together_mobile/common/constants.dart';
class SignTextField extends StatefulWidget {
const SignTextField({
super.key,
this.color = kPrimaryColor,
this.obscureText = false,
required this.type,
required this.labelText,
required this.controller,
required this.isError,
});
final Color color;
final bool obscureText;
final String type;
final String labelText;
final TextEditingController controller;
final void Function(String, bool) isError;
@override
State<SignTextField> createState() => _SignTextFieldState();
}
class _SignTextFieldState extends State<SignTextField> {
int _length = 0;
String? _errorText;
@override
Widget build(BuildContext context) {
return TextField(
onChanged: (String newValue) {
setState(() {
_length = newValue.characters.length;
});
setErrorText();
widget.isError(
widget.type,
(_errorText == null && widget.controller.text.isEmpty) ||
_errorText != null);
},
controller: widget.controller,
obscureText: widget.obscureText,
cursorColor: widget.color,
textAlignVertical: TextAlignVertical.bottom,
keyboardType: initTextInputType(),
decoration: InputDecoration(
errorText: _errorText,
labelText: widget.labelText,
counterText: '$_length 字符',
floatingLabelStyle: TextStyle(color: widget.color),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: widget.color),
),
),
);
}
TextInputType initTextInputType() {
switch (widget.type) {
case 'email':
return TextInputType.emailAddress;
case 'code':
return TextInputType.number;
case _:
return TextInputType.visiblePassword;
}
}
void setErrorText() {
if (widget.controller.text.isEmpty) {
setState(() {
_errorText = null;
});
}
switch (widget.type) {
case 'username':
if (widget.controller.text.contains(RegExp(r'\W+'))) {
setState(() {
_errorText = '用户名只允许字母, 数字和下划线';
});
} else if (_length < 5 || _length > 20) {
setState(() {
_errorText = '用户名需为8-20个字符';
});
} else {
setState(() {
_errorText = null;
});
}
break;
case 'password' || 'password1' || 'password2':
if (widget.controller.text.contains(RegExp(r'\s'))) {
setState(() {
_errorText = '密码不能包含空格';
});
} else if (_length < 8 || _length > 30) {
setState(() {
_errorText = '密码需为8-30个字符';
});
} else {
setState(() {
_errorText = null;
});
}
break;
case 'email':
var exp = RegExp(
r'^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$');
if (!exp.hasMatch(widget.controller.text)) {
setState(() {
_errorText = '邮箱格式错误';
});
} else {
setState(() {
_errorText = null;
});
}
case 'code':
if (!RegExp(r'\d{6}').hasMatch(widget.controller.text)) {
setState(() {
_errorText = '6为数字';
});
} else if (widget.controller.text.characters.length != 6) {
_errorText = '6位数字';
} else {
setState(() {
_errorText = null;
});
}
}
}
}
TextField textField({
Color color = kPrimaryColor,
bool obscureText = false,
required String labelText,
required TextEditingController controller,
}) {
return TextField(
controller: controller,
obscureText: obscureText,
cursorColor: kSecondaryColor,
textAlignVertical: TextAlignVertical.bottom,
decoration: InputDecoration(
helperText: '5-10位',
errorText: 'xxx',
labelText: labelText,
floatingLabelStyle: const TextStyle(color: kSecondaryColor),
focusedBorder:
UnderlineInputBorder(borderSide: BorderSide(color: color))),
);
}
ElevatedButton elevatedButton(
{required VoidCallback onPressed,
required String text,
Color? color = kPrimaryColor}) {
return ElevatedButton(
onPressed: onPressed,
style: ElevatedButton.styleFrom(
backgroundColor: color,
elevation: 0,
fixedSize: const Size(150, 20),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12))),
child: Text(
text,
style: const TextStyle(fontSize: 20.0, letterSpacing: 10),
),
);
}