王学岗——解决flutter弹出软键盘后布局无限滚动的情况

复制代码
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/svg.dart';
import 'package:vnm_version/widgets/login_registe_button.dart';
import 'package:vnm_version/widgets/login_register_error_tips.dart';

import '../../../config/url_parameters_constant.dart';
import '../../../router/routers.dart';
import '../../../utils/http/dio_utils.dart';
import '../../../utils/http/http_custom_error.dart';
import '../../../utils/http/url_util.dart';
import '../../../utils/navigator_utils.dart';
import '../../../widgets/common_input_container.dart';
import '../../../widgets/forgot_password_tips.dart';
import '../../../widgets/register_login_bottom.dart';

class InputAccountWidget extends StatefulWidget {
  const InputAccountWidget({super.key});

  @override
  State<StatefulWidget> createState() {
    return _InputAccountState();
  }
}

class _InputAccountState extends State<InputAccountWidget> {

  bool accountError = false;

  late FocusNode focusNode;

  String account = "";

  String errorTips = "";
  ///增加代码
  final keyboardVisibilityController = KeyboardVisibilityController();
  ScrollPhysics scrollPhysics = const AlwaysScrollableScrollPhysics();

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

    ///订阅键盘可见性变化
    keyboardVisibilityController.onChange.listen((bool visible) {
      ScrollPhysics sc;
      if (visible) {
        sc = const NeverScrollableScrollPhysics();
      } else {
        sc = const AlwaysScrollableScrollPhysics();
      }
      ///关键点:延迟后再setState,
      Future.delayed(const Duration(milliseconds: 500), () {
        setState(() {
          scrollPhysics = sc;
        });
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: KeyboardVisibilityBuilder(builder: (context, isKeyboardVisible) {
      return SizedBox(
          width: ScreenUtil().screenWidth,
          height: ScreenUtil().screenHeight,
          child: Stack(children: [
            Positioned.fill(
                child: Container(
              color: Colors.white,
              width: double.infinity,
              height: double.infinity,
              child: const Image(
                  image: AssetImage("assets/images/login_register_bg.png"),
                  fit: BoxFit.fitWidth,
                  alignment: Alignment.topCenter),
            )),
            Positioned.fill(
                child: SingleChildScrollView(
                    padding: EdgeInsets.only(
                        bottom: MediaQuery.of(context).viewInsets.bottom),
                    ///设置滚动模式
                    physics: scrollPhysics,
                    child: SizedBox(
                        width: ScreenUtil().screenWidth,
                        height: ScreenUtil().screenHeight,
                        child: Column(
                            mainAxisSize: MainAxisSize.min,
                            mainAxisAlignment: MainAxisAlignment.end,
                            children: [
                              Container(
                                width: ScreenUtil().screenWidth,
                                decoration: const BoxDecoration(
                                  image: DecorationImage(
                                    image: AssetImage(
                                        'assets/images/login_bg_for_move.png'),
                                    fit: BoxFit.fitWidth,
                                    alignment: Alignment.topCenter,
                                  ),
                                ),
                                child: Column(
                                  children: [
                                    SizedBox(height: 70.h),
                                    Image(
                                      image: const AssetImage(
                                          "assets/images/forgot_password_text.png"),
                                      height: 84.h,
                                    ),
                                    SizedBox(height: 30.h),
                                    const ForgotPasswordTips(0),
                                    SizedBox(height: 30.h),
                                    CommonInputContainer(
                                        accountError, focusNode.hasFocus,
                                        (value) {
                                      setState(() {
                                        account = value;
                                        if (accountError) {
                                          accountError = false;
                                        }
                                      });
                                    },
                                        false,
                                        focusNode,
                                        AppLocalizations.of(context)?.account ??
                                            "Account",
                                        SvgPicture.asset(
                                            "assets/images/login_account.svg"),
                                        null),
                                    LoginRegisterErrorTipsWidget(
                                        accountError,
                                        true,
                                        AppLocalizations.of(context)
                                                ?.accountNotExist ??
                                            "The account you entered does not exist",
                                        45.w),
                                    SizedBox(height: 10.h),
                                    LoginRegisterButtons(_submit,
                                        "assets/images/submit_enabled.png",
                                        iconDisabled:
                                            "assets/images/submit_disabled.png",
                                        isButtonEnabled:
                                            account.isNotEmpty && !accountError)
                                  ],
                                ),
                              ),
                              Container(
                                  width: double.infinity,
                                  height: 130.h,
                                  color: Colors.white),

                              RegisterLoginBottomButton(() {}, () {}),
                            ]))))
          ]));
    }));
  }

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

  void _submit() {
    Map<String, dynamic> params = {UrlParametersConstant.account: account};
    DioUtils.main.postRequest(UrlUtil.checkUserBindPhone, jsonMap: params).then(
        (responseMap) {
      NavigatorUtils.pushName(context, Routers.inputPhone,
          parameters: {UrlParametersConstant.account: account});
    }, onError: (e) {
      if (e is ResponseCustomError) {
        if (e.code == 11009) {
          setState(() {
            accountError = true;
            errorTips = AppLocalizations.of(context)?.accountNotExist ??
                "The account you entered does not exist";
          });
        } else if (e.code == 11040) {
          setState(() {
            accountError = true;
            errorTips =
                AppLocalizations.of(context)?.accountNotBoundToMobileNumber ??
                    "Account not bound to mobile number";
          });
        } else {
          setState(() {
            accountError = true;
            errorTips =
                AppLocalizations.of(context)?.unknownError ?? "Unknown error";
          });
        }
      }
    });
  }
}

现在拖动上面的部分,会发现无法滑动

相关推荐
坚果派·白晓明1 小时前
Windows 11 OpenHarmony 版 Flutter 开发环境搭建完整指南
windows·flutter·开源鸿蒙·鸿蒙跨平台应用
音浪豆豆_Rachel1 小时前
Flutter跨平台通信的实战演练:复杂数据结构与单元测试在鸿蒙生态中的完美实现
数据结构·flutter·单元测试·harmonyos
音浪豆豆_Rachel2 小时前
Flutter跨平台通信的类型安全艺术:枚举与复杂对象在鸿蒙生态中的映射与序列化
flutter·harmonyos
昼-枕2 小时前
【鸿蒙Flutter入门】10分钟快速上手开发天气应用
flutter·华为·harmonyos
kirk_wang2 小时前
Flutter `shared_preferences` 三方库在 OpenHarmony 平台的适配实践
flutter·移动开发·跨平台·arkts·鸿蒙
音浪豆豆_Rachel3 小时前
Flutter鸿蒙文件选择器内核解析:从Dart调用到ArkTS系统级对话
flutter·harmonyos
音浪豆豆_Rachel3 小时前
Flutter鸿蒙文件选择器实现层解析:消息通道、协议转换与数据处理
flutter·华为·harmonyos
音浪豆豆_Rachel3 小时前
Flutter鸿蒙文件选择器入口解析:插件生命周期与平台绑定
flutter·harmonyos
消失的旧时光-19433 小时前
401 刷新 Token 的队列版(请求挂起排队 + 刷新后统一重放/统一失败)
flutter·dio
消失的旧时光-19433 小时前
Repository 层如何无缝接入本地缓存 / 数据库
数据库·flutter·缓存