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

时间:2019-03-22 06:08:10

标签: flutter textfield flutter-layout

我正在为一个应用程序开发用户配置文件更新页面,我在那里遇到问题,要使用初始数据填充表单,我曾使用StreamBuilder并使用TextEditingController将数据加载到TextField,可以很好地加载并且运行良好,但是问题是当我尝试更改TextField并专注于下一个TextField StreamBuilder时,会使用tha数据刷新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,
              ),
            ]

        ),
        )],
    );
  }
}

2 个答案:

答案 0 :(得分:0)

在构建方法中设置值时会发生问题。如果要像上面一样设置值,请在类_UserProfileScreenState中维护变量_initialized = false,并在初始化后将其设置为true

类似的东西:

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

希望这会有所帮助!

答案 1 :(得分:0)

您应该使用onChange按照mycode。

  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,
                          );
                        }),