How to use Flutter AnimatedContainer with height matching child - flutter

Currently this code works to resize a container to toggle between different content, but it's not animating. I think that I need to provide a height property to make the animation work, and when I do provide a height to toggle between it does match, like this:
height: selected ? 400 : 100,
The container animates smoothly between the two states. However the height is no longer adaptive. So I try to supply a height using:
GlobalKey _key = GlobalKey();
_size = _key.currentContext.size;
height: _size.height,
But it gives me errors and I'm not sure how to fix it.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool selected = false;
// GlobalKey _key = GlobalKey();
// Size _size = _key.currentContext.size;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(
child: ListView(
children: [
GestureDetector(
onTap: () {
setState(() {
selected = !selected;
// _size = _key.currentContext.size;
});
},
child: Padding(
padding: EdgeInsets.all(5),
child: AnimatedContainer(
// height: _size.height,
// key: _key,
duration: Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
boxShadow: [
BoxShadow(
blurRadius: 2.5,
spreadRadius: 0.4,
color: Colors.grey,
offset: Offset(0, 0.5),
),
],
),
child: Padding(
padding: EdgeInsets.all(17),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Move fridge up stairs',
style: TextStyle(fontSize: 16),
),
SizedBox(height: 5),
Text(
'Sarah - 2 days ago - 2.3km',
style: TextStyle(color: Colors.black54),
),
if (selected)
Container(
child: Column(
children: [
Padding(
padding: EdgeInsets.fromLTRB(0, 20, 0, 20),
child: Text(
'Fridge is a single door. Sitting in kitchen. Need one strong person as I will help move it.',
style: TextStyle(
color: Colors.black54,
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Row(
children: [
Icon(
Icons.calendar_today,
color: Colors.black54,
size: 20,
),
Text(
' In three days',
style: TextStyle(
color: Colors.black54,
),
),
],
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Row(
children: [
Icon(
Icons.attach_money,
color: Colors.black54,
),
Text(
' 30',
style: TextStyle(
color: Colors.black54,
),
),
],
),
),
Row(
children: [
Text('Price : '),
Container(
width: 140,
margin: EdgeInsets.fromLTRB(0, 0, 0, 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white,
border: Border.all(color: Colors.white),
),
child: Container(
child: TextField(
decoration: new InputDecoration(
hintText: "Your price",
contentPadding: const EdgeInsets.all(10.0)),
keyboardType: TextInputType.number,
maxLines: null,
),
),
),
],
),
Row(
children: [
Text('Reply : '),
Expanded(
child: TextField(
decoration: new InputDecoration(
hintText: "Enter your reply",
contentPadding: const EdgeInsets.all(10.0)),
keyboardType: TextInputType.multiline,
maxLines: null,
),
),
],
),
SizedBox(height:20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: 10,
),
FlatButton(
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.blue, width: 1, style: BorderStyle.solid),
borderRadius: BorderRadius.circular(50),
),
color: Colors.white,
textColor: Colors.black,
onPressed: () {
/*...*/
},
child: Padding(
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text(
"Reply",
),
),
),
],
)
],
),
),
],
),
),
),
),
),
],
),
),
],
)
);
}
}

I thing AnimatedContainer is not Appropriate for this situation. I think its better to use AnimatedCrossFade. The AnimatedContainer will automatically animate between the old and new values of properties when they change using the provided curve and duration.
following code is refactored for using AnimatedCrossFade:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool selected = false;
// GlobalKey _key = GlobalKey();
// Size _size = _key.currentContext.size;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(
child: ListView(
children: [
GestureDetector(
onTap: () {
setState(() {
selected = !selected;
// _size = _key.currentContext.size;
});
},
child: Padding(
padding: EdgeInsets.all(5),
child: AnimatedCrossFade(
duration: Duration(seconds: 1),
crossFadeState: selected
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
firstChild: Container(
// height: !selected ? 100 : 400,
// key: _key,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
boxShadow: [
BoxShadow(
blurRadius: 2.5,
spreadRadius: 0.4,
color: Colors.grey,
offset: Offset(0, 0.5),
),
],
),
child: Padding(
padding: EdgeInsets.all(17),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Move fridge up stairs',
style: TextStyle(fontSize: 16),
),
SizedBox(height: 5),
Text(
'Sarah - 2 days ago - 2.3km',
style: TextStyle(color: Colors.black54),
),
if (selected)
Container(
child: Column(
children: [
Padding(
padding:
EdgeInsets.fromLTRB(0, 20, 0, 20),
child: Text(
'Fridge is a single door. Sitting in kitchen. Need one strong person as I will help move it.',
style: TextStyle(
color: Colors.black54,
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Row(
children: [
Icon(
Icons.calendar_today,
color: Colors.black54,
size: 20,
),
Text(
' In three days',
style: TextStyle(
color: Colors.black54,
),
),
],
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Row(
children: [
Icon(
Icons.attach_money,
color: Colors.black54,
),
Text(
' 30',
style: TextStyle(
color: Colors.black54,
),
),
],
),
),
Row(
children: [
Text('Price : '),
Container(
width: 140,
margin:
EdgeInsets.fromLTRB(0, 0, 0, 0),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(20.0),
color: Colors.white,
border:
Border.all(color: Colors.white),
),
child: Container(
child: TextField(
decoration: new InputDecoration(
hintText: "Your price",
contentPadding:
const EdgeInsets.all(
10.0)),
keyboardType:
TextInputType.number,
maxLines: null,
),
),
),
],
),
Row(
children: [
Text('Reply : '),
Expanded(
child: TextField(
decoration: new InputDecoration(
hintText: "Enter your reply",
contentPadding:
const EdgeInsets.all(10.0)),
keyboardType:
TextInputType.multiline,
maxLines: null,
),
),
],
),
SizedBox(height: 20),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: 10,
),
FlatButton(
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.blue,
width: 1,
style: BorderStyle.solid),
borderRadius:
BorderRadius.circular(50),
),
color: Colors.white,
textColor: Colors.black,
onPressed: () {
/*...*/
},
child: Padding(
padding: EdgeInsets.fromLTRB(
0, 10, 0, 10),
child: Text(
"Reply",
),
),
),
],
)
],
),
),
],
),
),
),
secondChild: Container(
// height: !selected ? 100 : 400,
// key: _key,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
boxShadow: [
BoxShadow(
blurRadius: 2.5,
spreadRadius: 0.4,
color: Colors.grey,
offset: Offset(0, 0.5),
),
],
),
child: Padding(
padding: EdgeInsets.all(17),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Move fridge up stairs',
style: TextStyle(fontSize: 16),
),
SizedBox(height: 5),
Text(
'Sarah - 2 days ago - 2.3km',
style: TextStyle(color: Colors.black54),
),
],
),
),
),
),
),
),
],
),
),
],
));
}
}

You can use custom animation to do this, like this:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
bool selected = false;
GlobalKey _key1 = GlobalKey();
GlobalKey _key2 = GlobalKey();
AnimationController _controller;
Animation _animation;
bool foward = false;
#override
void initState() {
super.initState();
_controller =
AnimationController(vsync: this, duration: Duration(seconds: 1));
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
void didChangeDependencies() {
super.didChangeDependencies();
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
_animation = Tween<double>(
begin: _key1.currentContext.size.height,
end: _key2.currentContext.size.height +
_key1.currentContext.size.height)
.chain(CurveTween(curve: Curves.fastOutSlowIn))
.animate(_controller);
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: ListView(
children: [
Padding(
padding: EdgeInsets.all(5),
child: GestureDetector(
onTap: () {
if (foward) {
_controller.reverse();
} else {
_controller.forward();
}
foward = !foward;
},
child: (_animation == null)
? _buildWidget(_key1, _key2)
: AnimatedBuilder(
// curve: Curves.fastOutSlowIn,
animation: _controller,
builder: (context, child) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
boxShadow: [
BoxShadow(
blurRadius: 2.5,
spreadRadius: 0.4,
color: Colors.grey,
offset: Offset(0, 0.5),
),
],
),
child: Padding(
padding: EdgeInsets.all(17.0),
child: Container(
height: _animation.value, child: child),
));
},
child: _buildWidget(_key1, _key2)),
),
),
],
)));
}
Widget _buildWidget(Key key1, Key key2) {
return SingleChildScrollView(
physics: const NeverScrollableScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Widget1(
key: _key1,
),
Widget2(
key: _key2,
),
],
),
);
}
}
class Widget1 extends StatefulWidget {
Widget1({Key key}) : super(key: key);
#override
_Widget1State createState() => _Widget1State();
}
class _Widget1State extends State<Widget1> {
#override
Widget build(BuildContext context) {
return Column(mainAxisSize: MainAxisSize.min, children: [
Text(
'Move fridge up stairs',
style: TextStyle(fontSize: 16),
),
SizedBox(height: 5),
Text(
'Sarah - 2 days ago - 2.3km',
style: TextStyle(color: Colors.black54),
),
]);
}
}
class Widget2 extends StatefulWidget {
Widget2({Key key}) : super(key: key);
#override
Widget2State createState() => Widget2State();
}
class Widget2State extends State<Widget2> {
#override
Widget build(BuildContext context) {
return Column(mainAxisSize: MainAxisSize.min, children: [
Container(
child: Column(children: [
Padding(
padding: EdgeInsets.fromLTRB(0, 20, 0, 20),
child: Text(
'Fridge is a single door. Sitting in kitchen. Need one strong person as I will help move it.',
style: TextStyle(
color: Colors.black54,
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Row(
children: [
Icon(
Icons.calendar_today,
color: Colors.black54,
size: 20,
),
Text(
' In three days',
style: TextStyle(
color: Colors.black54,
),
),
],
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Row(
children: [
Icon(
Icons.attach_money,
color: Colors.black54,
),
Text(
' 30',
style: TextStyle(
color: Colors.black54,
),
),
],
),
),
Row(
children: [
Text('Price : '),
Container(
width: 140,
margin: EdgeInsets.fromLTRB(0, 0, 0, 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white,
border: Border.all(color: Colors.white),
),
child: Container(
child: TextField(
decoration: new InputDecoration(
hintText: "Your price",
contentPadding: const EdgeInsets.all(10.0)),
keyboardType: TextInputType.number,
maxLines: null,
),
),
),
],
),
Row(
children: [
Text('Reply : '),
Expanded(
child: TextField(
decoration: new InputDecoration(
hintText: "Enter your reply",
contentPadding: const EdgeInsets.all(10.0)),
keyboardType: TextInputType.multiline,
maxLines: null,
),
),
],
),
SizedBox(height: 20),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
SizedBox(
width: 10,
),
FlatButton(
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.blue, width: 1, style: BorderStyle.solid),
borderRadius: BorderRadius.circular(50),
),
color: Colors.white,
textColor: Colors.black,
onPressed: () {
/*...*/
},
child: Padding(
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text(
"Reply",
),
))
])
]))
]);
}
}

Related

Blue line at the end of the screen flutter

I'm creating a dashboard from flutter. in my code, I have used the singlechildscroll view and it's not working. and I'm getting a blue line at the end of the page before the bottom navigation bar. I think it's because the page is not scrollable. There's no error display in the console. how do I correct this? appreciate your help on this.
import 'package:flutter/material.dart';
import '../constants/colors.dart';
import '../widgets/bottomNavigation.dart';
class DashboardScreen extends StatefulWidget {
const DashboardScreen({Key? key}) : super(key: key);
#override
_DashboardScreenState createState() => _DashboardScreenState();
}
class _DashboardScreenState extends State<DashboardScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
Padding(
padding: const EdgeInsets.only(right: 15),
child: Container(
width: 30,
child: Image.asset(
'assets/images/user.png',
),
),
),
],
backgroundColor: Colors.transparent,
elevation: 0.0,
iconTheme: IconThemeData(color: Colors.black),
),
drawer: Drawer(),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(top: 20, left: 20),
child: Text(
"Hi, NEO",
style: TextStyle(
fontSize: 25,
color: Colors.black,
fontWeight: FontWeight.bold,
//fontFamily: "Dubai"
),
),
),
SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.green,
),
),
Container(
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.deepPurple,
),
),
Container(
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.blue,
),
),
],
),
// SizedBox(
// height: 30,
// ),
Row(
children: [
Padding(
padding: const EdgeInsets.only(top: 30, left: 20),
child: Text(
"Your Leads",
style: TextStyle(
fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.bold,
//fontFamily: "Dubai"
),
),
),
],
),
SizedBox(
height:30 ,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 75,
width: 350,
decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [
BoxShadow(
offset: Offset(0, 1),
blurRadius: 5,
color: Colors.black.withOpacity(0.3),
),
],
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 75,
width: 350,
decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [
BoxShadow(
offset: Offset(0, 1),
blurRadius: 5,
color: Colors.black.withOpacity(0.3),
),
],
),
)
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 75,
width: 350,
decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(10),
color: Colors.lightGreen,
boxShadow: [
BoxShadow(
offset: Offset(0, 1),
blurRadius: 5,
color: Colors.black.withOpacity(0.3),
),
],
),
)
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 75,
width: 350,
decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [
BoxShadow(
offset: Offset(0, 1),
blurRadius: 5,
color: Colors.black.withOpacity(0.3),
),
],
),
)
],
),
Expanded(child: Container(child: BottomNavigation())),
],
),
);
}
}
[![enter image description here][1]][1]
//bottomnavigation
import 'package:flutter/material.dart';
class BottomNavigation extends StatefulWidget {
const BottomNavigation({Key? key}) : super(key: key);
#override
State<BottomNavigation> createState() => _BottomNavigationState();
}
class _BottomNavigationState extends State<BottomNavigation> {
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static const List<Widget> _widgetOptions = <Widget>[
Text(
'Index 0: Home',
style: optionStyle,
),
Text(
'Index 1: Business',
style: optionStyle,
),
Text(
'Index 2: School',
style: optionStyle,
),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BottomNavigationBar Sample'),
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'School',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
Looking at the updated code, both classes return a Scaffold with an Appbar. Thus, the blue box you see at the bottom is the Appbar of the class _BottomNavigationState.
Please refer to the code below for a correct implementation of a BottomNavigationBar.
Explanation
Generally, if one wants to encapsulate a BottomNavigationBar in its own Widget, this Widget needs to return a BottomNavigationBar in its build() method and not a Scaffold.
But usually, a BottomNavigationBar is used as shown below, without using an extra Widget.
Code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: MyStatefulWidget(),
);
}
}
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
#override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static const List<Widget> _widgetOptions = <Widget>[
Text(
'HOME PAGE',
style: optionStyle,
),
Text(
'COURSE PAGE',
style: optionStyle,
),
Text(
'CONTACT GFG',
style: optionStyle,
),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('GeeksForGeeks'),
backgroundColor: Colors.green,
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
// HERE ! bottomNavigationBar: MyBottomNavigatioBar(...)
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.bookmark),
title: Text('Courses'),
),
BottomNavigationBarItem(
icon: Icon(Icons.contact_mail),
title: Text('Mail'),
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
Source
https://www.geeksforgeeks.org/bottomnavigationbar-widget-in-flutter/
Okay I try your code and this is the result, I dont have any blue line, In your case I think you can try 2 possible solutions.
First one is to wrap your column with a singleChildScrollView, but I think you´ll need 2 columns one for the singleChildScrollView and another for the bottomNavigationBar.
Something like this:
body: Column(
children: [
SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(top: 20, left: 20),
child: Text(
"Hi, NEO",
style: TextStyle(
fontSize: 25,
color: Colors.black,
fontWeight: FontWeight.bold,
//fontFamily: "Dubai"
),
),
),
SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.green,
),
),
Container(
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.deepPurple,
),
),
Container(
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.blue,
),
),
],
),
// SizedBox(
// height: 30,
// ),
Row(
children: [
Padding(
padding: const EdgeInsets.only(top: 30, left: 20),
child: Text(
"Your Leads",
style: TextStyle(
fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.bold,
//fontFamily: "Dubai"
),
),
),
],
),
SizedBox(
height:30 ,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 75,
width: 350,
decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [
BoxShadow(
offset: Offset(0, 1),
blurRadius: 5,
color: Colors.black.withOpacity(0.3),
),
],
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 75,
width: 350,
decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [
BoxShadow(
offset: Offset(0, 1),
blurRadius: 5,
color: Colors.black.withOpacity(0.3),
),
],
),
)
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 75,
width: 350,
decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(10),
color: Colors.lightGreen,
boxShadow: [
BoxShadow(
offset: Offset(0, 1),
blurRadius: 5,
color: Colors.black.withOpacity(0.3),
),
],
),
)
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 75,
width: 350,
decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [
BoxShadow(
offset: Offset(0, 1),
blurRadius: 5,
color: Colors.black.withOpacity(0.3),
),
],
),
)
],
),
],
),
),
Expanded(child: Container( BottomNavigation )),
],
),
The second one is that your BottomNavigation have the problem of the blue line, and I can't test it because I don't see your code.

NoSuchMethodError: Class 'List<Data> has no instance getter

I have gridviewbuilder that takes data from itemGriddata which has onTap function that directs it to a new page that takes data from that model as well but when I click on it the error in the title appears, any help or some kind of enlightement would be appreciated
this is gridview page
import 'package:flutter/material.dart';
import 'package:wild_wild_rift/builds/SinglePage.dart';
import 'package:wild_wild_rift/data/model.dart';
import 'package:google_fonts/google_fonts.dart';
class GridViewPage extends StatefulWidget {
#override
_GridViewPage createState() => _GridViewPage();
}
class _GridViewPage extends State<GridViewPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.grey,
automaticallyImplyLeading: true,
title: const Text(
'Champions',
style: TextStyle(
fontFamily: 'Lexend Doca',
color: Colors.white,
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
elevation: 2,
),
body: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(15, 15, 15, 15),
child: GridView.builder(
itemCount: itemGriddata.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 1,
),
itemBuilder: (context, index) {
return GridSingleItem(
itemGriddata: itemGriddata[index],
onTap: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SinglePage(itemGriddata[index])));
},
);
},
),
),
),
],
));
}
}
class GridSingleItem extends StatelessWidget {
final itemGriddata;
final Function onTap;
const GridSingleItem({Key key, #required this.itemGriddata, this.onTap})
: super(key: key);
#override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: const Color(0xEEEEEE),
image: DecorationImage(
fit: BoxFit.cover,
image: Image.asset(itemGriddata.image).image,
),
boxShadow: const [
BoxShadow(
blurRadius: 3,
color: Color(0xDA000000),
)
],
borderRadius: BorderRadius.circular(9),
border: Border.all(
color: Colors.black,
),
),
child: Align(
alignment: AlignmentDirectional(-0.45, 0.85),
child: Text(
itemGriddata.name,
style: TextStyle(
fontFamily: 'Lexend Deca',
color: Color(0xFFFFFCFC),
fontWeight: FontWeight.normal,
shadows: [
Shadow(
blurRadius: 8.0,
color: Colors.black,
offset: Offset(1.0, 1.0),
),
],
),
),
),
),
),
);
}
}
this is page that I'd want to take data
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import '../data/model.dart';
class SinglePage extends StatefulWidget {
#override
_SinglePage createState() => _SinglePage();
final Data data;
SinglePage(this.data);
}
class _SinglePage extends State<SinglePage> {
PageController pageViewController;
bool isFirstButton = false;
bool isSecondButton = false;
#override
void initState() {
super.initState();
pageViewController = PageController(initialPage: 0);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: const Color(0xFF090F13),
automaticallyImplyLeading: true,
title: Text(
itemGriddata.name,
style: TextStyle(
fontFamily: 'Lexend Deca',
color: Colors.white,
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
actions: const [],
centerTitle: false,
elevation: 2,
),
backgroundColor: const Color(0xFF262D34),
body: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(0, 0, 0, 25),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Material(
color: Colors.transparent,
elevation: 3,
child: Container(
width: MediaQuery.of(context).size.width,
height: 150,
decoration: BoxDecoration(
color: const Color(0xFF090F13),
image: DecorationImage(
fit: BoxFit.cover,
image: Image.asset(
itemGriddata.backgroundimage,
).image,
),
),
),
),
],
),
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(20, 12, 20, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
children: const [
Text(
'Choose role',
style: TextStyle(
fontFamily: 'Lexend Deca',
color: Color(0xFF8B97A2),
fontSize: 14,
fontWeight: FontWeight.normal,
),
),
],
),
),
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(0, 12, 1, 0),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
16, 0, 0, 0),
child: InkWell(
onTap: () async {
isSecondButton = false;
isFirstButton = true;
setState(() {});
await pageViewController.animateToPage(
0,
duration: const Duration(milliseconds: 500),
curve: Curves.ease,
);
},
child: Material(
color: Colors.transparent,
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: const Color(0xFF090F13),
borderRadius: BorderRadius.circular(8),
shape: BoxShape.rectangle,
border: isFirstButton
? Border.all(color: Colors.white)
: null),
child: Stack(
children: [
Align(
alignment: const AlignmentDirectional(
0, -0.05),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/icon-position-jungle.png',
width: 50,
height: 50,
fit: BoxFit.cover,
),
const Padding(
padding: EdgeInsetsDirectional
.fromSTEB(0, 8, 0, 0),
child: AutoSizeText(
'BUILD 1',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Lexend Deca',
color: Color(0xFF8B97A2),
fontSize: 14,
fontWeight:
FontWeight.normal,
),
),
),
],
),
),
],
),
),
),
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
16, 0, 0, 0),
child: Material(
color: Colors.transparent,
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: const Color(0xFF090F13),
borderRadius: BorderRadius.circular(8),
border: isSecondButton
? Border.all(color: Colors.white)
: null),
child: InkWell(
onTap: () async {
isSecondButton = true;
isFirstButton = false;
setState(() {});
await pageViewController.animateToPage(
1,
duration:
const Duration(milliseconds: 500),
curve: Curves.ease,
);
},
child: Stack(
children: [
Align(
alignment: const AlignmentDirectional(
0, -0.05),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/icon-position-jungle.png',
width: 50,
height: 50,
fit: BoxFit.cover,
),
const Padding(
padding: EdgeInsetsDirectional
.fromSTEB(0, 8, 0, 0),
child: AutoSizeText(
'BUILD 2',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Lexend Deca',
color: Color(0xFF8B97A2),
fontSize: 14,
fontWeight:
FontWeight.normal,
),
),
),
],
),
),
],
),
),
),
),
),
],
),
),
),
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(20, 8, 20, 8),
child: Row(
mainAxisSize: MainAxisSize.max,
children: const [
Text(
'Builds',
style: TextStyle(
fontFamily: 'Lexend Deca',
color: Color(0xFF8B97A2),
fontSize: 14,
fontWeight: FontWeight.normal,
),
),
],
),
),
SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
16, 8, 16, 0),
child: Container(
width: MediaQuery.of(context).size.width,
height: 200,
decoration: BoxDecoration(
color: const Color(0x00090F13),
boxShadow: const [
BoxShadow(
blurRadius: 3,
color: Colors.transparent,
offset: Offset(0, 2),
)
],
borderRadius: BorderRadius.circular(8),
),
child: SizedBox(
width: double.infinity,
height: 500,
child: PageView(
controller: pageViewController,
scrollDirection: Axis.horizontal,
children: [
Image.asset(
'assets/images/image_1.png',
width: 100,
height: 100,
fit: BoxFit.cover,
),
Image.asset(
'assets/images/image_2.png',
width: 100,
height: 100,
fit: BoxFit.scaleDown,
),
],
),
),
),
),
],
),
),
],
),
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(20, 0, 20, 8),
child: Row(
mainAxisSize: MainAxisSize.max,
children: const [
Text(
'Text',
style: TextStyle(
fontFamily: 'Poppins',
color: Color(0xFF8B97A2),
),
),
],
),
),
],
),
),
);
}
}
and this is the model with data
final dynamic itemGriddata = [
Data(
name: "Ahri",
image: "assets/images/Ahri.png",
backgroundimage: "assets/images/Ahri_0.jpg"),
Data(
name: "Akali",
image: "assets/images/Akali.png",
backgroundimage: "assets/images/Akali_0.jpg")
];
class Data {
final String name;
final String image;
final String backgroundimage;
Data({this.name, this.image, this.backgroundimage});
}
The issue is that your SinglePage widget has a prop named final Data data; but the _SinglePageState widget is calling itemGriddata for your title and images. You'll need to change your code like so:
class SinglePage extends StatefulWidget {
const SinglePage(Key? key, this.data): super(key: key);
final Data data;
#override
State<StatefulWidget> createState() => _SinglePageState();
}
class _SinglePageState extends State<SinglePage> {
// use widget.data to get name, image, and backgroundImage
// ex... widget.data.name or widget.data.image
#override
Widget build(BuildContext context) {
return Text(widget.data.name);
}
}
You're passing the data correctly to SinglePage, but just change a few lines to ensure you're calling something with actual data! :D

Flutter Navigator.pop(context) won't work

I have seen many questions about Navigator.pop(context) but I didn't find my answer.
As you can see there are three screens so far. The Navigator.pop(context) works fine in the StoryDetailScreen and turns me back to the MainPage. The problem here with EditStoryScreen page, when I get into it I cant go back to the MainPage, when I click on the IconButton I see a black screen.
main.dart
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return
MultiProvider(
providers: [
ChangeNotifierProvider<Stories>(
create: (_) =>
Stories(),
),
ChangeNotifierProvider<Story>(
create:(ctx) => Story(),
),
],
child: MaterialApp(
title: 'MyShop',
theme: ThemeData(
primarySwatch: Colors.purple,
accentColor: Colors.deepOrange,
fontFamily: 'Lato',
),
home: Mainpage(),
routes: {
StoryDetailScreen.routeName: (ctx) => StoryDetailScreen(),
UserStory.routeName: (ctx) => UserStory(),
EditStoryScreen.routeName: (ctx) => EditStoryScreen(),
}),
);
}
}
Mainpage.dart
class Mainpage extends StatefulWidget {
static const routeName = 'main';
#override
_MainpageState createState() => _MainpageState();
}
class _MainpageState extends State<Mainpage> {
var _showOnlyFav = false;
#override
Widget build(BuildContext context) {
final storyCon = Provider.of<Stories>(context);
return Scaffold(
body: SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/back.jpg"), fit: BoxFit.fill)),
child: Column(children: <Widget>[
SizedBox(
height: 50,
),
Container(
child: Text("Short Stories",
style: TextStyle(
fontSize: 40, backgroundColor: Colors.grey[300])),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Row(
children: [
Container(
height: 40,
width: 290,
decoration: BoxDecoration(
color: Colors.grey[300],
border: Border.all(width: 1, color: Colors.black),
borderRadius: BorderRadius.circular(7)
// image: DecorationImage(
// image: AssetImage("images/text.png"))
),
child: Center(
child: Row(
children: [
InkWell(
onTap: () {
Navigator.of(context).pushReplacementNamed(UserStory.routeName);
},
child: Text(
"Edit Stroy",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 30,
// backgroundColor: Colors.grey[300]),
),
),
),
InkWell(
onTap: () {
Navigator.of(context).pushReplacementNamed(EditStoryScreen.routeName);
},
child:Text(
"Add Stroy",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 30,
// backgroundColor: Colors.grey[300]),
),
),)
],
),
),
),
],
))),
StorysGrid(_showOnlyFav),
]),
),
),
);
}
}
EditStoryScreen.dart
class EditStoryScreen extends StatefulWidget {
static const routeName = 'edit';
#override
_EditStoryScreenState createState() => _EditStoryScreenState();
}
class _EditStoryScreenState extends State<EditStoryScreen> {
final _storyFocusNode = FocusNode();
final _imgController = TextEditingController();
final _imgFocusNode = FocusNode();
#override
void initState() {
_imgFocusNode.addListener(updateImg);
super.initState();
}
#override
void dispose() {
_imgFocusNode.removeListener(updateImg);
_storyFocusNode.dispose();
_imgController.dispose();
_imgFocusNode.dispose();
super.dispose();
}
void updateImg() {
if (!_imgFocusNode.hasFocus) {
setState(() {});
}
}
// void backToHome(context) {
// Navigator.pushReplacementNamed(BuildContext(), context);
// }
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Container(
height: 650,
color: Colors.white,
child: Column(
children: [
SizedBox(
height: 30,
),
Align(
alignment: Alignment.topLeft,
child: RaisedButton(
child: Icon(Icons.arrow_back_ios),
onPressed: () => Navigator.pop(context)
)),
Padding(
padding: const EdgeInsets.fromLTRB(15, 10, 15, 15),
child: Form(
child: ListView(
shrinkWrap: true,
children: <Widget>[
TextFormField(
decoration: InputDecoration(labelText: "Title"),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
FocusScope.of(context).requestFocus(_storyFocusNode);
},
),
TextFormField(
decoration: InputDecoration(labelText: "Story's text"),
maxLines: 14,
keyboardType: TextInputType.multiline,
focusNode: _storyFocusNode,
),
Row(
children: [
Container(
width: 100,
height: 100,
margin: EdgeInsets.only(top: 8, right: 10),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.grey),
),
child: _imgController.text.isEmpty
? Text("Enter a Url")
: Center(
child: FittedBox(
child: Image.network(
_imgController.text,
),
),
),
),
Container(
width: 200,
child: TextFormField(
decoration: InputDecoration(
labelText: "Image URL",
),
keyboardType: TextInputType.url,
textInputAction: TextInputAction.done,
controller: _imgController,
focusNode: _imgFocusNode,
),
)
],
),
],
),
),
),
],
),
),
),
);
}
}
StoryDetailScreen.dart
class StoryDetailScreen extends StatelessWidget {
// final String title;
// final double price;
// ProductDetailScreen(this.title, this.price);
static const routeName = '/story-detail';
#override
Widget build(BuildContext context) {
final storyId =
ModalRoute.of(context).settings.arguments as String; // is the id!
final loadedStory = Provider.of<Stories>(
context,
listen: false,
).findById(storyId);
return Scaffold(
body: SingleChildScrollView(
child: Container(
width: double.infinity,
// height: 700,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/back1.jpg"), fit: BoxFit.fill)),
// color: Color(0xfffae3d9),
// child: Column(children: <Widget>[
// SizedBox(
// height: 10,
// ),
// Container(
// width: 340,
child:
Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
SizedBox(
height: 50,
),
Align(
alignment: Alignment.topLeft,
child: RaisedButton(
child: Icon(Icons.arrow_back_ios),
onPressed: (){
Navigator.pop(context);
})
),
Card(
elevation: 10,
margin: EdgeInsets.all(10),
child: Text("${loadedStory.title}",
softWrap: false,
textDirection: TextDirection.ltr,
style: TextStyle(
color: Color(0xFF6a2c70),
decorationColor: Colors.black,
fontSize: 25,
fontWeight: FontWeight.bold,
)),
),
SizedBox(height: 30),
Container(
width: double.infinity,
color: Colors.white70,
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 10, horizontal: 5),
child: Text(
loadedStory.story,
textDirection: TextDirection.rtl,
style: TextStyle(
color: Color(0xFF6a2c70),
decorationColor: Colors.black,
fontSize: 25,
fontWeight: FontWeight.bold,
// fontFamily: "Kufam"),
),
),
),
),
SizedBox(
height: 20,
),
Card(
child: Container(
height: 60,
width: 210,
decoration: BoxDecoration(color: Colors.white60),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Like(),
]),
),
),
),
// ],
// )
SizedBox(
height: 30,
)
]),
)
// ]
,
),
// ),
// ),
);
}
}
You're invoking
Navigator.of(context).pushReplacementNamed(UserStory.routeName)
so this is removing your Mainpage from the navigation stack and replacing it with UserStory, which is why when you call Navigator.pop(context), there's nothing to go back to and all you get is a black screen.
Change it to Navigator.of(context).pushNamed(UserStory.routeName).
You have to define the Mainpage route as well in the routes.

Custom Widget GridView

I was trying to perform a "Custom Widget" tutorial, and as you can see my source when I called the custom widget myGridItems(gridName, gridImage, color1, color2) the parameters are underlined, I don't know what did I miss.
import 'package:flutter/material.dart';
import 'package:carousel_pro/carousel_pro.dart';
import 'package:flutter/services.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown
]);
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Carousel',
home: ImageCarousel(),
);
}
}
class ImageCarousel extends StatefulWidget {
_ImageCarouselState createState() => new _ImageCarouselState();
}
class _ImageCarouselState extends State<ImageCarousel> with SingleTickerProviderStateMixin {
Animation<double> animation;
AnimationController controller;
initState() {
super.initState();
controller = new AnimationController(
duration: const Duration(milliseconds: 2000), vsync: this);
animation = new Tween(begin: 0.0, end: 18.0).animate(controller)
..addListener(() {
setState(() {
// the state that has changed here is the animation object’s value
});
});
controller.forward();
}
#override
Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height;
Widget carousel = new Carousel(
boxFit: BoxFit.cover,
images: [
new AssetImage('assets/s1.jpg'),
new AssetImage('assets/s2.jpg'),
],
animationCurve: Curves.fastOutSlowIn,
animationDuration: Duration(seconds: 1),
);
Widget banner = new Padding(
padding: const EdgeInsets.only(top: 20.0, left: 20.0),
child: new Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15.0),
bottomRight: Radius.circular(15.0)),
color: Colors.amber.withOpacity(0.5),
),
padding: const EdgeInsets.all(10.0),
child: new Text(
'Enter to learn, leave to achieve',
style: TextStyle(
fontFamily: 'fira',
fontSize: animation.value, //18.0,
//color: Colors.white,
),
),
),
// ),
// ),
);
Widget myGridItems (String gridName, String gridImage, int color1, int color2){
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.0),
gradient: new LinearGradient(
colors: [
Color(color1),
Color(color2),
],
begin: Alignment.centerLeft,
end: new Alignment(1.0, 1.0),
)
),
child: Stack(
children: <Widget>[
Opacity(
opacity: 0.3,
child: Container(
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(24.0),
image: DecorationImage(
image: AssetImage('assets/s1.jpg'),
fit: BoxFit.fill)
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(child: Text("Job", style: TextStyle(color: Colors.white, fontSize: 16),)),
SizedBox(width: 10.0),
Container(child: Icon(Icons.school, color: Colors.white)),
SizedBox(width: 10.0),
Container(child: Text("Guide", style: TextStyle(color: Colors.white, fontSize: 16),)),
],
),
),
SizedBox(height: 10.0),
Padding(
padding: const EdgeInsets.only(left: 16.0),
child: Text(gridName, style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),),
),
],
)
],
),
);
}
return new Scaffold(
appBar: AppBar(
title: Text('Kelden Bilingual Higher Institute of Professional Studies\n'
'Accord N° 18-1020/L/MINSUP/SG/DDES/SD-ESUP/SDA/LMN du 03/12/2018\n'
'Arrêté N° 078/MINEFOP/SG/DFOP/SDGSF/SACD du 13/03/2017', textAlign: TextAlign.center, style: TextStyle(fontSize: 9.5,),),
),
backgroundColor: Colors.blue[200],
body: new Column(
children: <Widget>[
new Container(
padding: const EdgeInsets.fromLTRB(0, 1, 0, 90.0),
height: screenHeight / 2,
child: new ClipRRect(
borderRadius: BorderRadius.circular(0.0),
child: new Stack(
children: [
carousel,
banner,
],
),
),
),
Flexible(
child: GridView.count(
crossAxisCount: 2,
padding: EdgeInsets.all(16.0),
childAspectRatio: 0.9,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
children: <Widget>[
myGridItems(gridName, gridImage, color1, color2)
],
),
)
],
),
);
}
dispose() {
controller.dispose();
super.dispose();
}
}

How to make custom tabbar with gradient

How to make tab bar like below image in flutter?Is it possible to develop a Tabbar like below ?If not possible then what is the next better working solution?
Thank you for the support and i solved this issue my self without using any answers from stackoverflow
Try this way
I have created tab layout using ScrollablePositionedList
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_widgets/flutter_widgets.dart';
void main() => runApp(HomeScreen());
int currentTab = 0;
class HomeScreen extends StatefulWidget {
#override
_HomeScreenPage createState() => _HomeScreenPage();
}
class TabModel {
String text;
TabModel({this.text});
}
List<TabModel> _tabList = [
TabModel(text: "Android"),
TabModel(text: "IOS"),
TabModel(text: "Java"),
TabModel(text: "JavaScript"),
TabModel(text: "PHP"),
TabModel(text: "HTML"),
TabModel(text: "C++"),
];
class _HomeScreenPage extends State<HomeScreen>
with SingleTickerProviderStateMixin {
PageController _controller = PageController(initialPage: 0, keepPage: false);
final ItemScrollController itemScrollController = ItemScrollController();
final ItemPositionsListener itemPositionListener =
ItemPositionsListener.create();
#override
void initState() {
super.initState();
}
#override
void dispose() {
super.dispose();
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.purple,
brightness: Brightness.light,
accentColor: Colors.red),
darkTheme: ThemeData(
brightness: Brightness.dark,
),
home: Scaffold(
appBar: AppBar(
title: Text("Custom TabBar"),
),
body: Column(
children: <Widget>[
Container(
height: 60,
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(14.0),
border: Border.all(color: Colors.black, width: 1.0)),
child: ScrollablePositionedList.builder(
scrollDirection: Axis.horizontal,
itemCount: _tabList.length,
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
gradient: currentTab == index
? LinearGradient(
colors: [
Colors.redAccent,
Colors.redAccent[200],
Colors.redAccent[100]
],
)
: null,
borderRadius: BorderRadius.circular(13.0),
),
child: FlatButton(
color: Colors.transparent,
onPressed: () {
setState(() {
currentTab = index;
_controller.jumpToPage(currentTab);
});
},
child: Text(
_tabList[index].text,
),
),
);
},
itemScrollController: itemScrollController,
itemPositionsListener: itemPositionListener,
)),
Flexible(
child: Container(
child: PageView(
controller: _controller,
onPageChanged: (pageId) {
setState(() {
currentTab = pageId;
itemScrollController.scrollTo(
index: currentTab, duration: Duration(seconds: 1));
});
},
children: <Widget>[
Container(
color: Colors.pink,
child: Center(
child: Text(
_tabList[currentTab].text,
style: TextStyle(
color: Colors.white,
fontSize: 50,
fontWeight: FontWeight.bold),
),
),
),
Container(
color: Colors.cyan,
child: Center(
child: Text(
_tabList[currentTab].text,
style: TextStyle(
color: Colors.white,
fontSize: 50,
fontWeight: FontWeight.bold),
),
),
),
Container(
color: Colors.red,
child: Center(
child: Text(
_tabList[currentTab].text,
style: TextStyle(
color: Colors.white,
fontSize: 50,
fontWeight: FontWeight.bold),
),
),
),
Container(
color: Colors.green,
child: Center(
child: Text(
_tabList[currentTab].text,
style: TextStyle(
color: Colors.white,
fontSize: 50,
fontWeight: FontWeight.bold),
),
),
),
Container(
color: Colors.grey,
child: Center(
child: Text(
_tabList[currentTab].text,
style: TextStyle(
color: Colors.white,
fontSize: 50,
fontWeight: FontWeight.bold),
),
),
),
Container(
color: Colors.purple,
child: Center(
child: Text(
_tabList[currentTab].text,
style: TextStyle(
color: Colors.white,
fontSize: 50,
fontWeight: FontWeight.bold),
),
),
),
Container(
color: Colors.teal,
child: Center(
child: Text(
_tabList[currentTab].text,
style: TextStyle(
color: Colors.white,
fontSize: 50,
fontWeight: FontWeight.bold),
),
),
),
],
),
)),
],
)));
}
}
You can find source code for this demo from my github account
OUTPUT
import 'package:flutter/material.dart';
void main() => runApp(
MaterialApp(home: MainScreen()),
);
class MainScreen extends StatefulWidget {
_MainState createState() => _MainState();
}
class _MainState extends State<MainScreen> {
int viewChoice = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
'Toolbar Title',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold /*fontSize,etc*/),
),
actions: [
IconButton(
icon: Icon(Icons.account_circle),
onPressed: () {
//Todo when pressed
}),
]),
body: Container(
child: Column(mainAxisSize: MainAxisSize.min, children: [
SizedBox(
height: 200,
width: double.infinity,
child: Stack(children: [
Container(
padding: EdgeInsets.all(10.0),
alignment: Alignment.centerLeft,
color: Colors.yellow,
height: 100.0,
width: double.infinity,
child: Text('Tem',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 20.0)), //Tem is in your ex pic
),
Positioned(
top: 75.0,
left: 40.0,
right: 40.0,
child: Container(
margin: EdgeInsets.only(left: 25.0, right: 25.0),
alignment: Alignment.topCenter,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(14.0),
border: Border.all(color: Colors.black, width: 1.0)),
child: Row(mainAxisSize: MainAxisSize.min, children: [
Expanded(
child: Container(
decoration: BoxDecoration(
gradient: viewChoice == 0
? LinearGradient(
colors: [Colors.orange, Colors.orangeAccent],
)
: null,
borderRadius: BorderRadius.circular(13.0),
border: viewChoice == 0
? Border.all(color: Colors.black, width: 1.0)
: null,
),
child: FlatButton(
color: Colors.transparent,
onPressed: () {
setState(() {
viewChoice = 0;
});
},
child: Text(
'All',
/*style as your requirement*/
),
),
),
),
Expanded(
child: Container(
decoration: BoxDecoration(
gradient: viewChoice == 1
? LinearGradient(
colors: [Colors.orange, Colors.orangeAccent],
)
: null,
borderRadius: BorderRadius.circular(13.0),
border: viewChoice == 1
? Border.all(color: Colors.black, width: 1.0)
: null,
),
child: FlatButton(
onPressed: () {
setState(() {
viewChoice = 1;
});
},
child: Text(
'Favorites',
/*style as your requirement*/
),
),
),
),
]),
),
),
]),
),
viewChoice == 0
? ListView(shrinkWrap: true, children: [
//Content of All categories
])
: ListView(shrinkWrap: true, children: [
//Content of All categories
])
]),
),
);
}
}
TabBar without AppBar
Give a try to below code.
import 'package:flutter/material.dart';
import 'package:flutter_text_to_image/utils/app_colors.dart';
class TabBarWidget extends StatefulWidget {
final String firstTabTxt;
final String firstTabViewTxt;
final String secondTabTxt;
final String secondTabViewTxt;
const TabBarWidget({
super.key,
required this.firstTabTxt,
required this.secondTabTxt,
required this.firstTabViewTxt,
required this.secondTabViewTxt,
});
#override
State
<TabBarWidget>
createState() => _TabBarWidgetState();
}
class _TabBarWidgetState extends State
<TabBarWidget>
with SingleTickerProviderStateMixin {
TabController? _tabController;
#override
void initState() {
_tabController = TabController(length: 2, vsync: this);
super.initState();
}
#override
void dispose() {
_tabController?.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Container(
height: 100,
child: Column(
children: [
Container(
height: 35,
decoration: BoxDecoration(
border: Border.all(
color: AppColors.tabBorderColor,
),
borderRadius: BorderRadius.circular(
5.0,
),
),
child: TabBar(
controller: _tabController,
indicator: BoxDecoration(
gradient: LinearGradient(
colors: [
AppColors.waterMelonColor,
AppColors.mangoColor,
AppColors.azureColor,
AppColors.sapphireColor,
],
begin: FractionalOffset(0.0, 0.0),
end: FractionalOffset(1.0, 0.0),
stops: [
0.1,
0.4,
0.6,
1.0,
],
tileMode: TileMode.clamp,
),
borderRadius: BorderRadius.circular(
2.0,
),
),
labelColor: AppColors.whiteColor,
unselectedLabelColor: AppColors.blackColor,
tabs: [
Tab(
text: widget.firstTabTxt,
),
Tab(
text: widget.secondTabTxt,
),
],
),
),
Expanded(
child: TabBarView(
controller: _tabController,
children: [
Padding(
padding: EdgeInsets.only(top: 10),
child: Column(
children: [
Text(
widget.firstTabViewTxt,
),
],
),
),
Padding(
padding: EdgeInsets.only(top: 10),
child: Column(
children: [
Text(
widget.secondTabViewTxt,
),
],
),
),
],
),
),
],
),
);
}
}