Is there solution for images disapearing in flutter after hot reload? - flutter

I'm creating a new flutter app, and i want a solution for the images disappearing problem after flutter hot reload.
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
#override
State <StatefulWidget> createState() {
return HomeState();
}
}
class HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.redAccent,
title: Text('Login Page '),
),
body: Container(
padding: EdgeInsets.all(33.0),
alignment: Alignment.center,
child: Column(
children: <Widget>[
Image.asset('img/userlogin.png'),
Container(
child: Column(
children: <Widget>[
TextField(
controller: null,
decoration: InputDecoration(
icon: Icon(Icons.person), hintText: 'Yor Name'),
)
],
),
)
],
),
),
);
}
}

You could pre-cache the image using preCacheImage function inside you initState methods
like so:
class HomeState extends State<Home> {
#override
void initState() {
precacheImage(new AssetImage('img/userlogin.png'));
super.initState();
}
#override
Widget build(BuildContext context) {
// Widgets...
}
}

Related

How to set value for a text field based on value from another text field in Flutter automatically?

I am trying to build a form for data capture, I have some instances where some form section have duplicate textfields. I want to reduce redundancy and copy data from the previously keyed in textfields like section 1 and have it appear on the duplicate textfield fields in section 20 of the same form. I have only managed the example below where you have to click on a button for the textfield to be pushed to another field. The code
import "package:flutter/material.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Home(),
);
}
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final titleController = TextEditingController();
String text = "No Value Entered";
void _setText() {
setState(() {
text = titleController.text;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('GeeksforGeeks'),
backgroundColor: Colors.green,
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(15),
child: TextField(
decoration: InputDecoration(labelText: 'Title'),
controller: titleController,
),
),
SizedBox(
height: 8,
),
RaisedButton(
onPressed: _setText,
child: Text('Submit'),
elevation: 8,
),
SizedBox(
height: 20,
),
Text(text),
],
),
);
}
}
How can I achieve this by passing one textfield value to another textfield without pressing the submit button and not changing the state of the entire form?
You just need to add listeners to the respective textControllers as below:
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final titleController = TextEditingController();
final titleController2 = TextEditingController();
String text = "No Value Entered";
#override
void initState() {
super.initState();
titleController.addListener(() {
setState(() {
titleController2.text = titleController.text;
});
});
titleController2.addListener(() {
setState(() {
titleController.text = titleController2.text;
});
});
}
#override
void dispose() {
titleController.dispose();
titleController2.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('GeeksforGeeks'),
backgroundColor: Colors.green,
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(15),
child: TextField(
decoration: InputDecoration(labelText: 'Title'),
controller: titleController,
),
),
Padding(
padding: const EdgeInsets.all(15),
child: TextField(
decoration: InputDecoration(labelText: 'Title'),
controller: titleController2,
),
),
SizedBox(
height: 8,
),
// RaisedButton(
// onPressed: _setText,
// child: Text('Submit'),
// elevation: 8,
// ),
// SizedBox(
// height: 20,
// ),
// Text(text),
],
),
);
}
}
Register a listener on the TextEditingController on the initState method.
Then dispose of it on the dispose method.
Like this:
import "package:flutter/material.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Home(),
);
}
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final TextEditingController titleController = TextEditingController();
String text = "No Value Entered";
#override
void initState() {
titleController.addListener(_setText);
super.initState();
}
#override
void dispose() {
titleController.dispose();
super.dispose();
}
void _setText() {
setState(() {
text = titleController.text;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('GeeksforGeeks'),
backgroundColor: Colors.green,
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(15),
child: TextField(
decoration: InputDecoration(labelText: 'Title'),
controller: titleController,
),
),
SizedBox(
height: 8,
),
RaisedButton(
onPressed: _setText,
child: Text('Submit'),
elevation: 8,
),
SizedBox(
height: 20,
),
Text(text),
],
),
);
}
}

flutter: How to detect keyboard?

I want detect Keyboard. And want to show it other text when keyboard is visible or unvisible.
But my code is not working.
This is my code.
class Search extends StatefulWidget {
#override
_SearchState createState() => _SearchState();
}
class _SearchState extends State<Search> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.white,
child: Column(
children: [
Expanded(
flex: 1,
child: ListView(
children: [
MediaQuery.of(context).viewInsets.bottom !=0 ? Center(child: Text("true"),) : Center(child: Text("false"),)
],
),
)
],
),
),
);
}
}
As #Anas Mohammed mentioned, you can do it with the keyboard_visibility package. Here is a total example:
import 'package:flutter/material.dart';
import 'package:keyboard_visibility/keyboard_visibility.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Keyboard visibility example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: KeyboardVisibilityExample(),
);
}
}
class KeyboardVisibilityExample extends StatefulWidget {
KeyboardVisibilityExample({Key key}) : super(key: key);
#override
_KeyboardVisibilityExampleState createState() => _KeyboardVisibilityExampleState();
}
class _KeyboardVisibilityExampleState extends State<KeyboardVisibilityExample> {
KeyboardVisibilityNotification _keyboardVisibility = new KeyboardVisibilityNotification();
int _keyboardVisibilitySubscriberId;
bool _keyboardState;
#protected
void initState() {
super.initState();
_keyboardState = _keyboardVisibility.isKeyboardVisible;
_keyboardVisibilitySubscriberId = _keyboardVisibility.addNewListener(
onChange: (bool visible) {
setState(() {
_keyboardState = visible;
});
},
);
}
#override
void dispose() {
_keyboardVisibility.removeListener(_keyboardVisibilitySubscriberId);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Keyboard visibility example'),
),
body: Center(
child: Padding(
padding: EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'Input box for keyboard test',
),
),
Container(height: 60.0),
Text(
'The current state of the keyboard is: ' + (_keyboardState ? 'VISIBLE' : 'NOT VISIBLE'),
),
],
)
),
),
);
}
}
for to visible keyboard this code:
FocusScope.of(context).requestFocus();
for to unvisible keyboard this code:
FocusScope.of(context).unfocus();
for check visiblity of keyboard :
FocusScope.of(context).hasFocus
your provided code:
class Search extends StatefulWidget {
#override
_SearchState createState() => _SearchState();
}
class _SearchState extends State<Search> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.white,
child: Column(
children: [
Expanded(
flex: 1,
child: ListView(
children: [
FocusScope.of(context).hasFocus ? Center(child: Text("true"),) : Center(child: Text("false"),)
],
),
)
],
),
),
);
}
}
Accepted answer contains old library not support null safety, you can use this one flutter_keyboard_visibility which support null safety.

how do I listen isDrawerOpen on Flutter?

I want to hide some widgets when the drawer opens. (it's mean when user open drawer then I need to hide some widgets)
Currently, I am using
if(!_scaffoldKey.currentState.isDrawerOpen)
//hide widget
But this is not listen. Is there any way to do listen drawer callbacks?
There is no callback mechanism till now in flutter which gives events for Drawer(), but still we can apply a good solution for it.
I divided the solution using two stateful widgets,
HomeScreen (Main Widget)
MyDrawer (Drawer Widget)
1. HomeScreen:
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
bool _isDrawerOpen = false;
void drawerCallback(bool isOpen) {
print('Drawer Status:' + isOpen.toString());
// Based on the bool value set visibility of your widget
WidgetsBinding.instance.addPostFrameCallback((_){
setState(() {
_isDrawerOpen = isOpen;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(title: Text('Nav Sample App')),
body: _isDrawerOpen
? Align(alignment: Alignment.centerRight, child: Text('Drawer Open'))
: Align(alignment: Alignment.centerRight, child: Text('Drawr Close')),
drawer: MyDrawer(drawerCallback));
}
}
Above you can see that based on _isDrawerOpen we are setting widgets in the body with the ternary operator.
2. MyDrawer()
class MyDrawer extends StatefulWidget {
final Function _drawerCallback;
MyDrawer(this._drawerCallback);
#override
_MyDrawerState createState() => _MyDrawerState();
}
class _MyDrawerState extends State<MyDrawer> {
#override
void initState() {
super.initState();
widget._drawerCallback(true);
}
#override
void dispose() {
widget._drawerCallback(false);
super.dispose();
}
#override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(color: Colors.blue),
),
Text("Drawer Item 1"),
Text("Drawer Item 2"),
],
),
);
}
}
Heart of the logic is applied in initState() and dispose() callbacks where we are returning status.
You can use the onTap() function for drawers using a ListView:
Drawer(
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawers'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Drawer 1'),
onTap: () {
// Insert code to hide or delete your desired widget
// Then close the drawer
Navigator.pop(context);
},
),
],
),
),//drawer

Geting inserted data of text field into a listview in the previous screen

I am new in flutter , i am trying to get the data inserted in the text field into a list and show this list into the previous screen.
I had made two screen in first screen we navigate to the first screen and on second screen i have three text fields from witch i want to fetch the data into a new list and show this list into the previous screen someone if getting what i am trying to say please help thanks in advance.
this is my main page
import "package:flutter/material.dart";
import 'second.dart';
void main() {
runApp(new MaterialApp(home: new MyApp(),
routes: <String, WidgetBuilder>{
"/Data": (BuildContext context) => new Data()
}));
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("NOTE bOOK"),
),
body: new Container(
),
floatingActionButton: new FloatingActionButton(
onPressed: () {
Navigator.of(context).pushNamed("/Data");
},
child: new Icon(Icons.add))),
);
}
this is my second page
import 'package:flutter/material.dart';
import 'package:flutter_apptasktwo/main.dart';
class Data extends StatefulWidget {
#override
_DataState createState() => _DataState();
}
class _DataState extends State<Data> {
List<String> messages = List();
var _textController = new TextEditingController();
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Color(0xff84FFFF),
appBar: AppBar(
title: Text("List"),
),
body: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new
TextField(
controller : _textController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Hint text '
)
),
new
TextField(
controller : _textController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Hint date'
)
),
new
TextField(
controller : _textController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Hint discription '
),
),
FloatingActionButton(
onPressed: () {
Navigator.pop(context ,MyApp());
},
child: Icon(Icons.save),
backgroundColor: Colors.green,
),
],
)
),
);
}
}
}
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
String returned = 'Retuned text will appear here..';
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Returning Data Demo'),
),
body: Center(
child: Column(children: [
Text(returned, style: TextStyle(color: Colors.black)),
RaisedButton(
onPressed: () async {
var someValue = await Navigator.of(context)
.push(MaterialPageRoute(builder: (con) => SelectionScreen()));
print(someValue);
if (someValue != null && someValue.toString().isNotEmpty) {
setState(() {
returned = someValue.toString();
});
}
},
child: Text('Get Values', style: TextStyle(color: Colors.white)),
)
])),
);
}
}
class SelectionScreen extends StatefulWidget {
#override
_SelectionScreenState createState() => _SelectionScreenState();
}
class _SelectionScreenState extends State<SelectionScreen> {
TextEditingController c1, c2, c3;
//and son on....
#override
void initState() {
super.initState();
c1 = TextEditingController();
c2 = TextEditingController();
c3 = TextEditingController();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Pick an option'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: c1,
),
TextField(
controller: c2,
),
TextField(
controller: c3,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
onPressed: () {
// Close the screen and return "Nope!" as the result.
Navigator.pop(context, [c1.text, c2.text, c3.text]);
},
child: Text('Submit'),
),
)
],
),
),
);
}
}

flutter's AutomaticKeepAliveClientMixin doesn't keep the page state after navigator.push

was testing AutomaticKeepAliveClientMixin and run into an issue,
page loses state after navigator.push
anyone knows this issue? any workarounds? be glad for any info, cheers
my goal is to keep the page state
steps to reproduce: open app click PageOne's push-button then go back swipe right and left and the page loses state
image
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: MyApp()));
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
initialIndex: 0,
length: 2,
child: Scaffold(
body: TabBarView(
children: <Widget>[Page1(), Page2()],
),
bottomNavigationBar: Material(
child: TabBar(
labelColor: Colors.black,
tabs: <Widget>[
Tab(
icon: Icon(Icons.check),
),
Tab(
icon: Icon(Icons.check),
),
],
),
),
),
),
);
}
}
class Page1 extends StatefulWidget {
#override
Page1State createState() {
return new Page1State();
}
}
class Page1State extends State<Page1> with AutomaticKeepAliveClientMixin {
#override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
Container(
height: 300,
color: Colors.orange,
),
Container(
height: 300,
color: Colors.pink,
),
Container(
height: 300,
color: Colors.yellow,
child: Center(
child: Container(height: 26,
child: MaterialButton(
color: Colors.blue,
child:
Text('clicking this and back then swipe => page loses state'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => PushedPage()),
);
}),
),
),
),
],
);
}
#override
bool get wantKeepAlive => true;
}
class Page2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(height: 300, color: Colors.orange);
}
}
class PushedPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
color: Colors.blue,
),
);
}
}
From the documentation on AutomaticKeepAliveClientMixin:
A mixin with convenience methods for clients of
[AutomaticKeepAlive]. Used with [State] subclasses.
Subclasses must implement [wantKeepAlive], and their [build]
methods must call super.build (the return value will always return
null, and should be ignored).
So in your code, before you return the ListView just call super.build:
Widget build(BuildContext context) {
super.build(context);
return ListView(...
}