StreamBuilder 中的 TextField 丢失了编辑后的值

TextField inside StreamBuilder lost the edited values

我正在为一个应用程序开发用户配置文件更新页面,我遇到了问题,为了用初始数据填充表单,我使用了 StreamBuilder 并使用 TextEditingController 将数据加载到 TextField ,数据加载正常并且运行良好,但问题是当我尝试更改 TextField 并专注于下一个 TextField StreamBuilder 使用之前加载并丢失的数据刷新 ui编辑的数据。在这种情况下,Stream 不会从网络调用中更新。有人遇到过这种情况吗?或任何推荐的方法来做到这一点?请帮忙。

代码

class UserProfileScreen extends StatefulWidget {
  @override
  _UserProfileScreenState createState() => _UserProfileScreenState();
}

class _UserProfileScreenState extends State<UserProfileScreen> {
  UserProfileBloc userBloc;

  final firstNameController = TextEditingController();
  final surnameNameController = TextEditingController();
  final phoneController = TextEditingController();
  final emailController = TextEditingController();

  var _hashCode = 0;

  @override
  void initState() {
    super.initState();
    userBloc = UserProfileBloc();
    userBloc.getUser();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 0.0,
        leading: IconButton(
          icon: Icon(
            Icons.close,
            color: ColorPallet.white,
          ),
          onPressed: () {
            if (Navigator.canPop(context)) {
              Navigator.pop(context);
            }
          },
        )
      ),
      body: buildUserProfileContent(context),
    );
  }

  Container buildUserProfileContent(BuildContext context) {
    return Container(
      child: StreamBuilder<UserProfileState>(
        stream: userBloc.user,
        initialData: UserProfileInitState(),
        builder: (context, snapshot) {
          if (snapshot.data is UserProfileDataState) {
            UserProfileDataState state = snapshot.data;
            return buildProfileContent(state.user, state.profileImage);
          }

        },
      ),
    );
    //);
  }

  ListView buildProfileContent(User user, Uint8List profileImage) {
    firstNameController.text = user.firstName;
    return ListView(
      children: <Widget>[
        Container(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              TextField(
                controller: firstNameController,
              ),
            ]

        ),
        )],
    );
  }
}

问题发生在您在构建方法中设置值时。如果你想像上面那样设置值,在 class _UserProfileScreenState 维护一个变量 _initialized = false 并在初始化后使其成为 true

类似于:

if(!_initialized){
    firstNameController.text = user.firstName;
    _initialized = true;
}

希望对您有所帮助!

你应该按照我的代码使用onChange。

  onChanged: (value) => {_onChangeValue()},

  StreamBuilder(
                        initialData: true,
                        stream: _loginBloc.isToggledPass,
                        builder: (context, snapshot) {
                          return TextField(
                            controller: _passwordController,
                            obscureText: snapshot.data,
                            textInputAction: TextInputAction.done,
                            onChanged: (value) => {_onChangeValue()},
                            decoration: InputDecoration(
                                hintText: hintPassword,
                          );
                        }),