I am developing an android TV application using flutter. The remote control key which user is pressing, can be detected by RawKeyboardListener. But the focus is having an issue. Initially the focus will be in username field, then once editing complete it will move to password field, and then to the button. So OnTap mehthod will be triggered. After that the focus is only going to username button for up arrow key. No response for down arrow key. Also if the data entered again, even if the button is having focus, I am not able to enter it(onTap function is not working). Any idea??
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';
import 'package:google_fonts/google_fonts.dart';
class WelcomePage extends StatefulWidget {
#override
_WelcomePageState createState() => _WelcomePageState();
}
class _WelcomePageState extends State<WelcomePage> {
TextEditingController nameController = TextEditingController();
TextEditingController passwordController = TextEditingController();
var usermame, password = '';
late FocusNode _fs = FocusNode();
FocusNode? userNameFocusNode;
FocusNode? passwordFocusNode;
FocusNode? buttonFocusNode;
#override
void initState() {
super.initState();
_fs = FocusNode();
userNameFocusNode = FocusNode();
passwordFocusNode = FocusNode();
buttonFocusNode = FocusNode();
setFirstFocus();
}
setFirstFocus() {
if (userNameFocusNode == null) {
userNameFocusNode = FocusNode();
passwordFocusNode = FocusNode();
buttonFocusNode = FocusNode();
FocusScope.of(context).requestFocus(userNameFocusNode);
}
changeFocus(BuildContext context, FocusNode node) {
FocusScope.of(context).requestFocus(node);
}
}
#override
void dispose() {
super.dispose();
_fs.dispose();
userNameFocusNode?.dispose();
passwordFocusNode?.dispose();
buttonFocusNode?.dispose();
}
Widget _title() {
return RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: 'Login Page',
style: GoogleFonts.portLligatSans(
textStyle: Theme.of(context).textTheme.headline4,
fontSize: 50,
fontWeight: FontWeight.w700,
color: Colors.red,
),
);
}
Widget _usernameController() {
return Container(
width: MediaQuery.of(context).size.width / 2.5,
padding: const EdgeInsets.symmetric(vertical: 13),
alignment: Alignment.center,
child: TextFormField(
textInputAction: TextInputAction.done,
onEditingComplete: () {
userNameFocusNode!.unfocus();
FocusScope.of(context).requestFocus(passwordFocusNode);
},
textAlign: TextAlign.left,
focusNode: userNameFocusNode,
autofocus: true,
controller: nameController,
style:
const TextStyle(fontSize: 22.0, height: 1, color: Colors.white),
decoration: InputDecoration(
isDense: true,
prefixIcon: const Padding(
padding: EdgeInsets.only(left: 0),
child: Icon(
Icons.person,
size: 30,
color: Colors.white,
),
),
fillColor: Colors.white,
border: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.white, width: 5.00),
borderRadius: BorderRadius.circular(20.0),
),
labelText: ' Username',
labelStyle: const TextStyle(color: Colors.white, fontSize: 20),
)));
}
Widget _passwordController() {
return Container(
width: MediaQuery.of(context).size.width / 2.5,
padding: const EdgeInsets.symmetric(vertical: 13),
alignment: Alignment.center,
child: TextFormField(
textInputAction: TextInputAction.done,
onEditingComplete: () {
passwordFocusNode!.unfocus();
FocusScope.of(context).requestFocus(buttonFocusNode);
},
focusNode: passwordFocusNode,
obscureText: true,
textAlign: TextAlign.left,
autofocus: true,
controller: passwordController,
style:
const TextStyle(fontSize: 22.0, height: 1, color: Colors.white),
decoration: InputDecoration(
isDense: true,
prefixIcon: const Padding(
padding: EdgeInsets.only(left: 0),
child: Icon(
Icons.https,
size: 25,
color: Colors.white,
),
),
fillColor: Colors.white,
border: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.white, width: 5.00),
borderRadius: BorderRadius.circular(20.0),
),
labelText: ' Password',
labelStyle: const TextStyle(color: Colors.white, fontSize: 20),
)));
}
Widget _submitButton() {
return InkWell(
focusNode: buttonFocusNode,
onTap: () {
print('${nameController.text} + ${passwordController.text}');
},
child: Container(
width: MediaQuery.of(context).size.width / 2.5,
padding: const EdgeInsets.symmetric(vertical: 5),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(10)),
boxShadow: <BoxShadow>[
BoxShadow(
color: const Color(0xffdf8e33).withAlpha(100),
offset: const Offset(2, 4),
blurRadius: 8,
spreadRadius: 2)
],
color: Colors.white),
child: const Text(
'Login',
style: TextStyle(fontSize: 20, color: Colors.red),
),
),
);
}
void snackBardata(context, String actionMsg, var duration, Color snColour,
Color snDataColor) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
actionMsg,
style: TextStyle(
color: snDataColor,
fontSize: 20,
),
textAlign: TextAlign.center,
),
duration: Duration(seconds: 2),
backgroundColor: snColour,
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
));
}
void _handleKeyPressed(context, event) {
if (event is RawKeyDownEvent) {
switch (event.data.logicalKey.keyLabel.toString()) {
case 'Select':
{
_fs.unfocus();
print('select key pressed');
FocusScope.of(context).requestFocus(buttonFocusNode);
}
break;
case 'Arrow Down':
{
print('arrow down');
FocusScope.of(context).requestFocus(userNameFocusNode);
}
break;
case 'Arrow Left':
{}
break;
case 'Arrow Up':
{
print('arrow up');
FocusScope.of(context).requestFocus(passwordFocusNode);
}
break;
case 'Arrow Right':
{}
break;
default:
{
print('unknown--------------------------------');
}
break;
}
}
}
#override
Widget build(BuildContext context) {
return Shortcuts(
shortcuts: {
LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
},
child: Scaffold(
body: SingleChildScrollView(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20),
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
image: DecorationImage(
image: const AssetImage('assets/asset1.jpg'),
fit: BoxFit.fill,
colorFilter: ColorFilter.mode(
Colors.black.withOpacity(0.6), BlendMode.hardLight),
),
borderRadius: const BorderRadius.all(Radius.circular(0)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey.shade200,
offset: const Offset(2, 4),
blurRadius: 5,
spreadRadius: 2)
],
gradient: const LinearGradient(
begin: Alignment.topCenter, end: Alignment.bottomCenter,
// colors: [Colors.yellow, Colors.teal])),
colors: [Color(0xfffbb448), Color(0xffe46b10)])),
child: RawKeyboardListener(
focusNode: _fs,
onKey: (event) {
_handleKeyPressed(context, event);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_title(),
const SizedBox(
height: 20,
),
_usernameController(),
_passwordController(),
const SizedBox(
height: 20,
),
_submitButton(),
const SizedBox(
height: 20,
),
],
),
),
),
),
));
}
}
Related
I am new to flutter and dart , I have a problem where the parameter size cant have null value. I tried to search in the google the same problem that people had been facing and the solution is to add 'required'. i had tried that but the problem is in my body
Below here is my CustomCard().
import 'package:flutter/material.dart';
import '../../constants.dart';
class CustomCard extends StatefulWidget {
final Size size;
final Icon icon;
final String title, statusOn, statusOff;
const CustomCard(
{ required Key key,
required this.size,
required this.icon,
required this.title,
required this.statusOn,
required this.statusOff})
: super(key: key);
#override
_CustomCardState createState() => _CustomCardState();
}
class _CustomCardState extends State<CustomCard>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<Alignment> _animation;
bool isChecked = true;
void initState() {
_animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 350),
);
_animation = Tween<Alignment>(
begin: Alignment.bottomCenter, end: Alignment.topCenter)
.animate(
CurvedAnimation(
parent: _animationController,
curve: Curves.linear,
reverseCurve: Curves.easeInBack,
),
);
super.initState();
}
#override
Widget build(BuildContext context) {
return Container(
height: 140,
width: widget.size.width * 0.35,
decoration: BoxDecoration(
color: kBgColor,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 8,
offset: Offset(3, 3),
),
BoxShadow(
color: Colors.white,
blurRadius: 8,
offset: Offset(-3, -3),
),
],
),
child: Padding(
padding: EdgeInsets.all(15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
widget.icon,
AnimatedBuilder(
animation: _animationController,
builder: (animation, child) {
return GestureDetector(
onTap: () {
setState(() {
if (_animationController.isCompleted) {
_animationController.animateTo(20);
} else {
_animationController.animateTo(0);
}
isChecked = !isChecked;
});
},
child: Container(
height: 40,
width: 25,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.grey.shade50,
boxShadow: [
BoxShadow(
color: Colors.grey.shade200,
blurRadius: 0,
offset: Offset(3, 3),
),
BoxShadow(
color: Colors.black12,
blurRadius: 5,
offset: Offset(-3, -3),
),
],
),
child: Align(
alignment: _animation.value,
child: Container(
height: 15,
width: 15,
margin: EdgeInsets.symmetric(
vertical: 2, horizontal: 1),
decoration: BoxDecoration(
color: isChecked
? Colors.grey.shade300
: kGreenColor,
shape: BoxShape.circle,
),
),
),
),
);
},
),
],
),
SizedBox(height: 10),
Text(
widget.title,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: kBlueColor,
),
),
Text(
isChecked ? widget.statusOff : widget.statusOn,
style: TextStyle(
fontWeight: FontWeight.bold,
color: kGreenColor,
),
),
],
)),
);
}
}
And below here is my Body.dart
import 'package:flutter/material.dart';
import 'package:neew/constants.dart';
import 'package:neew/MainScreen/custom_card.dart';
class MainScreenBody extends StatefulWidget {
#override
_MainScreenBodyState createState() => _MainScreenBodyState();
}
class _MainScreenBodyState extends State<MainScreenBody> {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Padding(
padding: EdgeInsets.all(8.0),
child: Column(
children: [
SizedBox(height: size.height * 0.1),
Center(
child: Text(
"My Home",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 25,
),
),
),
SizedBox(height: size.height * 0.05),
CustomCard(
size: size,
icon: Icon(
Icons.home_outlined,
size: 55,
color: Colors.grey.shade400,
),
title: 'Entry',
statusOn: 'OPEN',
statusOff: 'LOCKED',
)
],
),
);
}
}
The error that i detect in body dart is in CustomCard().
Please help me, I will really appreciate it.
main.dart code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:toggle_switch/toggle_switch.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:mybmiapp/calculatedval.dart';
import 'package:mybmiapp/globals.dart' as globals;
import 'globals.dart' as globals;
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MaterialApp(
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
#override
_MyState createState() => _MyState();
}
class _MyState extends State<MyApp> {
bool _isBannerAdReady = false;
var msgController = TextEditingController();
var msgController2 = TextEditingController();
int genderindex = 0;
String text3 = "";
int maxLength = 10;
String kg = "0";
String p = "32";
double? n = null;
double? n2 = null;
double oldVal = 0.00;
double newVal = 0.00;
double oldVal2 = 0.00;
double newVal2 = 0.00;
#override
final heightcon = TextEditingController();
final weightcon = TextEditingController();
Widget build(BuildContext context) {
return MaterialApp(
theme: new ThemeData(backgroundColor: Colors.white),
home: Center(
child: Column(
children: <Widget>[
SizedBox(height: 50),
Material(
elevation: 30.0,
shadowColor: Colors.grey,
child: Container(
color: Colors.transparent,
width: 300,
child: SingleChildScrollView(
child: TextField(
controller: heightcon,
style: TextStyle(
color: Colors.black,
fontSize: 30,
),
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'textfield',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(0.0),
borderSide: BorderSide(
color: Colors.black,
width: 2.0,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(0.0),
borderSide: BorderSide(
color: Colors.black54,
width: 2.0,
),
),
),
onChanged: (heightval) { },
),
),
),
),
SizedBox(height: 50),
Material(
elevation: 30.0,
shadowColor: Colors.grey,
child: Container(
width: 300,
child: SingleChildScrollView(
child: TextField(
controller: weightcon,
style: TextStyle(
color: Colors.black,
fontSize: 30,
),
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'textfield',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(0.0),
borderSide: BorderSide(
color: Colors.black,
width: 2.0,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(0.0),
borderSide: BorderSide(
color: Colors.black54,
width: 2.0,
),
),
),
onChanged: (weightval) { },
),
),
),
),
SizedBox(height: 30),
SizedBox(
height: 57,
width: 150,
child: Material(
elevation: 30,
shadowColor: Colors.grey,
child: ElevatedButton(
style: ButtonStyle(
textStyle: MaterialStateProperty.all(TextStyle(
fontSize: 23,
color: Colors.white,
)),
backgroundColor:
MaterialStateProperty.all(Colors.red),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0),
side: BorderSide(color: Colors.white)))),
child: Text('button'),
onPressed: () {
print(genderindex);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondRoute()),
);
},
),
),
),
]),
));
// ],
//);
}
}
Next Screen (calculatedval.dart) code.
import 'package:flutter/material.dart';
import 'package:mybmiapp/globals.dart' as globals;
class SecondRoute extends StatelessWidget {
const SecondRoute({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text((globals.weightvalue).toStringAsFixed(2)),
),
body: Center(
child: Column(
children: <Widget>[
SizedBox(
height: 30,
),
Material(
elevation: 30,
shadowColor: Colors.grey,
child: Container(
alignment: Alignment.center,
height: 75,
width: 245,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey,
),
borderRadius: BorderRadius.circular(0.0),
),
child: Text(
"BMI IS " + (globals.bmi).toStringAsFixed(2),
style: TextStyle(
color: Colors.red,
fontSize: 33,
),
)),
),
SizedBox(
height: 30,
),
Material(
elevation: 30,
shadowColor: Colors.grey,
child: Container(
alignment: Alignment.center,
height: 80,
width: 245,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey,
),
borderRadius: BorderRadius.circular(0.0),
),
child: Text(
"BMI Level is " + globals.BmiLevel,
style: TextStyle(
color: Colors.black,
fontSize: 33,
),
)),
),
Text("only for 20 years plus")
])),
);
}
}
This is my screen output.
My console output
W/IInputConnectionWrapper( 3079): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper( 3079): requestCursorAnchorInfo on inactive InputConnection
2
W/IInputConnectionWrapper( 3079): getTextBeforeCursor on inactive InputConnection
D/InputConnectionAdaptor( 3079): The input method toggled cursor monitoring on
Use Scaffold or Material widget wrap your code and don't need to use MaterialApp I have updated the code little bit take a look
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MaterialApp(
theme: ThemeData(),
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
#override
_MyState createState() => _MyState();
}
class _MyState extends State<MyApp> {
bool _isBannerAdReady = false;
var msgController = TextEditingController();
var msgController2 = TextEditingController();
int genderindex = 0;
String text3 = "";
int maxLength = 10;
String kg = "0";
String p = "32";
double? n = null;
double? n2 = null;
double oldVal = 0.00;
double newVal = 0.00;
double oldVal2 = 0.00;
double newVal2 = 0.00;
#override
Widget build(BuildContext context) {
final heightcon = TextEditingController();
final weightcon = TextEditingController();
return Material(
child: Column(children: <Widget>[
const SizedBox(height: 50),
Material(
elevation: 30.0,
shadowColor: Colors.grey,
child: Container(
color: Colors.transparent,
width: 300,
child: SingleChildScrollView(
child: TextField(
controller: heightcon,
style: const TextStyle(
color: Colors.black,
fontSize: 30,
),
decoration: InputDecoration(
border: const OutlineInputBorder(),
hintText: 'textfield',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(0.0),
borderSide: const BorderSide(
color: Colors.black,
width: 2.0,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(0.0),
borderSide: const BorderSide(
color: Colors.black54,
width: 2.0,
),
),
),
onChanged: (heightval) {},
),
),
),
),
const SizedBox(height: 50),
Material(
elevation: 30.0,
shadowColor: Colors.grey,
child: Container(
width: 300,
child: SingleChildScrollView(
child: TextField(
controller: weightcon,
style: TextStyle(
color: Colors.black,
fontSize: 30,
),
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'textfield',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(0.0),
borderSide: BorderSide(
color: Colors.black,
width: 2.0,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(0.0),
borderSide: BorderSide(
color: Colors.black54,
width: 2.0,
),
),
),
onChanged: (weightval) {},
),
),
),
),
SizedBox(height: 30),
SizedBox(
height: 57,
width: 150,
child: Material(
elevation: 30,
shadowColor: Colors.grey,
child: ElevatedButton(
style: ButtonStyle(
textStyle: MaterialStateProperty.all(TextStyle(
fontSize: 23,
color: Colors.white,
)),
backgroundColor: MaterialStateProperty.all(Colors.red),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0),
side: BorderSide(color: Colors.white)))),
child: Text('button'),
onPressed: () {
print(genderindex);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
),
),
),
]),
);
//);
}
}
class SecondRoute extends StatelessWidget {
const SecondRoute({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('(globals.weightvalue).toStringAsFixed(2)'),
),
body: Center(
child: Column(children: <Widget>[
SizedBox(
height: 30,
),
Material(
elevation: 30,
shadowColor: Colors.grey,
child: Container(
alignment: Alignment.center,
height: 75,
width: 245,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey,
),
borderRadius: BorderRadius.circular(0.0),
),
child: Text(
"BMI IS " + ' (globals.bmi).toStringAsFixed(2)',
style: TextStyle(
color: Colors.red,
fontSize: 33,
),
)),
),
SizedBox(
height: 30,
),
Material(
elevation: 30,
shadowColor: Colors.grey,
child: Container(
alignment: Alignment.center,
height: 80,
width: 245,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey,
),
borderRadius: BorderRadius.circular(0.0),
),
child: Text(
"BMI Level is " + 'globals.BmiLevel',
style: TextStyle(
color: Colors.black,
fontSize: 33,
),
)),
),
Text("only for 20 years plus")
])),
);
}
}
I want to make the login button visible only when user enter the credentials in Text Form Field (Email and Password), otherwise login button should be invisible.
My LoginPage is designed as below:-
class _LoginPageState extends State<LoginPage> {
final _formKey = GlobalKey<FormState>();
late String _email, _password, error = '';
bool _obscureText = true;
bool _isKeyboardVisible = true;
bool _canShowButton = true;
final AuthenticationService _authenticationService = AuthenticationService();
_hideWidget(){
setState(() {
_canShowButton = !_canShowButton;
});
}
_toggle() {
setState(() {
_obscureText = !_obscureText;
});
}
_submit() async {
if(_formKey.currentState!.validate()){
_formKey.currentState?.save();
dynamic result = await _authenticationService.loginWithEmail(email: _email, password: _password);
if(result == null) {
setState(() => error = 'Es wurde kein Benutzerkonto gefunden. Bitte erstellen Sie zuerst das Konto');
} else {
Navigator.pushNamed(context, HomePage.id);
}
print(_email);
print(_password);
}
}
#override
void initState() {
super.initState();
}
#override
void dispose() {
super.dispose();
}
#override
Widget build(BuildContext context) {
_isKeyboardVisible = MediaQuery.of(context).viewInsets.bottom != 0;
if(!_isKeyboardVisible) {
return GestureDetector(
onTap: (){
FocusScopeNode currentFocus = FocusScope.of(context);
if(!currentFocus.hasPrimaryFocus){
currentFocus.unfocus();
}
},
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Column(
children: [
Container(
margin: EdgeInsets.only(top: 20),
alignment: Alignment.center,
child: Text("Bitte Melde Dich an",
style: TextStyle(color: color, fontWeight: FontWeight.bold, fontSize: 28),),
),
Form(
key: _formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0, vertical: 10.0),
child: Padding(
padding: EdgeInsets.only(left: 5.0, right: 5.0, top: 5.0),
child: SizedBox(
child: TextFormField(
autofocus: false,
decoration: InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(borderRadius: BorderRadius.all(
const Radius.circular(10.0),
)
),
filled: true,
fillColor: Colors.white,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: color, width: 2.0),
borderRadius: BorderRadius.circular(10.0)
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: color, width: 2.0),
borderRadius: BorderRadius.circular(10.0)
)
),
validator: (input) => !EmailValidator.validate(input!, true)
? 'Please enter valid email'
: null,
onSaved: (input) => _email = input!,
),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 30.0, vertical: 10.0
),
child: Padding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 5, bottom: 5),
child: Stack(
alignment: const Alignment(0, 0),
children: <Widget>[
TextFormField(
autofocus: false,
decoration: InputDecoration(
labelText: 'Password',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
const Radius.circular(10.0)
)
),
filled: true,
fillColor: Colors.white,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: color, width: 2.0),
borderRadius: BorderRadius.circular(10.0)
),
suffixIcon: IconButton(
onPressed: (){
_toggle();
},
icon: Icon(_obscureText ? Icons.visibility : Icons.visibility_off)
)
),
validator: (input) => input!.length < 6
? 'Must be at least 6 characters': null,
onSaved: (input) => _password = input!,
obscureText: _obscureText,
)
],
),
),
),
Padding(
padding: const EdgeInsets.only(top: 10),
child: Container(
width: MediaQuery.of(context).size.width - 70,
height: MediaQuery.of(context).size.height * 0.09,
child: !_canShowButton ? SizedBox.shrink() : TextButton(
style: TextButton.styleFrom(
primary: Colors.white,
backgroundColor: color,
elevation: 5,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0))
),
onPressed: () {
_hideWidget();
},
child: Text('Anmelden')),
),
),
],
),
)
],
),
),
),
);
} else {
return GestureDetector(
onTap: (){
FocusScopeNode currentFocus = FocusScope.of(context);
if(!currentFocus.hasPrimaryFocus){
currentFocus.unfocus();
}
},
child: Scaffold(
resizeToAvoidBottomInset: false,
body: SingleChildScrollView(
child: Column(
children: [
Container(
margin: EdgeInsets.only(top: 60),
alignment: Alignment.center,
child: Text(
'Login Credentials',
style: TextStyle(color: color, fontWeight: FontWeight.bold, fontSize: 28),
overflow: TextOverflow.clip,
)
),
Container(
margin: EdgeInsets.only(top: 20),
alignment: Alignment.center,
child: Text("Bitte Melde Dich an",
style: TextStyle(color: color, fontWeight: FontWeight.bold, fontSize: 28),),
),
Form(
key: _formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0, vertical: 10.0),
child: Padding(
padding: EdgeInsets.only(left: 5.0, right: 5.0, top: 5.0),
child: SizedBox(
/*height: _animation.value,*/
child: TextFormField(
decoration: InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(borderRadius: BorderRadius.all(
const Radius.circular(10.0),
)
),
filled: true,
fillColor: Colors.white,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: color, width: 2.0),
borderRadius: BorderRadius.circular(10.0)
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: color, width: 2.0),
borderRadius: BorderRadius.circular(10.0)
)
),
// focusNode: _focusNode,
validator: (input) => !EmailValidator.validate(input!, true) ? 'Please provide valid email':null,
onSaved: (input) => _email = input!,
),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 30.0, vertical: 10.0
),
child: Padding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 5, bottom: 5),
child: Stack(
alignment: const Alignment(0, 0),
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'Password',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
const Radius.circular(10.0)
)
),
filled: true,
fillColor: Colors.white,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: color, width: 2.0),
borderRadius: BorderRadius.circular(10.0)
),
suffixIcon: IconButton(
onPressed: (){
_toggle();
},
icon: Icon(_obscureText ? Icons.visibility : Icons.visibility_off)
)
),
validator: (input) => input!.length < 6
? 'Must be at least 6 characters': null,
onSaved: (input) => _password = input!,
obscureText: _obscureText,
)
],
),
),
),
],
),
)
],
),
),
),
);
In short I have added the bool variable and function as below. After that in onPressed of login Button I called _hideWidget().
bool _canShowButton = true;
_hideWidget(){
setState(() {
_canShowButton = !_canShowButton;
});
Padding(
padding: const EdgeInsets.only(top: 10),
child: Container(
width: MediaQuery.of(context).size.width - 70,
height: MediaQuery.of(context).size.height * 0.09,
child: !_canShowButton ? SizedBox.shrink() : TextButton(
style: TextButton.styleFrom(
primary: Colors.white,
backgroundColor: color,
elevation: 5,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0))
),
onPressed: () {
_hideWidget();
},
child: Text('Anmelden')),
),
),
What I have achieved is: The Login Button is there on the page and when I click on TextFormField it gets disappear.
Want to achieve: Login Button should be invisible on the screen and when user enters the credentials after that it should appear.
Is there any way to achieve this??
This is how you can tell if there's data in the textfield or not, if there is it'll change isFilled to true.
bool isFilled = false;
TextFormField(
onChanged: (val) {
setState(() {
(val.isEmpty) ? isFilled = false : isFilled = true;
});
},
)
Now to show the button when there's data in the textfield you can use ternary operator.
(isFilled)?TextButton(onPressed: (){}, child: Container()) : Container()
Just switch TextButton with your button. Ternary operators work like so
(condition) ? (do if true) : (do if false)
in this case, you're showing the button if isFilled = true, and an empty container if not
Well the simplest way of implementing this is to add a TextEdittingController to each Textfield and then render the button only when the TextEdittingController.tex is not empty,when it's empty you can render an empty container otherwise render the button,use a simple tenary operator to do this
I have a problem with My Flutter Project...
The Keyboar always Appear and Suddenly Disappear when I try to click the TextField..
But It's only happen in this Page...
here is the Code
import 'dart:io';
import 'package:chat_chat_8/service/auth.dart';
import 'package:chat_chat_8/theme/style.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:image_picker/image_picker.dart';
class ProfilePage extends StatefulWidget {
const ProfilePage({Key? key}) : super(key: key);
#override
State<ProfilePage> createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> {
TextEditingController txt_name = new TextEditingController();
TextEditingController txt_status = new TextEditingController();
final FirebaseAuth _auth = FirebaseAuth.instance;
ImagePicker picker = ImagePicker();
var stateCondition;
var profileImage;
File? uriImage;
#override
Widget build(BuildContext context) {
Widget PhotoProfile(String userImage) {
if (profileImage == null) {
profileImage = userImage;
}
return Container(
height: 197.53,
width: 197.53,
decoration: BoxDecoration(
image: DecorationImage(
image: profileImage == userImage
? NetworkImage(profileImage.toString())
: FileImage(uriImage as File) as ImageProvider,
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(150),
border: Border.all(
width: 2,
color: Purple_sub,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
height: 42.18,
width: 42.18,
child: ElevatedButton(
onPressed: () async {
XFile? image =
await picker.pickImage(source: ImageSource.gallery);
if (image != null) {
setState(() {
profileImage = File(image.path).toString();
uriImage = File(image.path);
});
}
},
style: ElevatedButton.styleFrom(
primary: Purple_sub,
shadowColor: Colors.black54,
padding: EdgeInsets.all(0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
Icons.mode_edit_outline_outlined,
color: Colors.white,
size: 25,
),
],
)),
)
],
));
}
Widget ConditionComboBox(var userCondition) {
if (stateCondition == null) {
stateCondition = userCondition;
}
return Container(
height: 55,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: Text_Field,
),
),
child: Padding(
padding: const EdgeInsets.all(13),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
focusColor: Colors.white,
value: stateCondition,
//elevation: 5,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xff595555),
fontSize: 24,
),
//iconEnabledColor: Colors.black,
items: <String>[
'Available',
'Unavailable',
'Busy',
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: TextStyle(
color: Color(0xff595555),
),
),
);
}).toList(),
hint: Text(
"Select your condition",
style: TextStyle(
color: Color(0xff595555),
fontSize: 14,
fontWeight: FontWeight.w500),
),
onChanged: (value) {
setState(() {
stateCondition = value;
});
},
),
),
),
);
}
Widget TextProfile(String userName, String userStatus) {
txt_name.text = userName;
txt_status.text = userStatus;
return Column(
children: <Widget>[
Container(
height: 56.67,
child: TextFormField(
controller: txt_name,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xff595555),
fontSize: 24,
),
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Text_Field),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Purple_sub,
),
),
),
),
),
SizedBox(
height: 18.19,
),
Container(
height: 56.67,
child: TextFormField(
controller: txt_status,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xff595555),
fontSize: 24,
),
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Text_Field),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Purple_sub,
),
),
),
),
),
],
);
}
Widget SaveButton() {
return Container(
height: 50,
width: MediaQuery.of(context).size.width,
child: ElevatedButton(
onPressed: () {
AuthMethod().updateUser(
_auth.currentUser!.uid,
txt_name.text,
uriImage != null ? uriImage as File : null,
txt_status.text,
stateCondition,
);
},
style: ElevatedButton.styleFrom(
primary: Purple_sub,
),
child: Text(
'Complete',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.w700,
),
),
),
);
}
return Scaffold(
body: SingleChildScrollView(
child: Padding(
padding: MediaQuery.of(context).viewInsets,
child: Container(
padding: EdgeInsets.only(top: 51.32),
margin: EdgeInsets.symmetric(
horizontal: 22.55,
),
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection("Users")
.doc(_auth.currentUser!.uid)
.snapshots(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Container();
}
return Container(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/logo_app.png',
height: 50,
width: 50.64,
),
SizedBox(
width: 11.25,
),
Text(
'Profile',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 27,
),
)
],
),
SizedBox(
height: 44,
),
PhotoProfile(
snapshot.data.data()["userImage"],
),
SizedBox(
height: 54.83,
),
TextProfile(
snapshot.data.data()["userName"],
snapshot.data.data()["userStatus"],
),
SizedBox(
height: 18.19,
),
ConditionComboBox(
snapshot.data.data()["userCondition"],
),
SizedBox(
height: 100.98,
),
SaveButton(),
SizedBox(
height: 65.79,
),
],
),
);
},
),
),
),
),
);
}
}
I've tries many ways to solve this matter such as like in google
but no works at all
And my senior also can not solve this problem
I hope Some body can help me to Solve this Problem
Thx
I think you have to get all of the widgets (except the scaffold) out of the build method.
In flutter, I want to make an application that scans qr code and display the qr text.
I have two buttons, which are done, scan again.
And how to put that 2 button, bottom of that scan area. If i try to put that button inside expanded layer, it looks all red
Here is the code & screenshot.
How can i solve this ?
import 'package:flutter/material.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:qr_code_scanner/qr_scanner_overlay_shape.dart';
void main() => runApp(MaterialApp(home: QRSCAN()));
const flash_on = "FLASH ON";
const flash_off = "FLASH OFF";
const front_camera = "FRONT CAMERA";
const back_camera = "BACK CAMERA";
class QRSCAN extends StatefulWidget {
const QRSCAN({
Key key,
}) : super(key: key);
#override
State<StatefulWidget> createState() => _QRSCANState();
}
class _QRSCANState extends State<QRSCAN> {
bool Done_Button = false;
var qrText = "";
QRViewController controller;
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.blueAccent),
onPressed: () {
Navigator.pop(context);
controller?.pauseCamera();
},
),
elevation: 0.0,
backgroundColor: Colors.white,
actions: <Widget>[
IconButton(
icon: Icon(Icons.help_outline, color: Colors.grey,),
onPressed: () {},
),
],
),
body: Column(
children: <Widget>[
Expanded(
child: QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.blueAccent,
borderRadius: 10,
borderLength: 130,
borderWidth: 5,
overlayColor: Color(0xff010040),
),
),
flex: 4,
),
Expanded(
child: FittedBox(
fit: BoxFit.contain,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text("$qrText", style: TextStyle(color: Colors.black,),),
InkWell(
onTap: () async {
Navigator.pop(context);
},
child: Container(
width: 100.0,
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(colors: [
Color(0xFF1E75BB),
Color(0xFF1EEABB),
])),
child: Center(
child: Text(
'Done',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontFamily: 'Play',
),
),
),
),
),
SizedBox(
height: 25,
),
InkWell(
onTap: () async {
setState(() {
qrText = "";
controller?.resumeCamera();
Done_Button = false;
});
},
child: Container(
width: 100.0,
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(colors: [
Color(0xFF1E75BB),
Color(0xFF1EEABB),
])),
child: Center(
child: Text(
'Again',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontFamily: 'Play',
),
),
),
),
),
],
),
),
flex: 1,
),
],
),
);
}
_isFlashOn(String current) {
return flash_on == current;
}
_isBackCamera(String current) {
return back_camera == current;
}
void _onQRViewCreated(QRViewController controller) {
this.controller = controller;
controller.scannedDataStream.listen((scanData) {
setState(() {
qrText = scanData;
controller?.pauseCamera();
Done_Button = true;
});
});
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
}
you can refactor your code as follows
` Column(children: <Widget>[
/* QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.blueAccent,
borderRadius: 10,
borderLength: 130,
borderWidth: 5,
overlayColor: Color(0xff010040),
),
),*/
SizedBox(height:5),
Center(
child: Container(height: 100, color: Colors.white, width: 100),
),
Text(
"$qrText",
style: TextStyle(
color: Colors.black,
),
),
InkWell(
onTap: () async {
Navigator.pop(context);
},
child: Container(
width: 100.0,
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(colors: [
Color(0xFF1E75BB),
Color(0xFF1EEABB),
])),
child: Center(
child: Text(
'Done',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontFamily: 'Play',
),
),
),
),
),
SizedBox(
height: 25,
),
InkWell(
onTap: () async {
setState(() {
qrText = "";
// controller?.resumeCamera();
// Done_Button = false;
});
},
child: Container(
width: 100.0,
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(colors: [
Color(0xFF1E75BB),
Color(0xFF1EEABB),
])),
child: Center(
child: Text(
'Again',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontFamily: 'Play',
),
),
),
),
),
]),
);`