总体采用GetX架构,使用getx响应式控制验证码状态很简单ios
先看下logic层markdown
class MobileLoginLogic extends GetxController {
RxBool showClear = false.obs;
RxBool codeEnable = false.obs;
RxBool checkBox = false.obs;
RxBool loginBtnEable = false.obs;
/// 倒计时的计时器。
late Timer _timer;
/// 当前倒计时的秒数。
late int _seconds = 20;
late bool needRestTime;
RxString verifyStr = '获取验证码'.obs;
TextEditingController mobileMemberController = TextEditingController();
TextEditingController codeController = TextEditingController();
final formKey = GlobalKey<FormState>();
late String identifierForVendor;
@override
void onReady() {
// TODO: implement onReady
super.onReady();
mobileMemberController.addListener(() {
showClear.value = mobileMemberController.text.isNotEmpty;
codeEnable.value = chinaPhoneNumber(mobileMemberController.text);
setLoginBtnStatus();
});
codeController.addListener(() {
setLoginBtnStatus();
});
initPlatformState();
}
Future<void> initPlatformState() async {
DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
if (Platform.isIOS) {
IosDeviceInfo iosDeviceInfo = await deviceInfoPlugin.iosInfo;
identifierForVendor = iosDeviceInfo.identifierForVendor;
}
}
setLoginBtnStatus(){
if (mobileMemberController.text.length>=3) {
loginBtnEable.value = true;
}else{
loginBtnEable.value = false;
}
}
clearField() {
showClear.value = false;
mobileMemberController.clear();
}
checkArgement(){
checkBox.value = !checkBox.value;
}
/// 取消倒计时的计时器。
void _cancelTimer() {
_timer.cancel();
}
/// 启动倒计时的计时器。
void startTimer() {
// 计时器(`Timer`)组件的按期(`periodic`)构造函数,建立一个新的重复计时器。
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
if (_seconds == 0) {
_cancelTimer();
_seconds = 20;
verifyStr.value = '从新发送';
codeEnable.value = true;
return;
}
_seconds--;
verifyStr.value = '已发送$_seconds' + 's';
codeEnable.value = false;
});
}
chageCodeStatus(){
if (codeEnable.value) {
startTimer();
}
}
bool chinaPhoneNumber(String input) {
String regexPhoneNumber =
"^((13[0-9])|(15[^4])|(166)|(17[0-8])|(18[0-9])|(19[8-9])|(147,145))\\d{8}\$";
return RegExp(regexPhoneNumber).hasMatch(input);
}
loginClick() async{
if (!loginBtnEable.value) return;
print(identifierForVendor);
Fluttertoast.showToast(msg: '登陆中',gravity: ToastGravity.CENTER,toastLength:Toast.LENGTH_LONG);
try{
var response = await Dio().post('',data: {
'token':mobileMemberController.text,
'imei':identifierForVendor
});
Map<String,dynamic> data = response.data;
if (data["code"] == 200) {
StorageManager.sharedPreferences.setString(StorageManager.access_token, mobileMemberController.text);
UserModel userModel = UserModel.fromJson(data["data"]);
StorageManager.localStorage.setItem(StorageManager.access_user, userModel);
Get.offNamed(Routes.MAIN);
}else{
Fluttertoast.showToast(msg: '登陆失败');
}
}catch(e){
Fluttertoast.showToast(msg: '登陆失败');
}
}
}
复制代码
验证码单独的statelessWidget架构
class VerifyCodeWidget extends StatelessWidget {
final MobileLoginLogic logic = Get.put(MobileLoginLogic());
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () => logic.chageCodeStatus(),
child: Obx(() => Container(
padding: EdgeInsets.all(5.0),
decoration: BoxDecoration(
border: Border.all(
color: logic.codeEnable.value
? Color(0xFF0165B8)
: Colors.white)),
child: Text(
logic.verifyStr.value,
style: TextStyle(color: logic.codeEnable.value?Color(0xFF0165B8):Color(0xFFACB1B6)),
),
)),
);
}
}
复制代码
经过logic.codeEnable.value 控制是否能够点击less
logic.verifyStr.value 控制显示的文本async
手机号框根据内容显示清空图标ide
TextFormField(
controller: logic.mobileMemberController,
inputFormatters: <TextInputFormatter>[
LengthLimitingTextInputFormatter(11)
],
textInputAction: TextInputAction.next,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: '请输入手机号',
labelStyle: TextStyle(color: Color(0xFF898E92)),
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
suffixIcon: Obx(() => Visibility(
visible: logic.showClear.value,
child: IconButton(
icon: Icon(
CupertinoIcons.clear_thick_circled,
color: Color(0xFFCBD0D4),
),
onPressed: logic.clearField))))),
复制代码
suffixIocn是后缀清除按钮 经过 Obx(() => Visibility()控制是都显示函数