Flutter - How to restart or redraw current screen Widget - dart

I'm using Navigation drawer and in it i have design one screen name as PostProperty screen in which multiple text form fields, image uploading are implemented, what i want is when user click on submit/add button, then the current screen widget should be redraw or all form fields should be clear so that user can submit/add another, please guide me, how to achieve this.
Widget Build Code
#override
Widget build(BuildContext context) {
return new Scaffold(
key: scaffoldKey,
resizeToAvoidBottomPadding: false,
backgroundColor: Colors.white,
appBar: showAppbar
? AppBar(
title: new Text(
setAppBarTitle(val_property_type),
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
centerTitle: true,
backgroundColor: ColorConstant.bg_color,
)
: null,
body: ModalProgressHUD(
inAsyncCall: _isInAsyncCall,
child: buildPropertyForm(context),
opacity: 0.5,
progressIndicator: CircularProgressIndicator(),
),
);
}
buildPropertyForm is the form in which i have include all text form field and other content.
Please see below screenshot

You could change the key for each TextFormField dynamically once you submit and also change the TextEditingControllers' values to null.

Related

How to wrap Text on AppBar

I added sub-Appbar on my application. How to view all text on the app bar without reducing font size?
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: submitRequestAppBar(context),
body: Scaffold(
appBar:
PreferredSize(
preferredSize: Size.fromHeight(40.0),
child:
AppBar(
backgroundColor: Colors.grey[350],
leading: Container(),
title: Text(
widget.title,
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 15.0),
),
),
),
You can create an scroll-animation to show the text that doesn't fit the screen. You can use this widget, the marquee. It's open-source so if you want to contribute you can just fork it and create a pull-request, from here.
It it's only wrapping you are after and don't care about the design. Then you should look into the solution on SO.

TextField's autofocus property causing the widget into 'dirty' State

AppBar has a search icon, when clicked it displays a TextField in the 'title' property. When search icon is clicked I need TextField to autofocus. Problem is with 'autofocus' property, if set to true, instead of only changing the state of the title property, something is causing the widget to turn into a 'dirty' state. This causes the main build function to get called which rebuilds the entire thing.
Tried to replicate this and provide a sample app but strangely enough it seems to work just fine in the demo.
Any debug suggestions?
AppBar(
centerTitle: true,
title: StreamBuilder(
stream: false,
initialData: symbolBloc.isSearching,
builder: (BuildContext context, AsyncSnapshot<bool> snapshot){
if(snapshot.data) {
return TextField(
// autofocus: true, <--- here
controller: searchQuery,
style: new TextStyle(
color: Colors.white,
),
);
}
return new Text("", style: new TextStyle(color: Colors.white)
);
}),
backgroundColor: Colors.blueGrey,
elevation: 0.0,
actions: <Widget>[
StreamBuilder(
stream: bloc.isSearchActive,
initialData: false,
builder: (BuildContext context, AsyncSnapshot<bool> snapshot){
if(snapshot.data)
return activeSearchIconButton(symbolBloc);
return searchIconButton(symbolBloc);
},
),
],
),
searchIconButton(SymbolBloc bloc){
return new IconButton(
icon: new Icon(
Icons.search,
color: Colors.white,
),
tooltip: 'Search',
onPressed: (){
bloc.displaySearchField(true);
},
);
}
activeSearchIconButton(SymbolBloc bloc){
return new IconButton(
icon: new Icon(
Icons.close,
color: Colors.white,
),
tooltip: 'Search',
onPressed: (){
bloc.displaySearchField(false);
},
);
}
You can set FocusNode property of TextField and on Button click call FocusScope.of(context).requestFocus(_focusNode);
The problem had do with InheritedWidgets. Having more than one InheritedWidget was the cause. I had a parent widget wrapping the runApp() function (holds a reference to api object) and a child widget wrapping each route (holds reference to bloc class for each specific screen).
Problem went away once I moved the contents of child widget over to the parent and removed the child InheritedWidget altogether.

Remove highlight when Flutter's TabBar is tapped

I'm trying to implement my own TabBar design in flutter. I was able to get a pretty good result. However, when I tap another tab to change the tab, there is a highlight create by default as shown in the image here. I'm wondering if there is any way I can get rid of the square highlight on tapped. I've been looking around for like almost a day not and did not find any solution.
If anyone have any solution please let me know. Thanks.
Edited: as CopsOnRoad suggestion I wrapped the TabBar in the Container and set the color to Colors.transparent, but it does not really disappear so I tried to set the color to Theme.of(context).canvasColor for now.
Container(
color: Theme.of(context).canvasColor,
child: TabBar(
isScrollable: true,
indicator: ShapeDecoration(
color: Color(0xFFE6E6E6),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(99.0)
)
),
tabs: List<Widget>.generate(
categories.length,
(index) => Tab(
child: Text(
categories[index],
style: TextStyle(
fontFamily: 'Hiragino Sans',
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Color(0xFF4D4D4D),
),
),
)
),
)
)
You can also disable the ripple/highlight/splash effect with the code below. Add the Theme with the data of ThemeData where the hightlight and splash color is both transparent.
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(70),
child: Theme(
data: ThemeData(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
),
child: AppBar( ... )
That's the ripple effect. You can remove it by wrapping it in a Container and giving transparent color to it.
you should set tabbar splashFactory: NoSplash.splashFactory as this post mentioned.
TabBar(splashFactory: NoSplash.splashFactory,)
How to disable default Widget splash effect in Flutter?
Here is my custom solution from #Tempelriter
Theme(
data: Theme.of(context).copyWith(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
),
child: Container(
decoration: BoxDecoration(
color: Colors.gray,
border: Border.all(
color: Colors.red
),
borderRadius: BorderRadius.circular(50),
),
child: TabBar(
isScrollable: true,
tabs: [
Tab(text: 'comingSoon'),
Tab(text: 'selling'),
],
),
),
);
I had the similar issue. I tried to read the documentation and found it.
///
/// If non-null, it is resolved against one of [MaterialState.focused],
/// [MaterialState.hovered], and [MaterialState.pressed].
///
/// [MaterialState.pressed] triggers a ripple (an ink splash), per
/// the current Material Design spec.
///
/// If the overlay color is null or resolves to null, then the default values
/// for [InkResponse.focusColor], [InkResponse.hoverColor], [InkResponse.splashColor],
/// and [InkResponse.highlightColor] will be used instead.
final MaterialStateProperty<Color?>? overlayColor;
Finally just added overlayColor to transparent. It solved my issue.
overlayColor: MaterialStateProperty.all(Colors.transparent)

How can I avoid the background image to shrink when my keyboard is active?

I would like to have a background image with text inputs but I don't know which widget I should use to avoid the background image to shrink when my keyboard is active.
Here you can find two screen shots of the problem and my code:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
var backgroundImage = new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/forest.jpg'), fit: BoxFit.cover));
return new MaterialApp(
home: new Scaffold(
body: new Stack(
children: <Widget>[
new Container(
decoration: backgroundImage,
),
new TextField()
],
)));
}
}
closed keyboard
active keyboard
Put Container outside of Scaffold, and make Scaffold as a child of Container with the background image.
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/bg.png'),
fit: BoxFit.cover,
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
body: ListView(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
hintText: "Email",
),
),
],
),
),
);
You can use the property resizeToAvoidBottomPadding from Scaffold :
Scaffold(
resizeToAvoidBottomPadding: false,
...
It's the default functionality of the flutter to keep UI above the keyboard so if you set resizeToAvoidBottomInset : false then you will lose the functionality of keeping your UI components above the keyboard
To have a background image in your application, and not to shrink it
better way is to do it like this
Container(
decoration: BoxDecoration(
color: primaryColor, // background color
image: DecorationImage(image: AssetImage(AppImages.appBg)),// background image above color
),
child: SafeArea(
child: Scaffold(
backgroundColor: Colors.transparent, //**IMPORTANT**
body: //All Ui code here//),
),
It is necessary to set Scaffold backgroundColor: Colors.transparent
otherwise, you won't be able to see your background image

Second page in flutter naviagtion flow is not full size

I am trying to make a basic "new activity" in flutter
I have followed the flutters docs and made a button that navigates to the next page with:
Navigator.push(context, new MaterialPageRoute(builder: (context)=> new HomePage(title: title,)));
This is the build method of the 2nd page/activity (HomePage.dart)
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Home"),
textTheme: orbitTextTheme),
body: new Center(
child: new Container(
color: Color.orange,
height: 150.0,
width: 150.0,
child:new Column(
children: <Widget>[
new TextField(
controller: _textController,
decoration: new InputDecoration(
hintText: "Try to type?"
),
)
],
),
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _newReg,
tooltip: 'New reg', //externalize
backgroundColor: Color.orange,
child: new Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
BUT, the second page is not full size: (Notice the missing floating action button)
Can anyone tell me what am doing wrong?
UPDATE
Was calling the Navigator.push( in a callback from googleSignIn (which presents a modal). So putting in a small delay fixed the bug. Thanks!
This graphical bug happens whenever you pop the last visible route before pushing a new one.
Consider using pushReplacement or pushReplacementNamed instead.

Resources