Layout issue: TabBarView with TextField Keyboard overflow - flutter

I'm trying to implement a specific design and as thhe title says I have encountered an issue in building my layout.
When I'm taping inside my TextField the keyboard open itself and create an overflow.
Screenshots
Code
deals_edition_page.dart
import 'package:flutter/material.dart';
import 'package:myuca/ui/manager/deals/edition_informations_tab.dart';
class DealsEditionPage extends StatefulWidget {
#override
State<StatefulWidget> createState() => _DealsEditionPageState();
}
class _DealsEditionPageState extends State<DealsEditionPage> {
MemoryImage _image;
Widget _buildAppbar() {
return AppBar(
elevation: 0,
leading: IconButton(
icon: Icon(Icons.close),
onPressed: () => Navigator.pop(context),
),
title: Text(/* random String */),
actions: [
IconButton(
icon: Icon(Icons.check),
onPressed: () => Navigator.pop(context),
),
],
);
}
Widget _buildHeaderTabBar() {
return SliverAppBar(
automaticallyImplyLeading: false,
expandedHeight: 224,
floating: true,
elevation: 0,
flexibleSpace:
FlexibleSpaceBar(background: Image.memory(_image.bytes, fit: BoxFit.cover)),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: _buildAppbar(),
body: DefaultTabController(
length: 2,
child: CustomScrollView(
slivers: <Widget>[
_buildHeaderTabBar(),
SliverToBoxAdapter(
child: TabBar(
indicatorWeight: 2,
tabs: [
Tab(text: 'Informations'),
Tab(text: 'Informations'),
],
),
),
SliverFillRemaining(
child: Column(
children: [
Expanded(
child: TabBarView(
children: [
EditionInformationsTab(),
Center(child: Text("Tab 2")),
],
),
),
],
),
),
],
),
),
);
}
}
edition_informations_tab.dart
import 'package:flutter/material.dart';
import 'package:myuca/extensions/extensions.dart' show WidgetModifier;
class EditionInformationsTab extends StatefulWidget {
#override
State<StatefulWidget> createState() => _EditionInformationsTabState();
}
class _EditionInformationsTabState extends State<EditionInformationsTab> {
final _list1 = <String>['Culture', 'Test'];
final _list2 = <String>['Etablissement', 'Test 1', 'Test 2'];
List<DropdownMenuItem<String>> _menuItemsGenerator(List<String> values) =>
values
.map<DropdownMenuItem<String>>((e) => DropdownMenuItem<String>(
value: e,
child: Text(e),
))
.toList();
#override
Widget build(BuildContext context) {
return Form(
child: Column(
children: [
DropdownButtonFormField<String>(
value: _list1.first,
decoration: InputDecoration(
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(4))),
items: _menuItemsGenerator(_list1),
onChanged: (_) {},
).padding(EdgeInsets.only(bottom: 24)),
DropdownButtonFormField(
value: _list2.first,
decoration: InputDecoration(
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(4))),
items: _menuItemsGenerator(_list2),
onChanged: (_) {},
).padding(EdgeInsets.only(bottom: 24)),
TextFormField(
maxLength: 30,
decoration: InputDecoration(
labelText: "Nom de l'offre",
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(4))),
),
],
),
).padding(EdgeInsets.only(
top: 16, left: 16, right: 16));
}
}
Any idea on how I could avoid this overflow when the keyboard is displayed ?

You can copy paste run full code below
You can in _EditionInformationsTabState wrap with SingleChildScrollView
class _EditionInformationsTabState extends State<EditionInformationsTab> {
...
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
working demo
full code
import 'package:flutter/material.dart';
class DealsEditionPage extends StatefulWidget {
#override
State<StatefulWidget> createState() => _DealsEditionPageState();
}
class _DealsEditionPageState extends State<DealsEditionPage> {
MemoryImage _image;
Widget _buildAppbar() {
return AppBar(
elevation: 0,
leading: IconButton(
icon: Icon(Icons.close),
onPressed: () => Navigator.pop(context),
),
title: Text("demo"),
actions: [
IconButton(
icon: Icon(Icons.check),
onPressed: () => Navigator.pop(context),
),
],
);
}
Widget _buildHeaderTabBar() {
return SliverAppBar(
automaticallyImplyLeading: false,
expandedHeight: 224,
floating: true,
elevation: 0,
flexibleSpace: FlexibleSpaceBar(
background: Image.network("https://picsum.photos/250?image=9",
fit: BoxFit.cover)),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: _buildAppbar(),
body: DefaultTabController(
length: 2,
child: CustomScrollView(
slivers: <Widget>[
_buildHeaderTabBar(),
SliverToBoxAdapter(
child: TabBar(
indicatorWeight: 2,
tabs: [
Tab(text: 'Informations'),
Tab(text: 'Informations'),
],
),
),
SliverFillRemaining(
child: Column(
children: [
Expanded(
child: TabBarView(
children: [
EditionInformationsTab(),
Center(child: Text("Tab 2")),
],
),
),
],
),
),
],
),
),
);
}
}
class EditionInformationsTab extends StatefulWidget {
#override
State<StatefulWidget> createState() => _EditionInformationsTabState();
}
class _EditionInformationsTabState extends State<EditionInformationsTab> {
final _list1 = <String>['Culture', 'Test'];
final _list2 = <String>['Etablissement', 'Test 1', 'Test 2'];
List<DropdownMenuItem<String>> _menuItemsGenerator(List<String> values) =>
values
.map<DropdownMenuItem<String>>((e) => DropdownMenuItem<String>(
value: e,
child: Text(e),
))
.toList();
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(top: 16, left: 16, right: 16),
child: Form(
child: Column(
children: [
Padding(
padding: EdgeInsets.only(bottom: 24),
child: DropdownButtonFormField<String>(
value: _list1.first,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(4))),
items: _menuItemsGenerator(_list1),
onChanged: (_) {},
),
),
Padding(
padding: EdgeInsets.only(bottom: 24),
child: DropdownButtonFormField(
value: _list2.first,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(4))),
items: _menuItemsGenerator(_list2),
onChanged: (_) {},
),
),
TextFormField(
maxLength: 30,
decoration: InputDecoration(
labelText: "Nom de l'offre",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(4))),
),
],
),
),
),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: DealsEditionPage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

Related

How to get titled container in flutter

I want the container to have title over it like in this picture -
I am using stack and positioned to get the same, but instead I am getting this -
Here is my code -
Expanded(
child: Stack(
children: [
Container(
........... //Some Code
),
Positioned(
left: 0,
top: 0,
child: Text("One"),
),
],0
)
),
If I try to position it with top: -5 or -10, this is what I get -
Is there any widget for this? If no, then I think padding is the only option left with me. What should I do?
There is a package flutter_titled_container 1.0.7.
import 'package:flutter/material.dart';
import 'package:flutter_titled_container/flutter_titled_container.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
centerTitle: true,
title: Text('Titled Container'),
),
body: Center(
child: TitledContainer(
titleColor: Colors.blue,
title: 'Container Title',
textAlign: TextAlignTitledContainer.Center,
fontSize: 16.0,
backgroundColor: Colors.white,
child: Container(
width: 250.0,
height: 200.0,
decoration: BoxDecoration(
border: Border.all(
color: Colors.blue,
),
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
child: Center(
child: Text(
'Some text',
style: TextStyle(fontSize: 28.0),
),
),
),
),
),
);
}
}
More details on here.
Try below code hope its help to you.
InputDecorator(
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Academic Year',
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: dropdownValue,
isDense: true,
isExpanded: true,
onChanged: (String? newValue) {
setState(() {
dropdownValue = newValue!;
});
},
items: <String>['2021-2022', '2022-2023', '2023-2024', '2024-2025']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
),
),
Result screen->
full example:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const Center(
child: MyStatefulWidget(),
),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
String dropdownValue = '2021-2022';
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10),
child: InputDecorator(
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Academic Year',
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: dropdownValue,
isDense: true,
isExpanded: true,
onChanged: (String? newValue) {
setState(() {
dropdownValue = newValue!;
});
},
items: <String>['2021-2022', '2022-2023', '2023-2024', '2024-2025']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
),
),
);
}
}
You can use InputDecorator
example:
InputDecorator(
child: Text("TEST"),
decoration: InputDecoration(
labelText: "lalala",
),
)
result:
Try to add margin.top to container insteads of negative Positioned.top. With the title, using Positioned.top/left/right to determine size and Align to align it to topleft, using Container with color.white to remove border line.
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: Column(
children: [
TitledContainer(
titleText: 'Hello world!',
child: Text('Your content place here! Bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla'),
),
],
),
),
);
}
}
class TitledContainer extends StatelessWidget {
const TitledContainer({required this.titleText, required this.child, this.idden = 8, Key? key}) : super(key: key);
final String titleText;
final double idden;
final Widget child;
#override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
margin: const EdgeInsets.only(top: 8),
padding: EdgeInsets.all(idden),
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.circular(idden * 0.6),
),
child: child,
),
Positioned(
left: 10,
right: 10,
top: 0,
child: Align(
alignment: Alignment.topLeft,
child: Container(
color: Colors.white,
child: Text(titleText, overflow: TextOverflow.ellipsis),
),
),
),
],
);
}
}
Try set margin for Container
Expanded(
child: Stack(
children: [
Container(
margin: EdgeInsets.all(5), //add this code
........... //Some Code
),
Positioned(
left: 0,
top: 0,
child: Text("One"),
),
],0
)
),

How to customize Dropdown Button and items in flutter?

Today I tried to design a dropdown button with customized items in it where I can select all items or deselect all items with one click. But I didn't understand the approach how to do it. So please help me guys how to approach the required design and below I placed my design and required design.
and here is my code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String dropdownvalue = 'Apple';
var items = ['Apple','Banana','Grapes','Orange','watermelon','Pineapple'];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("DropDownList Example"),
),
body: Container(
padding: EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("DropDownButton"),
Container(
height: 40,
padding: EdgeInsets.all(5.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
border: Border.all(
color: Colors.grey, style: BorderStyle.solid, width: 0.80),
),
child: DropdownButtonHideUnderline(
child: DropdownButton(
elevation: 0,
value: dropdownvalue,
icon: Icon(Icons.keyboard_arrow_down),
items:items.map((String items) {
return DropdownMenuItem(
value: items,
child: Text(items)
);
}
).toList(),
onChanged: (String? newValue){
setState(() {
dropdownvalue = newValue!;
});
},
),
),
),
],
),
],
),
),
);
}
}
You can use dropdown_button2 package for this:
import 'package:flutter/material.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String dropdownvalue = 'Apple';
var items = [
'Apple',
'Banana',
'Grapes',
'Orange',
'watermelon',
'Pineapple'
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("DropDownList Example"),
),
body: Container(
padding: EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("DropDownButton"),
Container(
height: 40,
padding: EdgeInsets.all(5.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
border: Border.all(color: Colors.grey, style: BorderStyle.solid, width: 0.80),
),
child: DropdownButtonHideUnderline(
child: DropdownButton2(
hint: Text(
'Select Item',
style: TextStyle(
fontSize: 14,
color: Theme.of(context).hintColor,
),
),
items: items
.map((item) => DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
))
.toList(),
value: dropdownvalue,
onChanged: (String? newValue) {
setState(() {
dropdownvalue = newValue!;
});
},
buttonHeight: 40,
buttonWidth: 140,
itemHeight: 40,
),
)),
],
),
],
),
),
);
}
}
final result:

I am getting two appBar in flutter app. I am trying to add Drawer widget and TabBar widget in flutter app

main.dart
import 'package:flutter/material.dart';
import 'package:stray_animal_emergencyrescue/signUpPage.dart';
import './commons/commonWidgets.dart';
import 'package:stray_animal_emergencyrescue/loggedIn.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 login UI',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
//String showPasswordText = "Show Password";
bool obscurePasswordText = true;
#override
Widget build(BuildContext context) {
final passwordField = TextField(
obscureText: obscurePasswordText,
decoration: InputDecoration(
//contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
hintText: "Password",
//border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
suffixIcon: IconButton(
icon: new Icon(Icons.remove_red_eye),
onPressed: () {
setState(() {
this.obscurePasswordText = !obscurePasswordText;
});
},
)),
);
final loginButon = Material(
//elevation: 5.0,
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
//print(MediaQuery.of(context).size.width);
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => LogIn()),
);
},
child: Text('Login', textAlign: TextAlign.center),
),
);
final facebookContinueButton = Material(
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
//print(MediaQuery.of(context).size.width);
},
child: Text('Facebook', textAlign: TextAlign.center),
),
);
final googleContinueButton = Material(
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
//print(MediaQuery.of(context).size.width);
},
child: Text('Google ', textAlign: TextAlign.center),
),
);
final signUpButton = Material(
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FormScreen()),
);
//print(MediaQuery.of(context).size.width);
},
child: Text('Sign Up ', textAlign: TextAlign.center),
),
);
return Scaffold(
appBar: AppBar(
title: Text("Animal Emergency App"),
),
body: Center(
child: Container(
//color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//SizedBox(height: 45.0),
getTextFieldWidget(),
SizedBox(height: 15.0),
passwordField,
sizedBoxWidget,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
facebookContinueButton,
SizedBox(width: 5),
googleContinueButton,
SizedBox(width: 5),
loginButon
],
),
/*loginButon,
signUpButton,*/
sizedBoxWidget,
const Divider(
color: Colors.black,
height: 20,
thickness: 1,
indent: 20,
endIndent: 0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
//crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
signUpButton
],
),
],
),
),
),
),
);
}
}
loggedIn.dart
import 'package:flutter/material.dart';
import './tabbarviews/emergencyresue/EmergencyHome.dart';
import './tabbarviews/animalcruelty/animalCrueltyHome.dart';
import './tabbarviews/bloodbank/bloodBankHome.dart';
class LogIn extends StatefulWidget {
#override
_LogInState createState() => _LogInState();
}
class _LogInState extends State<LogIn> {
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static List<Widget> _widgetOptions = <Widget>[
EmergencyHome(),
AnimalCrueltyHome(),
BloodBankHome()
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First app bar appearing'),
actions: <Widget>[
GestureDetector(
onTap: () {},
child: CircleAvatar(
//child: Text("SC"),
backgroundImage: AssetImage('assets/images/760279.jpg'),
//backgroundImage: ,
),
),
IconButton(
icon: Icon(Icons.more_vert),
color: Colors.white,
onPressed: () {},
),
],
),
drawer: Drawer(
child: ListView(
children: <Widget>[
new ListTile(title: Text("Primary")),
MyListTile(
"Home",
false,
"Your customized News Feed about people you follow, ongoing rescues, nearby activities, adoptions etc.",
3,
Icons.home,
true,
() {}),
MyListTile(
"News & Media Coverage",
false,
"News about incidents which need immediate action, changing Laws",
3,
Icons.home,
false,
() {}),
MyListTile(
"Report",
true,
"Report cases with evidences anonymously",
3,
Icons.announcement,
false,
() {}),
MyListTile(
"Blood Bank",
true,
"Details to donate blood ",
3,
Icons.medical_services,
false,
() {}),
],
),
),
body: _widgetOptions[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
selectedItemColor: Colors.blue,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.pets),
label: 'Emergency Rescue',
),
BottomNavigationBarItem(
icon: Icon(Icons.add_alert),
label: 'Report Cruelty',
),
BottomNavigationBarItem(
icon: Icon(Icons.medical_services),
label: 'Blood Bank',
),
/*BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'Safe Hands',
backgroundColor: Colors.blue),*/
],
onTap: _onItemTapped,
),
);
}
}
//Safe Hands
class MyListTile extends StatelessWidget {
final String title;
final bool isThreeLine;
final String subtitle;
final int maxLines;
final IconData icon;
final bool selected;
final Function onTap;
MyListTile(this.title, this.isThreeLine, this.subtitle, this.maxLines,
this.icon, this.selected, this.onTap);
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(title),
isThreeLine: isThreeLine,
subtitle:
Text(subtitle, maxLines: maxLines, style: TextStyle(fontSize: 12)),
leading: Icon(icon),
selected: selected,
onTap: onTap);
}
}
EmergencyHome.dart
import 'package:flutter/material.dart';
import './finishedAnimalEmergencies.dart';
import './reportAnimalEmergency.dart';
import './ongoingAnimalEmergencies.dart';
class EmergencyHome extends StatefulWidget {
#override
_EmergencyHomeState createState() => _EmergencyHomeState();
}
class _EmergencyHomeState extends State<EmergencyHome> {
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text("Second appBar appearing"),
bottom: TabBar(
tabs: [
Tab(
//icon: Icon(Icons.more_vert),
text: "Report",
),
Tab(
text: "Ongoing",
),
Tab(
text: "Finished",
)
],
),
),
body: TabBarView(
children: [
ReportAnimalEmergency(),
OngoingAnimalEmergencies(),
FinishedAnimalEmergencies(),
],
),
)
);
}
}
The issue I am facing is two appBar, I tried removing appBar from loggedIn.dart but Drawer hamburger icon is not showing, and I cannot remove appBar from emergencyHome.dart as I wont be able to add Tab bar. What is viable solution for this? Please help how to Structure by app and routes to easily manage navigation within app
Remove the appbar from EmergencyHome.dart
this will remove the second app title. But there will be that shadow from the first app bar so put elvation:0
so, this will look like one appbar now your drawer will also work.
you can use flexibleSpace in EmergencyHome.dart
DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
flexibleSpace: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
TabBar(
tabs: [
Tab(
//icon: Icon(Icons.more_vert),
text: "Report",
),
Tab(
text: "Ongoing",
),
Tab(
text: "Finished",
)
],
)
],
),
),
body: TabBarView(
children: [
ReportAnimalEmergency(),
OngoingAnimalEmergencies(),
FinishedAnimalEmergencies(),
],
),
)
);
You don't want to make two appbar to get the drawer property. Use DefaultTabController then inside that you can use scaffold.so, you can have drawer: Drawer() inside that you can also get a appbar with it with TabBar as it's bottom.
This is most suitable for you according to your use case.
i will put the full code below so you can copy it.
void main() {
runApp(const TabBarDemo());
}
class TabBarDemo extends StatelessWidget {
const TabBarDemo({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 3,
child: Scaffold(
drawer: Drawer(),
appBar: AppBar(
bottom: const TabBar(
tabs: [
Tab(
text: "report",
),
Tab(text: "ongoing"),
Tab(text: "completed"),
],
),
title: const Text('Tabs Demo'),
),
body: const TabBarView(
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
),
),
),
);
}
}
OUTPUT

How to update main class widget from page in Flutter

Here is my main class with pageview
class EditInvoice extends StatefulWidget {
#override
_EditInvoiceState createState() => _EditInvoiceState();
}
class _EditInvoiceState extends State<EditInvoice> {
String strTotal = '0';
#override
void initState() {
super.initState();
}
PageController pageController = PageController(
initialPage: 0,
keepPage: true,
);
Widget buildPageView() {
return PageView(
controller: pageController,
children: <Widget>[
AddItems(),
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.orange[600],
elevation: 2.0,
child: Icon(
Icons.check,
color: Colors.white,
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
automaticallyImplyLeading: false,
toolbarHeight: 140.0,
centerTitle: true,
title: Column(
children: <Widget>[
Row(
children: <Widget>[
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back)),
Padding(padding: EdgeInsets.only(left: 30.0)),
Align(
alignment: Alignment.center,
child: Text(
strTotal,
style: TextStyle(color: Colors.black),
),
)
],
),
],
),
backgroundColor: Colors.white,
),
body: buildPageView(),
);
}
}
class AddItems extends StatefulWidget {
#override
_AddItemsState createState() => _AddItemsState();
}
class _AddItemsState extends State<AddItems> {
#override
Widget build(BuildContext context) {
var items = Padding(
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Amount',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5)),
),
),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15,
),
cursorColor: Colors.black,
keyboardType: TextInputType.phone,
));
return Container(
child: Card(
child: Padding(
padding: EdgeInsets.only(top: 10, bottom: 5.0, left: 10.0, right: 10.0),
child: SingleChildScrollView(
child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Text(
'Add Items',
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
items,
])))),
);
}
}
I am implementing pageview in my Flutter application. I want to update the amount in main class whenever user entered value in TextFormField from pageview.
Here AddItems is the page added with pageview and EditInvoice is the main class.
I am new to Flutter application development.
You can use the Provider Pattern:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ProviderTest with ChangeNotifier {
String amount = '';
void updateAmount(String newAmount) {
amount = newAmount;
notifyListeners();
}
}
class EditInvoice extends StatefulWidget {
#override
_EditInvoiceState createState() => _EditInvoiceState();
}
class _EditInvoiceState extends State<EditInvoice> {
#override
void initState() {
super.initState();
}
PageController pageController = PageController(
initialPage: 0,
keepPage: true,
);
Widget buildPageView() {
return PageView(
controller: pageController,
children: <Widget>[
AddItems(),
],
);
}
#override
Widget build(BuildContext context) {
var providerTest = Provider.of<ProviderTest>(context);
return Scaffold(
backgroundColor: Colors.white,
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.orange[600],
elevation: 2.0,
child: Icon(
Icons.check,
color: Colors.white,
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
automaticallyImplyLeading: false,
toolbarHeight: 140.0,
centerTitle: true,
title: Column(
children: <Widget>[
Row(
children: <Widget>[
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back)),
Padding(padding: EdgeInsets.only(left: 30.0)),
Align(
alignment: Alignment.center,
child: Text(
providerTest.amount.toString(),
style: TextStyle(color: Colors.black),
),
)
],
),
],
),
backgroundColor: Colors.white,
),
body: buildPageView(),
);
}
}
class AddItems extends StatefulWidget {
#override
_AddItemsState createState() => _AddItemsState();
}
class _AddItemsState extends State<AddItems> {
#override
Widget build(BuildContext context) {
var providerTest = Provider.of<ProviderTest>(context, listen: false);
var items = Padding(
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: TextFormField(
onChanged: (value) {
providerTest.updateAmount(value);
},
decoration: InputDecoration(
labelText: 'Amount',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5)),
),
),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15,
),
cursorColor: Colors.black,
keyboardType: TextInputType.phone,
));
return Container(
child: Card(
child: Padding(
padding: EdgeInsets.only(top: 10, bottom: 5.0, left: 10.0, right: 10.0),
child: SingleChildScrollView(
child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Text(
'Add Items',
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
items,
])))),
);
}
}
And at main.dart
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => ProviderTest(),
child: MaterialApp(
home: EditInvoice(),
),
);
}
}
More info about Provider Pattern here:
Provider Pattern
you can give callback to from child widget to parent widget to update data,
you can use inherited widget or provider

How can I show/hide a floatingActionButton in one tab to another?

I was wondering how can I show/hide a FloatingActionButton in a TabBarView.
So for example in my first tab, I wanna a FloatingActionButton, but in the second tab I wanna hide it.
So in my case my code is:
class Notifications extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
floatingActionButton: FloatingActionButton(
backgroundColor: kPink,
child: Icon(Icons.add),
onPressed: () => print(Localizations.localeOf(context)),
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.only(top: kBigSeparation),
child: DefaultTabController(
length: 2,
initialIndex: 0,
child: Padding(
padding: kPaddingTabBar,
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(kTinySeparation),
decoration: BoxDecoration(
color: kLightGrey,
borderRadius: BorderRadius.all(
Radius.circular(50),
),
),
child: TabBar(
tabs: <Tab>[
Tab(
text: AppLocalizations.of(context)
.translate('messages'),
),
Tab(
text: AppLocalizations.of(context)
.translate('notifications'),
)
],
unselectedLabelColor: Colors.black54,
labelColor: Colors.black,
unselectedLabelStyle: kBoldText,
labelStyle: kBoldText,
indicatorSize: TabBarIndicatorSize.tab,
indicator: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(50),
color: Colors.white,
),
),
),
const SizedBox(height: kMediumSeparation),
Expanded(
child: TabBarView(children: [
MessagesTab(),
NotificationsTab(),
]),
),
],
),
),
),
),
),
);
}
}
You can copy paste run full code below
Step 1 : You need to use TabController
Step 2 : Show/hide floatingActionButton based on tabIndex
code snippet
TabBar(
controller: _tabController,
tabs: <Tab>[
...
floatingActionButton: _tabController.index == 0
? FloatingActionButton(
backgroundColor: Colors.pink,
child: Icon(Icons.add),
onPressed: () => print(Localizations.localeOf(context)),
)
: Container(),
working demo
full code
import 'package:flutter/material.dart';
class Notifications extends StatefulWidget {
#override
_NotificationsState createState() => _NotificationsState();
}
class _NotificationsState extends State<Notifications>
with SingleTickerProviderStateMixin {
TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this, initialIndex: 0);
_tabController.addListener(_switchTabIndex);
}
void _switchTabIndex() {
print(_tabController.index);
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
floatingActionButton: _tabController.index == 0
? FloatingActionButton(
backgroundColor: Colors.pink,
child: Icon(Icons.add),
onPressed: () => print(Localizations.localeOf(context)),
)
: Container(),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.only(top: 2.0),
child: Padding(
padding: EdgeInsets.all(1.0),
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.all(
Radius.circular(50),
),
),
child: TabBar(
controller: _tabController,
tabs: <Tab>[
Tab(
text: 'messages',
),
Tab(
text: 'notifications',
)
],
unselectedLabelColor: Colors.black54,
labelColor: Colors.black,
//unselectedLabelStyle: kBoldText,
//labelStyle: kBoldText,
indicatorSize: TabBarIndicatorSize.tab,
indicator: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(50),
color: Colors.white,
),
),
),
const SizedBox(height: 10),
Expanded(
child: TabBarView(controller: _tabController, children: [
MessagesTab(),
NotificationsTab(),
]),
),
],
),
),
),
),
);
}
}
class MessagesTab extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Text("MessagesTab");
}
}
class NotificationsTab extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Text("NotificationsTab");
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Notifications(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}