Reputation: 1
I am a Flutter beginner and I am currently trying to implement a login screen which must satisfy to the following requirements:
Here are wireframes that describe what I would like to achieve with Flutter:
Is this feasible with Flutter? Currently here is what I have attempted:
import 'package:flutter/material.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isSoftKeyboardOpen;
@override
void initState() {
super.initState();
var keyboardVisibilityController = KeyboardVisibilityController();
_isSoftKeyboardOpen = keyboardVisibilityController.isVisible;
// Subscribe
keyboardVisibilityController.onChange.listen((bool visible) {
setState(() {
_isSoftKeyboardOpen = visible;
});
});
}
@override
Widget build(BuildContext context) {
var mAppBar = AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
);
return Scaffold(
appBar: mAppBar,
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: LayoutBuilder(
builder: (context, constraint) {
return SingleChildScrollView(
padding: EdgeInsets.only(left: 16, right: 16),
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraint.maxHeight),
child: LayoutBuilder(
builder: (containerContext, constraint) {
return Container(
height: MediaQuery.of(containerContext).size.height - mAppBar.preferredSize.height - MediaQuery.of(context).padding.top,
color: Colors.green,
child: Column(
children: <Widget> [
Expanded(
flex: _isSoftKeyboardOpen ? 0 : 1,
child: Column(
children: <Widget> [
TextFormField(
decoration: InputDecoration(
labelText: "Username",
),
),
TextFormField(
decoration: InputDecoration(
labelText: "Password",
),
)
],
),
),
ElevatedButton(onPressed: null, child: Text("Sign in")
),
],
),
);
}
),
)
);
},
)
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
As you can see when the soft keyboard opens, the screen scrolls but there is unnecessary space below the button (which is the last element of the screen). Is there a way for me to change the screen height dynamically in my code to achieve what I want? Or is there another way to implement the sign in screen which fulfills my requirements.
Upvotes: 0
Views: 612
Reputation: 599
Hi @Jane you can achieve the desired output using the below code.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LoginPage(),
);
}
}
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('SIGN IN'),
),
body: LayoutBuilder(builder: (context, constraint) {
return ListView(
shrinkWrap: true,
padding: const EdgeInsets.all(16),
children: [
GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: Container(
color: Colors.white,
height: constraint.maxHeight -
32, // -32 to remove vertical padding
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: [
Column(
children: [
TextFormField(
decoration: InputDecoration(
labelText: "Username",
),
),
TextFormField(
decoration: InputDecoration(
labelText: "Password",
),
),
],
),
ElevatedButton(onPressed: null, child: Text("Sign in"))
],
),
),
),
],
);
}));
}
}
Also, try to use plugins only in dire situations when you can't achieve a particular task with flutter available resources.
Upvotes: 0
Reputation: 1619
You can user the below widget to gain your requirements:
return KeyboardVisibilityBuilder(
builder: (context, child, isKeyboardVisible) {
if (isKeyboardVisible) {
// build layout for visible keyboard
} else {
// build layout for invisible keyboard
}
},
child: child, // this widget goes to the builder's child property. Made for better performance.
);
Upvotes: 1