Comments (9)
I added it but still the same result. I noticed that might be the sha1 that is causing the problem. How do I fix that. I generated the keystore and debug one and took the certificate fingerprint for the Google-services.json but didn't work. How did u do this part?
-
If you're using android studio you can use
signingReport
Or from the terminal
./gradlew app:signingreport
-
Use the generated SHA1 while you're creating the
google-services.json
. Make sure the package name is the same as you chose for android. (CheckapplicationId
in yourbuild.gradle
)
from messio.
I am the 27-29 days mark and my login is not working like it should. I'm not sure if my authentication block or the registration page has the problem. Logs are below. Here is also the link to the repository.
https://github.com/Jukez17/WeChat
I/flutter (10482): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:316:33) I/flutter (10482): <asynchronous suspension> I/flutter (10482): #2 MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart:344:48) I/flutter (10482): <asynchronous suspension> I/flutter (10482): #3 GoogleSignIn._callMethod (package:google_sign_in/google_sign_in.dart:218:23) I/flutter (10482): <asynchronous suspension> I/flutter (10482): #4 GoogleSignIn._addMethodCall (package:google_sign_in/google_sign_in.dart:257:20) I/flutter (10482): #5 GoogleSignIn.signIn (package:google_sign_in/google_sign_in.dart:324:48) I/flutter (10482): #6 AuthenticationProvider.signInWithGoogle (package:wechat/providers/AuthenticationProvider.dart:18:28) I/flutter (10482): <asynchronous suspension> I/flutter (10482): #7 AuthenticationRepository.signInWithGoogle (package:wechat/repositories/AuthenticationRepository.dart:9:30) I/flutter (10482): #8 AuthenticationBloc.mapClickedGoogleLoginToState (package:wechat/blocs/authentication/authentication_bloc.dart:77:42) I/flutter (10482): <asynchronous suspension I/flutter (10482): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:569:7) I/flutter (10482): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:316:33) I/flutter (10482): <asynchronous suspension> I/flutter (10482): #2 MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart:344:48) I/flutter (10482): <asynchronous suspension> I/flutter (10482): #3 GoogleSignIn._callMethod (package:google_sign_in/google_sign_in.dart:218:23) I/flutter (10482): <asynchronous suspension> I/flutter (10482): #4 GoogleSignIn._addMethodCall.<anonymous closure> (package:google_sign_in/google_sign_in.dart:270:28) I/flutter (10482): #5 _rootRun (dart:async/zone.dart:1120:38) I/flutter (10482): #6 _CustomZone.run (dart:async/zone.dart:1021:19) I/flutter (10482): #7 _FutureListener.handleWhenComplete (dart:async/future_impl.dart:161:18) I/flutter (10482): #8 Future._propagateToListeners.handleWhenCompleteCallback (dart:async/future_impl.dart:648:39) I/flutter (10482): #9 Future._propagateToListeners (dart:async/future_impl.dart:704:37) I/flutter (10482): #10 Future._addListener.<anonymous closure> (dart:async/future_impl.dart:387:9) I/flutter (10482): #11 _rootRun I/flutter (10482): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:569:7) I/flutter (10482): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:316:33) I/flutter (10482): <asynchronous suspension> I/flutter (10482): #2 MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart:344:48) I/flutter (10482): <asynchronous suspension> I/flutter (10482): #3 GoogleSignIn._callMethod (package:google_sign_in/google_sign_in.dart:218:23) I/flutter (10482): <asynchronous suspension> I/flutter (10482): #4 GoogleSignIn._addMethodCall.<anonymous closure> (package:google_sign_in/google_sign_in.dart:270:28) I/flutter (10482): #5 _rootRun (dart:async/zone.dart:1120:38) I/flutter (10482): #6 _CustomZone.run (dart:async/zone.dart:1021:19) I/flutter (10482): #7 _FutureListener.handleWhenComplete (dart:async/future_impl.dart:161:18) I/flutter (10482): #8 Future._propagateToListeners.handleWhenCompleteCallback (dart:async/future_impl.dart:648:39) I/flutter (10482): #9 Future._propagateToListeners (dart:async/future_impl.dart:704:37) I/flutter (10482): #10 Future._addListener.<anonymous closure> (dart:async/future_impl.dart:387:9) I/flutter (10482): #11 _rootRun```
please add your google-services.json to android/app folder.
from messio.
I added it but still the same result. I noticed that might be the sha1 that is causing the problem. How do I fix that. I generated the keystore and debug one and took the certificate fingerprint for the Google-services.json but didn't work. How did u do this part?
from messio.
I have to try that, thank you :)
from messio.
Okey, progress was made but after sign in I get this error.
package:flutter/src/painting/_network_image_dart.io failed assertion line 23 pos 14 url != null : is not true
from messio.
Okey, progress was made but after sign in I get this error.
package:flutter/src/painting/_network_image_dart.io failed assertion line 23 pos 14 url != null : is not true
Can you post the code from your register screen? Looks like you forgot to add a placeholder.
from messio.
Here,
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:image_picker/image_picker.dart';
import 'package:wechat/config/Assets.dart';
import 'package:wechat/config/Decorations.dart';
import 'package:wechat/config/Palette.dart';
import 'package:wechat/config/Styles.dart';
import 'package:wechat/config/Transitions.dart';
import 'package:wechat/pages/ContactListPage.dart';
import 'package:wechat/widgets/CircleIndicator.dart';
import 'package:wechat/widgets/NumberPicker.dart';
import 'package:wechat/blocs/authentication/Bloc.dart';
class RegisterPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _RegisterPageState();
}
}
class _RegisterPageState extends State<RegisterPage>
with SingleTickerProviderStateMixin, WidgetsBindingObserver {
int currentPage = 0;
//fields for the form
File profileImageFile;
ImageProvider profileImage;
int age = 18;
final TextEditingController usernameController = TextEditingController();
var isKeyboardOpen =
false; //this variable keeps track of the keyboard, when its shown and when its hidden
PageController pageController =
PageController(); // this is the controller of the page. This is used to navigate back and forth between the pages
//Fields related to animation of the gradient
Alignment begin = Alignment.center;
Alignment end = Alignment.bottomRight;
//Fields related to animating the layout and pushing widgets up when the focus is on the username field
AnimationController usernameFieldAnimationController;
Animation profilePicHeightAnimation, usernameAnimation, ageAnimation;
FocusNode usernameFocusNode = FocusNode();
AuthenticationBloc authenticationBloc;
@override
void initState() {
initApp();
super.initState();
}
void initApp() async {
WidgetsBinding.instance.addObserver(this);
usernameFieldAnimationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 300));
profilePicHeightAnimation =
Tween(begin: 100.0, end: 0.0).animate(usernameFieldAnimationController)
..addListener(() {
setState(() {});
});
usernameAnimation =
Tween(begin: 50.0, end: 10.0).animate(usernameFieldAnimationController)
..addListener(() {
setState(() {});
});
ageAnimation =
Tween(begin: 80.0, end: 10.0).animate(usernameFieldAnimationController)
..addListener(() {
setState(() {});
});
usernameFocusNode.addListener(() {
if (usernameFocusNode.hasFocus) {
usernameFieldAnimationController.forward();
} else {
usernameFieldAnimationController.reverse();
}
});
pageController.addListener(() {
setState(() {
begin = Alignment(pageController.page, pageController.page);
end = Alignment(1 - pageController.page, 1 - pageController.page);
});
});
authenticationBloc = BlocProvider.of<AuthenticationBloc>(context);
authenticationBloc.state.listen((state) {
if (state is Authenticated) {
updatePageState(1);
}
});
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: onWillPop, //user to override the back button press
child: Scaffold(
resizeToAvoidBottomPadding: false,
// avoids the bottom overflow warning when keyboard is shown
body: SafeArea(
child: Stack(
children: <Widget>[
buildHome(),
BlocBuilder<AuthenticationBloc, AuthenticationState>(
builder: (context, state) {
if (state is AuthInProgress ||
state is ProfileUpdateInProgress) {
return buildCircularProgressBarWidget();
}
return SizedBox();
},
)
],
)),
));
}
buildHome() {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(begin: begin, end: end, colors: [
Palette.gradientStartColor,
Palette.gradientEndColor
])),
child: Stack(
alignment: AlignmentDirectional.bottomCenter,
children: <Widget>[
PageView(
controller: pageController,
physics: NeverScrollableScrollPhysics(),
onPageChanged: (int page) => updatePageState(page),
children: <Widget>[buildPageOne(), buildPageTwo()]),
Container(
margin: EdgeInsets.only(bottom: 30),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
for (int i = 0; i < 2; i++)
CircleIndicator(i == currentPage),
],
),
),
buildUpdateProfileButtonWidget()
]));
}
buildCircularProgressBarWidget() {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(begin: begin, end: end, colors: [
Palette.gradientStartColor,
Palette.gradientEndColor
])),
child: Container(
child: Center(
child: Column(children: <Widget>[
buildHeaderSectionWidget(),
Container(
margin: EdgeInsets.only(top: 100),
child: CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation<Color>(Palette.primaryColor)),
)
]),
)));
}
buildPageOne() {
return Column(
children: <Widget>[buildHeaderSectionWidget(), buildGoogleButtonWidget()],
);
}
buildHeaderSectionWidget() {
return Column(children: <Widget>[
Container(
margin: EdgeInsets.only(top: 250),
child: Image.asset(Assets.app_icon_fg, height: 100)),
Container(
margin: EdgeInsets.only(top: 30),
child: Text('WeChat Messenger',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 22)))
]);
}
buildGoogleButtonWidget() {
return Container(
margin: EdgeInsets.only(top: 100),
child: FlatButton.icon(
onPressed: () => BlocProvider.of<AuthenticationBloc>(context)
.dispatch(ClickedGoogleLogin()),
color: Colors.transparent,
icon: Image.asset(
Assets.google_button,
height: 25,
),
label: Text(
'Sign In with Google',
style: TextStyle(
color: Palette.primaryTextColorLight,
fontWeight: FontWeight.w800),
)));
}
buildPageTwo() {
return InkWell(
// to dismiss the keyboard when the user tabs out of the TextField
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
}, child: Container(
child: BlocBuilder<AuthenticationBloc, AuthenticationState>(
builder: (context, state) {
profileImage = Image.asset(Assets.user).image;
if (state is PreFillData) {
age = state.user.age != null ? state.user.age : 18;
profileImage = Image.network(state.user.photoUrl).image;
} else if (state is ReceivedProfilePicture) {
profileImageFile = state.file;
profileImage = Image.file(profileImageFile).image;
}
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: profilePicHeightAnimation.value),
buildProfilePictureWidget(),
SizedBox(
height: ageAnimation.value,
),
Text(
'How old are you?',
style: Styles.questionLight,
),
buildAgePickerWidget(),
SizedBox(
height: usernameAnimation.value,
),
Text(
'Choose a username',
style: Styles.questionLight,
),
buildUsernameWidget()
],
);
},
),
));
}
buildProfilePictureWidget() {
return GestureDetector(
onTap: pickImage,
child: CircleAvatar(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.camera,
color: Colors.white,
size: 15,
),
Text(
'Set Profile Picture',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 10,
),
)
],
),
backgroundImage: profileImage,
radius: 60,
),
);
}
buildAgePickerWidget() {
return Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
NumberPicker.horizontal(
initialValue: age,
minValue: 15,
maxValue: 100,
highlightSelectedValue: true,
onChanged: (num value) {
setState(() {
age = value;
});
}),
Text('Years', style: Styles.textLight)
],
);
}
buildUsernameWidget() {
return Container(
margin: EdgeInsets.only(top: 20),
width: 120,
child: TextField(
textAlign: TextAlign.center,
style: Styles.subHeadingLight,
focusNode: usernameFocusNode,
controller: usernameController,
decoration: Decorations.getInputDecoration(
hint: '@username', isPrimary: false),
));
}
updatePageState(index) {
if (currentPage == index) return;
if (index == 1)
pageController.nextPage(
duration: Duration(milliseconds: 300), curve: Curves.easeIn);
setState(() {
currentPage = index;
});
}
Future pickImage() async {
profileImageFile = await ImagePicker.pickImage(source: ImageSource.gallery);
authenticationBloc.dispatch(PickedProfilePicture(profileImageFile));
}
Future<bool> onWillPop() async {
if (currentPage == 1) {
//go to first page if currently on second page
pageController.previousPage(
duration: Duration(milliseconds: 300),
curve: Curves.easeOut,
);
return false;
}
return true;
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
usernameFieldAnimationController.dispose();
usernameFocusNode.dispose();
super.dispose();
}
///
/// This routine is invoked when the window metrics have changed.
///
@override
void didChangeMetrics() {
final value = MediaQuery.of(context).viewInsets.bottom;
if (value > 0) {
if (isKeyboardOpen) {
onKeyboardChanged(false);
}
isKeyboardOpen = false;
} else {
isKeyboardOpen = true;
onKeyboardChanged(true);
}
}
onKeyboardChanged(bool isVisible) {
if (!isVisible) {
FocusScope.of(context).requestFocus(FocusNode());
usernameFieldAnimationController.reverse();
}
}
navigateToHome() {
Navigator.push(
context,
SlideLeftRoute(page: ContactListPage()),
);
}
buildUpdateProfileButtonWidget() {
return AnimatedOpacity(
opacity: currentPage == 1 ? 1.0 : 0.0,
//shows only on page 1
duration: Duration(milliseconds: 500),
child: Container(
margin: EdgeInsets.only(right: 20, bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
FloatingActionButton(
onPressed: () => authenticationBloc.dispatch(SaveProfile(
profileImageFile, age, usernameController.text)),
elevation: 0,
backgroundColor: Palette.primaryColor,
child: Icon(
Icons.done,
color: Palette.accentColor,
),
)
],
)));
}
}```
from messio.
This should fix the issue. Added a null check for profile picture url. @Jukez17
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:image_picker/image_picker.dart';
import 'package:wechat/config/Assets.dart';
import 'package:wechat/config/Decorations.dart';
import 'package:wechat/config/Palette.dart';
import 'package:wechat/config/Styles.dart';
import 'package:wechat/config/Transitions.dart';
import 'package:wechat/pages/ContactListPage.dart';
import 'package:wechat/widgets/CircleIndicator.dart';
import 'package:wechat/widgets/NumberPicker.dart';
import 'package:wechat/blocs/authentication/Bloc.dart';
class RegisterPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _RegisterPageState();
}
}
class _RegisterPageState extends State<RegisterPage>
with SingleTickerProviderStateMixin, WidgetsBindingObserver {
int currentPage = 0;
//fields for the form
File profileImageFile;
ImageProvider profileImage;
int age = 18;
final TextEditingController usernameController = TextEditingController();
var isKeyboardOpen =
false; //this variable keeps track of the keyboard, when its shown and when its hidden
PageController pageController =
PageController(); // this is the controller of the page. This is used to navigate back and forth between the pages
//Fields related to animation of the gradient
Alignment begin = Alignment.center;
Alignment end = Alignment.bottomRight;
//Fields related to animating the layout and pushing widgets up when the focus is on the username field
AnimationController usernameFieldAnimationController;
Animation profilePicHeightAnimation, usernameAnimation, ageAnimation;
FocusNode usernameFocusNode = FocusNode();
AuthenticationBloc authenticationBloc;
@override
void initState() {
initApp();
super.initState();
}
void initApp() async {
WidgetsBinding.instance.addObserver(this);
usernameFieldAnimationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 300));
profilePicHeightAnimation =
Tween(begin: 100.0, end: 0.0).animate(usernameFieldAnimationController)
..addListener(() {
setState(() {});
});
usernameAnimation =
Tween(begin: 50.0, end: 10.0).animate(usernameFieldAnimationController)
..addListener(() {
setState(() {});
});
ageAnimation =
Tween(begin: 80.0, end: 10.0).animate(usernameFieldAnimationController)
..addListener(() {
setState(() {});
});
usernameFocusNode.addListener(() {
if (usernameFocusNode.hasFocus) {
usernameFieldAnimationController.forward();
} else {
usernameFieldAnimationController.reverse();
}
});
pageController.addListener(() {
setState(() {
begin = Alignment(pageController.page, pageController.page);
end = Alignment(1 - pageController.page, 1 - pageController.page);
});
});
authenticationBloc = BlocProvider.of<AuthenticationBloc>(context);
authenticationBloc.state.listen((state) {
if (state is Authenticated) {
updatePageState(1);
}
});
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: onWillPop, //user to override the back button press
child: Scaffold(
resizeToAvoidBottomPadding: false,
// avoids the bottom overflow warning when keyboard is shown
body: SafeArea(
child: Stack(
children: <Widget>[
buildHome(),
BlocBuilder<AuthenticationBloc, AuthenticationState>(
builder: (context, state) {
if (state is AuthInProgress ||
state is ProfileUpdateInProgress) {
return buildCircularProgressBarWidget();
}
return SizedBox();
},
)
],
)),
));
}
buildHome() {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(begin: begin, end: end, colors: [
Palette.gradientStartColor,
Palette.gradientEndColor
])),
child: Stack(
alignment: AlignmentDirectional.bottomCenter,
children: <Widget>[
PageView(
controller: pageController,
physics: NeverScrollableScrollPhysics(),
onPageChanged: (int page) => updatePageState(page),
children: <Widget>[buildPageOne(), buildPageTwo()]),
Container(
margin: EdgeInsets.only(bottom: 30),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
for (int i = 0; i < 2; i++)
CircleIndicator(i == currentPage),
],
),
),
buildUpdateProfileButtonWidget()
]));
}
buildCircularProgressBarWidget() {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(begin: begin, end: end, colors: [
Palette.gradientStartColor,
Palette.gradientEndColor
])),
child: Container(
child: Center(
child: Column(children: <Widget>[
buildHeaderSectionWidget(),
Container(
margin: EdgeInsets.only(top: 100),
child: CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation<Color>(Palette.primaryColor)),
)
]),
)));
}
buildPageOne() {
return Column(
children: <Widget>[buildHeaderSectionWidget(), buildGoogleButtonWidget()],
);
}
buildHeaderSectionWidget() {
return Column(children: <Widget>[
Container(
margin: EdgeInsets.only(top: 250),
child: Image.asset(Assets.app_icon_fg, height: 100)),
Container(
margin: EdgeInsets.only(top: 30),
child: Text('WeChat Messenger',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 22)))
]);
}
buildGoogleButtonWidget() {
return Container(
margin: EdgeInsets.only(top: 100),
child: FlatButton.icon(
onPressed: () => BlocProvider.of<AuthenticationBloc>(context)
.dispatch(ClickedGoogleLogin()),
color: Colors.transparent,
icon: Image.asset(
Assets.google_button,
height: 25,
),
label: Text(
'Sign In with Google',
style: TextStyle(
color: Palette.primaryTextColorLight,
fontWeight: FontWeight.w800),
)));
}
buildPageTwo() {
return InkWell(
// to dismiss the keyboard when the user tabs out of the TextField
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
}, child: Container(
child: BlocBuilder<AuthenticationBloc, AuthenticationState>(
builder: (context, state) {
profileImage = Image.asset(Assets.user).image;
if (state is PreFillData) {
age = state.user.age != null ? state.user.age : 18;
if (state.user.photoUrl != null) {
profileImage = Image.network(state.user.photoUrl).image;
}
} else if (state is ReceivedProfilePicture) {
profileImageFile = state.file;
profileImage = Image.file(profileImageFile).image;
}
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: profilePicHeightAnimation.value),
buildProfilePictureWidget(),
SizedBox(
height: ageAnimation.value,
),
Text(
'How old are you?',
style: Styles.questionLight,
),
buildAgePickerWidget(),
SizedBox(
height: usernameAnimation.value,
),
Text(
'Choose a username',
style: Styles.questionLight,
),
buildUsernameWidget()
],
);
},
),
));
}
buildProfilePictureWidget() {
return GestureDetector(
onTap: pickImage,
child: CircleAvatar(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.camera,
color: Colors.white,
size: 15,
),
Text(
'Set Profile Picture',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 10,
),
)
],
),
backgroundImage: profileImage,
radius: 60,
),
);
}
buildAgePickerWidget() {
return Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
NumberPicker.horizontal(
initialValue: age,
minValue: 15,
maxValue: 100,
highlightSelectedValue: true,
onChanged: (num value) {
setState(() {
age = value;
});
}),
Text('Years', style: Styles.textLight)
],
);
}
buildUsernameWidget() {
return Container(
margin: EdgeInsets.only(top: 20),
width: 120,
child: TextField(
textAlign: TextAlign.center,
style: Styles.subHeadingLight,
focusNode: usernameFocusNode,
controller: usernameController,
decoration: Decorations.getInputDecoration(
hint: '@username', isPrimary: false),
));
}
updatePageState(index) {
if (currentPage == index) return;
if (index == 1)
pageController.nextPage(
duration: Duration(milliseconds: 300), curve: Curves.easeIn);
setState(() {
currentPage = index;
});
}
Future pickImage() async {
profileImageFile = await ImagePicker.pickImage(source: ImageSource.gallery);
authenticationBloc.dispatch(PickedProfilePicture(profileImageFile));
}
Future<bool> onWillPop() async {
if (currentPage == 1) {
//go to first page if currently on second page
pageController.previousPage(
duration: Duration(milliseconds: 300),
curve: Curves.easeOut,
);
return false;
}
return true;
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
usernameFieldAnimationController.dispose();
usernameFocusNode.dispose();
super.dispose();
}
///
/// This routine is invoked when the window metrics have changed.
///
@override
void didChangeMetrics() {
final value = MediaQuery.of(context).viewInsets.bottom;
if (value > 0) {
if (isKeyboardOpen) {
onKeyboardChanged(false);
}
isKeyboardOpen = false;
} else {
isKeyboardOpen = true;
onKeyboardChanged(true);
}
}
onKeyboardChanged(bool isVisible) {
if (!isVisible) {
FocusScope.of(context).requestFocus(FocusNode());
usernameFieldAnimationController.reverse();
}
}
navigateToHome() {
Navigator.push(
context,
SlideLeftRoute(page: ContactListPage()),
);
}
buildUpdateProfileButtonWidget() {
return AnimatedOpacity(
opacity: currentPage == 1 ? 1.0 : 0.0,
//shows only on page 1
duration: Duration(milliseconds: 500),
child: Container(
margin: EdgeInsets.only(right: 20, bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
FloatingActionButton(
onPressed: () => authenticationBloc.dispatch(SaveProfile(
profileImageFile, age, usernameController.text)),
elevation: 0,
backgroundColor: Palette.primaryColor,
child: Icon(
Icons.done,
color: Palette.accentColor,
),
)
],
)));
}
}```
from messio.
Thank you it's working now :)
from messio.
Related Issues (20)
- Kotlin HOT 6
- Attachments not loading
- Stories HOT 1
- Execution failed for task ':app:processDebugGoogleServices'. HOT 11
- Tag Manager is not found HOT 2
- BLOC Building Issue HOT 3
- Notifications HOT 1
- Its showing googleservices.json file missing HOT 1
- Error when running code on master channel. HOT 3
- update bloc library HOT 1
- ChatRowWidget not displaying in HomePage and ConversationBottomSheet HOT 4
- Feature Suggestion: group chat HOT 1
- unable to pass sign in with google page HOT 1
- update failed HOT 1
- AuthenticationEvent build error with Equatable HOT 3
- Can the app be developed using WebRTC? HOT 2
- NumberPickerwidget and CircleAvtaar issues HOT 1
- Repo won't build/compile HOT 2
- Flutter run giving run HOT 1
- Tests are broken and so is the CI Pipeline
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from messio.