adee42 / flutter_keyboard_visibility

MIT License
237 stars 143 forks source link

It is not working on Login Bloc #7

Closed baeharam closed 5 years ago

baeharam commented 5 years ago

I'm implementing Login Form with Bloc pattern and I have to manage the size of LoginForm when keyboard is appeared. But It is not working...

import 'package:flutter/material.dart';
import 'package:privacy_of_animal/bloc_helpers/bloc_provider.dart';
import 'package:privacy_of_animal/logics/focus/focus.dart';
import 'package:privacy_of_animal/logics/validation/validation_bloc.dart';
import 'package:privacy_of_animal/resources/colors.dart';
import 'package:privacy_of_animal/resources/constants.dart';
import 'package:privacy_of_animal/widgets/initial_button.dart';
import 'package:keyboard_visibility/keyboard_visibility.dart';

class LoginForm extends StatefulWidget {
  @override
  _LoginFormState createState() => _LoginFormState();
}

class _LoginFormState extends State<LoginForm> with SingleTickerProviderStateMixin{

  final FocusNode _focusNode = FocusNode();
  final ValidationBloc _validationBloc = ValidationBloc();
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();
  final KeyboardVisibilityNotification _keyboardVisibilityNotification = KeyboardVisibilityNotification();

  @override
    void dispose() {
      _emailController.dispose();
      _passwordController.dispose();
      _focusNode.dispose();
      _keyboardVisibilityNotification.dispose();
      super.dispose();
    }

  @override
  Widget build(BuildContext context) {

    final FocusBloc _focusBloc = BlocProvider.of<FocusBloc>(context);

    _keyboardVisibilityNotification.addNewListener(
      onShow: _focusBloc.emitEvent(FocusEventOn()),
      onHide: _focusBloc.emitEvent(FocusEventOff())
    );

    return Container(
      height: ScreenUtil.height/3,
      width: ScreenUtil.width/1.3,
      color: Colors.red,
      child: Column(
        children: <Widget>[
          StreamBuilder<String>(
            stream: _validationBloc.email,
            builder: (BuildContext context, AsyncSnapshot<String> snapshot){
              return TextField(
                decoration: InputDecoration(
                  labelText: '이메일',
                  errorText: snapshot.error,
                ),
                onChanged: _validationBloc.onEmailChanged,
                keyboardType: TextInputType.emailAddress,
                controller: _emailController,
              );
            },
          ),
          SizedBox(height: 20.0),
          StreamBuilder<String>(
            stream: _validationBloc.password,
            builder: (BuildContext context, AsyncSnapshot<String> snapshot){
              return TextField(
                decoration: InputDecoration(
                  labelText: '비밀번호',
                  errorText: snapshot.error
                ),
                onChanged: _validationBloc.onPasswordChanged,
                obscureText: true,
                keyboardType: TextInputType.emailAddress,
                controller: _passwordController,
              );
            },
          ),
          SizedBox(height: 30.0),
          StreamBuilder<bool>(
            stream: _validationBloc.loginValid,
            builder: (BuildContext context, AsyncSnapshot<bool> snapshot){
              return InitialButton(
                text: '로그인',
                color: introLoginButtonColor,
                callback: (snapshot.hasData && snapshot.data==true) ? (){} : null,
              );
            },
          )
        ],
      ),
    );
  }
}

What is the problem?

adee42 commented 5 years ago

Hi, the first thing that catches my eye is that you are adding the listener in the build function. You should not do that because this function is sometimes being called multiple times while the keyboard appears. Instead you should move the listener into the initState function inside the _LoginFormState class. Here is an example how to implement that:

@protected void initState() {
    super.initState();

    _keyboardVisibilityNotification.addNewListener(
      onShow: _focusBloc.emitEvent(FocusEventOn()),
      onHide: _focusBloc.emitEvent(FocusEventOff())
    );
}

Also can you provide more information of what exactly is not working properly?

adee42 commented 5 years ago

I will close this issue as there hasn't been any updates recently. If the problem still persists, please re-open