fix:修复密码输入框焦点消失的问题

This commit is contained in:
anfe 2024-05-03 18:30:45 +08:00
parent f5963a166d
commit b8dd7f6cca
9 changed files with 203 additions and 100 deletions

View File

@ -94,7 +94,7 @@ class _StarLockForgetPasswordPageState
logic.checkNext(state.phoneController);
},
leftWidget: Padding(
padding: EdgeInsets.only(top: 30.w, bottom: 20.w, right: 20.w, left: 5.w),
padding: EdgeInsets.only(top: 30.w, bottom: 20.w, right: 5.w, left: 5.w),
child: Image.asset(
'images/icon_login_account.png',
width: 36.w,
@ -115,7 +115,7 @@ class _StarLockForgetPasswordPageState
isPwd: true,
leftWidget: Padding(
padding: EdgeInsets.only(
top: 30.w, bottom: 20.w, right: 20.w, left: 5.w),
top: 30.w, bottom: 20.w, right: 5.w, left: 5.w),
child: Image.asset(
'images/icon_login_password.png',
width: 36.w,
@ -142,7 +142,7 @@ class _StarLockForgetPasswordPageState
isPwd: true,
leftWidget: Padding(
padding: EdgeInsets.only(
top: 30.w, bottom: 20.w, right: 20.w, left: 5.w),
top: 30.w, bottom: 20.w, right: 5.w, left: 5.w),
child: Image.asset(
'images/icon_login_password.png',
width: 36.w,

View File

@ -15,6 +15,43 @@ import 'starLock_login_state.dart';
class StarLockLoginLogic extends BaseGetXController {
final StarLockLoginState state = StarLockLoginState();
final stateMyLogic = Get.put(StarLockMineLogic()).state;
int indexFocusNode = noneFocusNode;
static int noneFocusNode = 0;
static int emailOrPhoneFocusNode = 1;
static int pwdFocusNode = 2;
@override
void onInit() {
super.onInit();
// state.emailOrPhoneFocusNode.addListener(() {
// if (state.emailOrPhoneFocusNode.hasFocus) {
// indexFocusNode = emailOrPhoneFocusNode;
// } else {
// changeInputFocusNode();
// }
// });
// state.pwdFocusNode.addListener(() {
// if (state.pwdFocusNode.hasFocus) {
// indexFocusNode = pwdFocusNode;
// } else {
// changeInputFocusNode();
// }
// });
}
//
void changeInputFocusNode() {
Future.delayed(Duration(milliseconds: 100), () {
if (indexFocusNode == noneFocusNode) {
return;
}
if (indexFocusNode == emailOrPhoneFocusNode) {
state.emailOrPhoneFocusNode.requestFocus();
} else if (indexFocusNode == pwdFocusNode) {
state.pwdFocusNode.requestFocus();
}
});
}
void login() async {
var entity = await ApiRepository.to.login(

View File

@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:star_lock/flavors.dart';
import 'package:star_lock/widget/star_input_formatter.dart';
import '../../appRouters.dart';
import '../../app_settings/app_colors.dart';
@ -43,7 +43,7 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
),
onPressed: () async {
var data = await Get.toNamed(Routers.starLockRegisterPage);
if(data != null){
if (data != null) {
state.emailOrPhoneController.text = data['phoneOrEmailStr'];
logic.checkNext(state.emailOrPhoneController);
state.pwdController.text = data['pwd'];
@ -63,35 +63,38 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
width: 110.w, height: 110.w))),
SizedBox(height: 50.w),
Obx(() => CommonItem(
leftTitel: "${"你所在的".tr}${TranslationLoader.lanKeys!.countryAndRegion!.tr}",
rightTitle: "",
isHaveLine: true,
isPadding: false,
isHaveRightWidget: true,
isHaveDirection: true,
rightWidget: Text(
'${state.countryName.value} +${state.countryCode.value}',
textAlign: TextAlign.end,
style:
TextStyle(fontSize: 22.sp, color: AppColors.darkGrayTextColor),
),
action: () async {
var result = await Get.toNamed(Routers.selectCountryRegionPage);
if (result != null) {
result as Map<String, dynamic>;
state.countryCode.value = result['code'];
state.countryName.value = result['countryName'];
}
},
)),
leftTitel:
"${"你所在的".tr}${TranslationLoader.lanKeys!.countryAndRegion!.tr}",
rightTitle: "",
isHaveLine: true,
isPadding: false,
isHaveRightWidget: true,
isHaveDirection: true,
rightWidget: Text(
'${state.countryName.value} +${state.countryCode.value}',
textAlign: TextAlign.end,
style: TextStyle(
fontSize: 22.sp, color: AppColors.darkGrayTextColor),
),
action: () async {
var result =
await Get.toNamed(Routers.selectCountryRegionPage);
if (result != null) {
result as Map<String, dynamic>;
state.countryCode.value = result['code'];
state.countryName.value = result['countryName'];
}
},
)),
LoginInput(
focusNode: logic.state.emailOrPhoneFocusNode,
controller: state.emailOrPhoneController,
onchangeAction: (v) {
logic.checkNext(state.emailOrPhoneController);
},
leftWidget: Padding(
padding: EdgeInsets.only(
top: 30.w, bottom: 20.w, right: 20.w, left: 5.w),
top: 30.w, bottom: 20.w, right: 5.w, left: 5.w),
child: Image.asset(
'images/icon_login_account.png',
width: 36.w,
@ -107,6 +110,7 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
]),
SizedBox(height: 10.h),
LoginInput(
focusNode: logic.state.pwdFocusNode,
controller: state.pwdController,
onchangeAction: (v) {
logic.checkNext(state.pwdController);
@ -114,7 +118,7 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
isPwd: true,
leftWidget: Padding(
padding: EdgeInsets.only(
top: 30.w, bottom: 20.w, right: 20.w, left: 5.w),
top: 30.w, bottom: 20.w, right: 5.w, left: 5.w),
child: Image.asset(
'images/icon_login_password.png',
width: 36.w,
@ -137,7 +141,8 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
},
child: Container(
// color: Colors.red,
padding: EdgeInsets.only(left: 5.w, top:20.w, right: 10.w, bottom:20.h),
padding: EdgeInsets.only(
left: 5.w, top: 20.w, right: 10.w, bottom: 20.h),
child: Image.asset(
state.agree.value
? 'images/icon_round_select.png'
@ -257,15 +262,15 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
));
}
Widget loginInput({
TextEditingController? controller,
List<TextInputFormatter>? inputFormatters,
String? hintText,
bool? isHaveLeftWidget,
Widget? leftWidget,
String? label,
bool? isPwd,
BlockStrCallback? onchangeAction}) {
Widget loginInput(
{TextEditingController? controller,
List<TextInputFormatter>? inputFormatters,
String? hintText,
bool? isHaveLeftWidget,
Widget? leftWidget,
String? label,
bool? isPwd,
BlockStrCallback? onchangeAction}) {
return Container(
// color: Colors.red,
width: 1.sp,
@ -282,7 +287,9 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
height: 36.w,
),
),
SizedBox(width: 40.w,),
SizedBox(
width: 40.w,
),
Expanded(
child: TextField(
//
@ -290,7 +297,7 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
controller: controller,
onChanged: onchangeAction,
// autofocus: false,
inputFormatters:inputFormatters,
inputFormatters: inputFormatters,
decoration: InputDecoration(
//
contentPadding: const EdgeInsets.only(
@ -322,5 +329,4 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
),
);
}
}

View File

@ -17,6 +17,9 @@ class StarLockLoginState {
TextEditingController emailOrPhoneController = TextEditingController();
TextEditingController pwdController = TextEditingController();
FocusNode emailOrPhoneFocusNode = FocusNode();
FocusNode pwdFocusNode = FocusNode();
StarLockLoginState() {
// emailOrPhone.value = StoreService.to.getLastUserAccount() as String;
emailOrPhoneController.text = emailOrPhone.value;

View File

@ -203,7 +203,7 @@ class _StarLockRegisterPageState extends State<StarLockRegisterPage> {
leftWidget:
// Image.asset('images/icon_login_account.png', width: 30.w, height: 30.w,),
Padding(
padding: EdgeInsets.only(right: 10.w, left: 5.w),
padding: EdgeInsets.only(right: 5.w, left: 5.w),
child: Image.asset(
state.isIphoneType.value
? 'images/icon_login_account.png'
@ -227,7 +227,7 @@ class _StarLockRegisterPageState extends State<StarLockRegisterPage> {
},
isPwd: true,
leftWidget: Padding(
padding: EdgeInsets.only(right: 10.w, left: 5.w),
padding: EdgeInsets.only(right: 5.w, left: 5.w),
child: Image.asset(
'images/icon_login_password.png',
width: 30.w,

View File

@ -13,6 +13,8 @@ import 'package:get/get.dart';
// flavorizr.yaml
FutureOr<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await _setCommonServices();
//

View File

@ -1,3 +1,4 @@
import 'package:extended_text_field/extended_text_field.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@ -11,11 +12,11 @@ import 'package:star_lock/app_settings/app_colors.dart';
typedef BlockStrCallback = void Function(dynamic textStr);
typedef BlockClickCallback = void Function();
class LoginInput extends StatelessWidget {
class LoginInput extends StatefulWidget {
TextEditingController? controller;
FocusNode? focusNode;
List<TextInputFormatter>? inputFormatters;
TextInputType? keyboardType;
FocusNode? focusNode;
Color? background;
String? hintText;
bool? isHaveLeftWidget;
@ -25,70 +26,110 @@ class LoginInput extends StatelessWidget {
bool? isSuffixIcon;
Widget? rightSlot;
BlockStrCallback? onchangeAction;
BlockStrCallback? onSubmitted;
BlockClickCallback? onTapAction;
LoginInput(
{Key? key,
required this.controller,
this.focusNode,
this.rightSlot,
this.label,
this.isPwd,
this.isSuffixIcon,
this.inputFormatters,
this.keyboardType,
this.background,
this.hintText,
this.isHaveLeftWidget = true,
this.leftWidget,
this.onchangeAction,
this.onTapAction,
})
: super(key: key);
LoginInput({
Key? key,
required this.controller,
this.rightSlot,
this.focusNode,
this.label,
this.isPwd,
this.isSuffixIcon,
this.inputFormatters,
this.keyboardType,
this.background,
this.hintText,
this.isHaveLeftWidget = true,
this.leftWidget,
this.onchangeAction,
this.onTapAction,
this.onSubmitted,
}) : super(key: key);
@override
State<LoginInput> createState() => _LoginInputState();
}
class _LoginInputState extends State<LoginInput> {
@override
Widget build(BuildContext context) {
bool isPwd = widget.isPwd ?? false;
String pwd = (widget.controller?.text ?? '').replaceAll(RegExp(r'.'), '*');
return Container(
child: Column(
decoration: BoxDecoration(
border: Border(bottom: BorderSide(width: 0.5.h, color: Colors.grey)),
),
child: Row(
children: [
TextField(
//
maxLines: 1,
controller: controller,
focusNode: focusNode,
onChanged: onchangeAction,
onTap: onTapAction,
autofocus: false,
inputFormatters: inputFormatters,
decoration: InputDecoration(
//
contentPadding: const EdgeInsets.only(
top: 8.0, left: -19.0, right: -15.0, bottom: 8.0),
labelText: label,
labelStyle: TextStyle(fontSize: 22.sp,color: AppColors.darkGrayTextColor),
hintStyle: TextStyle(fontSize: 22.sp),
hintText: hintText,
//线
border: InputBorder.none,
suffixIcon: (isSuffixIcon ?? false)
? IconButton(
icon: const Icon(Icons.clear),
onPressed: controller!.clear,
)
: null,
//
icon: isHaveLeftWidget == true
? leftWidget
: SizedBox(
width: 20.w,
height: 40.w,
widget.isHaveLeftWidget == true
? widget.leftWidget ?? SizedBox()
: SizedBox(
width: 20.w,
height: 40.w,
),
Expanded(
child: Stack(
children: [
TextField(
//
maxLines: 1,
controller: widget.controller,
focusNode: widget.focusNode,
onChanged: (String text) {
if (widget.onchangeAction != null) {
widget.onchangeAction!(text);
}
setState(() {});
},
onTap: widget.onTapAction,
autofocus: false,
inputFormatters: widget.inputFormatters,
textInputAction: TextInputAction.next,
keyboardType: isPwd ? TextInputType.emailAddress : null,
style: isPwd
? TextStyle(
fontSize: 22.sp,
color: Colors.transparent,
letterSpacing: 2.5,
fontFamily: 'Monospace',
)
: null,
decoration: InputDecoration(
//
contentPadding: const EdgeInsets.only(
top: 8.0, right: -10.0, bottom: 8.0),
labelText: widget.label,
labelStyle: TextStyle(
fontSize: 22.sp, color: AppColors.darkGrayTextColor),
hintStyle: TextStyle(fontSize: 22.sp),
hintText: widget.hintText,
//线
border: InputBorder.none,
suffixIcon: (widget.isSuffixIcon ?? false)
? IconButton(
icon: const Icon(Icons.clear),
onPressed: widget.controller!.clear,
)
: null,
),
),
if (isPwd)
Padding(
padding: EdgeInsets.only(top: 30.h),
child: Text(
pwd,
style: TextStyle(
fontSize: 22.sp,
color: AppColors.darkGrayTextColor,
letterSpacing: 2.0,
fontFamily: 'Monospace',
),
),
),
],
),
obscureText: isPwd ?? false,
),
Container(
height: 0.5.h,
color: Colors.grey,
),
],
),

View File

@ -0,0 +1,13 @@
import 'package:flutter/services.dart';
class StarInputFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
//
return TextEditingValue(
text: '*' * newValue.text.length,
selection: TextSelection.collapsed(offset: newValue.text.length),
);
}
}

View File

@ -170,6 +170,7 @@ dependencies:
expandable: ^5.0.1
colorfilter_generator: ^0.0.8
file_picker: ^5.3.1
extended_text_field: 13.1.0
dev_dependencies: