Flutter: How to show number of items in cart while using firebase - firebase

I am building an e-commerce app using flutter and firebase. I am storing the cart data in a nested collection for each user in firestore and I want to show the number of items in cart above the cart icon in flutter but I don't know how to fetch that in real-time.
Here is the code of my homepage:
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
TabController _tabController;
#override
void initState() {
_tabController = TabController(length: 5, vsync: this, initialIndex: 0);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: TabBar(
controller: _tabController,
labelColor: Colors.yellow[800],
unselectedLabelColor: Colors.grey[800],
indicatorColor: Colors.transparent,
tabs: [
Tab(icon: Icon(Icons.local_grocery_store_outlined)),
Tab(
icon: Icon(Icons.card_giftcard_outlined),
),
Tab(
icon: Icon(Icons.fastfood_outlined),
),
Tab(
icon: Stack(
children: [
Icon(Icons.shopping_bag_outlined),
new Positioned(
top: 0.0,
right: 0.0,
child: CircleAvatar(
radius: 8.0,
backgroundColor: Colors.yellow[800],
child: Center(
child: Container(
padding: EdgeInsets.all(2),
child: Text(
/*Number of item in cart*/,
style: TextStyle(
color: Colors.black54,
fontSize: 10.0,
fontWeight: FontWeight.w500),
),
}),
),
),
)),
],
),
),
Tab(
icon: Icon(Icons.person_outline_outlined),
),
],
),
body: TabBarView(controller: _tabController, children: [
Store(),
Text("page"),
Text("page"),
CartPage(),
UserPage()
]),
);
}
}
I am using StreamBuilder to display the cart to the user.
My Firestore Structure

Related

Search bar in flutter app fetch articles from WordPress API

I guys, I have a News Flutter app that fetch articles from WordPress API,I have this code in my app but I don't know how to show up articles from search bar.
As you can see in the body of the Home page I have a busy body homepage because there are tabs widgets to show up.
I share screens to understand my case.
Is there another way to show up results maybe using a search delegate?
HomePage
searchbar page
Empty searchbar when I search keyword, no results
Home screen with tabs to load
class SearchBar extends StatefulWidget{
final List<Article> posts;
const SearchBar({Key? key, required this.posts,}) : super(key: key);
#override
_SearchBarState createState() => _SearchBarState();
}
class _SearchBarState extends State<SearchBar> {
final List<Article> _searchedPost = [];
late List<Article> _searchedArticles = [];
late final data;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: TextField(
decoration: const InputDecoration(
hintText: "Cerca Articolo",
border: InputBorder.none,
),
onChanged: (val) {
setState(() {
_searchedArticles = widget.posts.where((element) => element.title!.contains(val)).toList();
});
},
),
),
body: _searchedArticles.isEmpty ?
Scaffold(
body: Padding(padding: const EdgeInsets.all(12),
child: Column(
children: [
Image.asset("assets/images/search-illustration.png", height: 230,),
const SizedBox(height: 20,),
const Text('Nessun articolo trovato!',
style: TextStyle(
fontSize: 20.0,
color: Colors.black,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 20,),
const Text('Inserisci meglio le lettere o parole chiave dell’articolo che stai cercando e riprova.',
style: TextStyle(
fontSize: 16.0,
color: Colors.black54,
fontWeight: FontWeight.w400,
),
),
const SizedBox(height: 30,),
MaterialButton(
height: 50,
elevation: 0,
color: Colors.blue[900],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: Row(
children: const [
Text('Torna alla home', style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600),),
],
),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => HomePage(),
),
);
},
),
],
),
),
) : ListView.builder(
itemCount: _searchedArticles.length,
itemBuilder: (context, i) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Card(
margin: const EdgeInsets.all(10),
elevation: 5,
shadowColor: Colors.black26,
child: InkWell(
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
//data["_embedded"]["wp:featuredmedia"][0]["link"],),
_searchedArticles[i].urlImage == null
? const Text("Nessuna immagine caricata")
: Image.network(data["_embedded"]["wp:featuredmedia"][0]["link"],
width: double.infinity,
height: 220,
fit: BoxFit.cover,
),
// Title article
Column(
children: [
Padding(
padding: const EdgeInsets.only(
left: 16, top: 16, bottom: 16),
child: Row(
children: [
Expanded(
child: Text(_searchedArticles[i].title as String,
maxLines: 3,
overflow: TextOverflow.clip,
softWrap: true,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
,
),
),
),
],
),
)
],
),
],
),
),
onTap: () {
if (_searchedPost[i] != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ArticlePage(
data: _searchedPost[i],
),
),
);
}
},
),
),
],
);
},
),
);
}
}```
Home page
class HomePage extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<HomePage> with SingleTickerProviderStateMixin {
TabController? _tabController;
final List<Tab> topTabs = <Tab>[
const Tab(child: Text("Notizie")),
const Tab(child: Text("Fiscalità")),
const Tab(child: Text("Gestione")),
const Tab(child: Text("Business")),
const Tab(child: Text("Documentazione")),
];
#override
void initState() {
/// Start tabs articles
_tabController = TabController(length: topTabs.length, initialIndex: 0, vsync: this)..addListener(() {setState(() {});});
super.initState();
/// End tabs articles
}
/// tabs
Future<bool> _onWillPop() async {
if (_tabController?.index == 0) {
await SystemNavigator.pop();
}
Future.delayed(const Duration(microseconds: 200), () {
_tabController?.index = 0;
});
return _tabController?.index == 0;
}
final _scaffoldKey = GlobalKey<ScaffoldState>();
///
///
/// Search page
final List<Article> _posts = [];
#override
Widget build(BuildContext context) {
return Container(
child: WillPopScope(
onWillPop: _onWillPop,
child: Scaffold(
key: _scaffoldKey,
extendBody: true,
drawer: NavbarMenu(),
backgroundColor: const Color(0xFFFAFAFA),
appBar: AppBar(
elevation: 0,
leading: Builder(
builder: (BuildContext context) {
return GestureDetector(
child: Center(
child: IconButton(
icon: const Icon(
Icons.dehaze_outlined,
color: Colors.white,
),
onPressed: () {
Scaffold.of(context).openDrawer();
},
),
),
);
},
),
backgroundColor: Colors.blue[900],
centerTitle: true,
title: Image.asset('assets/images/bird.png', fit: BoxFit.contain, height: 32,),
/// Action search icon
actions: <Widget>[
/// First search icon
IconButton(
icon: const Icon(Icons.search, color: Colors.white,),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context)=> SearchBar(posts: _posts,)
));
},
),
],
/// Bottom tab bar
bottom: TabBar(
controller: _tabController,
indicatorColor: const Color(0xFFF9E14B),
tabs: topTabs,
indicator: const UnderlineTabIndicator(
borderSide: BorderSide(
width: 4.0,
color: Color(0xFFF9E14B),
),
insets: EdgeInsets.symmetric(horizontal: 10.0, vertical: 0),
),
labelColor: Colors.yellow,
unselectedLabelColor: Colors.white,
isScrollable: true,
labelStyle: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16,
fontFamily: "Raleway"),
unselectedLabelStyle: const TextStyle(
fontWeight: FontWeight.w400,
fontSize: 14,
),
),
),
/// Body
body: TabBarView(
controller: _tabController,
children: const [
//SearchBar(posts: [],),
NewsPage(),
FiscalitaPage(),
GestionePage(),
BusinessPage(),
DocumentazionePage(),
],
),
///
),
),
);
}```

How to retrieve data from firebase straight into the app?

I am new to flutter. I want to retrieve data from firebase firestore database and display it in the application. My requirement is to display the data in the form of a text in the screen. I have attached the my code below for a better understanding.
Note : I have already configured firebase in my project.
Code :
class dashboard extends StatefulWidget {
#override
_dashboardState createState() => _dashboardState();
}
// ignore: camel_case_types
class _dashboardState extends State<dashboard> {
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
int _selectedIndex = 0;
#override
Widget build(BuildContext context) {
MediaQueryData screen = MediaQuery.of(context);
final authService = Provider.of<AuthService>(context);
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 80.0, right: 250),
child: Center(
child: Container(
width: screen.size.width,
// height: 20.0,
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(15.0)),
child: (const Text(
'I need the data retreievd from firebase firestore to be displayed here.',
textAlign: TextAlign.justify,
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.black),
)),
),
),
),
Padding(
padding: EdgeInsets.only(left: 300.0, top: 1.0),
child: IconButton(
icon: new Icon(Icons.account_circle, size: 30.0),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfilePage(),
),
);
},
),
),
Padding(
padding: EdgeInsets.only(left: 300.0, top: 5.0),
child: IconButton(
icon: const Icon(
Icons.notifications,
size: 25.0,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Notifications(),
),
);
},
),
),
Padding(
padding: const EdgeInsets.only(top: 0.0),
child: Center(
child: Container(
width: 390,
height: 450,
decoration: BoxDecoration(
color: Colors.green.shade100,
borderRadius: BorderRadius.circular(10.0),
),
),
),
),
],
),
),
floatingActionButton: FloatingActionButton(onPressed: () async {
await authService.signOut();
}),
// : _children[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
backgroundColor: Colors.green[100],
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.book_online),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.read_more),
label: 'Settings',
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
label: 'Profile',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.green[800],
onTap: _onItemTapped,
),
);
}
}
You canretrieve data from firebase firestore database and display it in the application directly.
SteamBuilder(
steam:query(FirebaseFirestore.instance.collection('collection_name').
doc('doc_id').snapshot());
builder(context,snapshot){
return Text(snapshot.data.docs[0].get('field');
}
)

Cant Figure Out How To display Only the post details for the post I have clicked on

So I have this code here and I would like to display post details from firebase for the post which I have clicked on, but instead, it lists post details for every single post in the database one after another.
Can anyone help me figure out how I can make it so that when A post is clicked, details will show for only the post which was clicked, and not for all of the posts? Any help would be greatly appreciated, thank you.
The Info I would like to display on the post is
postTitle
postDesc
postAuthor
Here is what the firebase looks like
Code Here:
import 'package:tennis_event_app/services/crud.dart';
import 'package:tennis_event_app/views/create_blog.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
CrudMethods crudMethods = new CrudMethods();
QuerySnapshot? blogSnapshot;
#override
void initState() {
crudMethods.getData()?.then((result) {
blogSnapshot = result;
setState(() {});
});
super.initState();
}
Widget blogsList() {
return Container(
child: ListView.builder(
padding: EdgeInsets.only(top: 24),
itemCount: blogSnapshot!.docs.length,
itemBuilder: (context, index) {
return BlogTile(
author: blogSnapshot!.docs[index].get('author'),
title: blogSnapshot!.docs[index].get('title'),
desc: blogSnapshot!.docs[index].get('desc'),
imgUrl: blogSnapshot!.docs[index].get('imgUrl'),
);
},
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Flutter",
style: TextStyle(fontSize: 22),
),
Text(
"Blog",
style: TextStyle(fontSize: 22, color: Colors.blue),
)
],
),
backgroundColor: Colors.transparent,
elevation: 0.0,
),
body: Container(
child: blogSnapshot != null
? blogsList()
: Container(
child: Center(
child: CircularProgressIndicator(),
))),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => CreateBlog()));
},
),
);
}
}
class BlogTile extends StatelessWidget {
final String imgUrl, title, desc, author;
BlogTile(
{required this.author,
required this.desc,
required this.imgUrl,
required this.title});
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 16, right: 16, left: 16),
child: Stack(
children: <Widget>[
Container(
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(8)),
child: Image.network(
imgUrl,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
height: 170,
),
),
),
Container(
height: 170,
decoration: BoxDecoration(
color: Colors.black45.withOpacity(0.3),
borderRadius: BorderRadius.circular(6)),
),
Container(
height: 170,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
title,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
),
SizedBox(height: 4),
Text(
'$desc',
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w400),
),
SizedBox(
height: 4,
),
Text(author),
],
)),
Container(
child: SizedBox(
height: 170,
width: MediaQuery.of(context).size.width,
child: TextButton(
style: TextButton.styleFrom(
textStyle: const TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => DetailPage()));
},
child: const Text(''),
),
),
),
],
),
);
}
}
class DetailPage extends StatefulWidget {
#override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
CrudMethods crudMethods = new CrudMethods();
QuerySnapshot? blogSnapshot;
#override
void initState() {
crudMethods.getData()?.then((result) {
blogSnapshot = result;
setState(() {});
});
super.initState();
}
Widget blogsList2() {
return Container(
child: ListView.builder(
padding: EdgeInsets.only(top: 24),
itemCount: blogSnapshot!.docs.length,
itemBuilder: (context, index) {
return PageContent(
postAuthor: blogSnapshot!.docs[index].get('postAuthor'),
postTitle: blogSnapshot!.docs[index].get('postTitle'),
postDesc: blogSnapshot!.docs[index].get('postDesc'),
imgUrl: blogSnapshot!.docs[index].get('imgUrl'),
);
},
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Flutter",
style: TextStyle(fontSize: 22),
),
Text(
"Blog",
style: TextStyle(fontSize: 22, color: Colors.blue),
)
],
),
backgroundColor: Colors.transparent,
elevation: 0.0,
),
body: Container(
child: blogSnapshot != null
? blogsList2()
: Container(
child: Center(
child: CircularProgressIndicator(),
))),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => CreateBlog()));
},
),
);
}
}
class PageContent extends StatelessWidget {
final String imgUrl, postTitle, postDesc, postAuthor;
PageContent(
{required this.postAuthor,
required this.postDesc,
required this.imgUrl,
required this.postTitle});
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 16, right: 16, left: 16),
child: Card(
child: ListTile(
title: Text(
postTitle,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
),
subtitle: Text(
'$postDesc',
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w400),
),
)
)
);
}
}
I also reference crud.dart in that code, so incase you need it, here it is:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:collection';
class CrudMethods {
Future<void> addData(blogData) async {
print(blogData);
FirebaseFirestore.instance
.collection("blogs")
.add(blogData)
.then((value) => print(value))
.catchError((e) {
print(e);
});
}
getData() async {
return await FirebaseFirestore.instance
.collection("blogs")
.orderBy("ts", descending: true)
.get();
}
}
Thank you again for any help!
First I would recommend to modelize your data in an object for exemple a class Article that is easier to serialize and manipulate.
Then instead of requesting another time the database you should save your data in a List<Article> for example then you only update this list on refresh from your main page. That way you don'y manipulate a QuerySnapshot or Future but just your list of objects.
Finally and to answer your question, you could simply pass the clicked item Article to your details page and only display its content. Because here, you have the same construction as your main page with the same request that is resent.
Usually you can build your route like that (adding a parameter to your details with the index you clicked on for example)
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => DetailPage(article: _data[i])));
},
Here is an article on serialization from Flutter docs, it shows how to build your model with the toMap, toJson and fromJson methods.

How to Send Images in chat

I'm working on a chat room and I want to enable users send photos in chat. But I don't seem to be getting a hang of it.
I have the image picker widget, but I'm still yet to implement it cos I can't get a hang of it.
Here is the code to the chat screen and a photo as well. I have initialised Firebase properly and everything is working fine, messages are sending, and all. But I want to implement a message send feature into the project.
import 'package:chat/constants.dart';
import 'package:chat/utilities/constants.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:chat/models/auth.dart';
import 'package:chat/models/message.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class ChatScreen extends StatefulWidget {
final AuthImplementation auth;
final VoidCallback signedOut;
ChatScreen({
this.auth,
this.signedOut,
});
#override
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
final Firestore _firestore = Firestore.instance;
TextEditingController messageController = TextEditingController();
ScrollController scrollController = ScrollController();
String userName;
#override
void initState() {
super.initState();
widget.auth.getCurrentUserEmail().then((email) {
setState(() {
final String userEmail = email;
final endIndex = userEmail.indexOf("#");
userName = userEmail.substring(0, endIndex);
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: new Container(
padding: new EdgeInsets.all(8.0),
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage("assets/images/social-logo.png"),
fit: BoxFit.fill),
color: Colors.white,
borderRadius: new BorderRadius.all(new Radius.circular(80.0)),
border: new Border.all(
color: Colors.white,
width: 1.0,
),
),
),
title: Text("One Gov FX Signal Room",
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.bold,
fontFamily: 'Spartan',
)),
backgroundColor: kPrimaryColor,
actions: <Widget>[
IconButton(
icon: FaIcon(FontAwesomeIcons.signOutAlt),
color: Colors.white,
onPressed: logOut),
],
),
backgroundColor: antiFlashWhite,
body: Column(
children: <Widget>[
Container(
color: Colors.white,
padding: EdgeInsets.only(left: 10, right: 0, bottom: 10, top: 10),
child: Row(
children: [
CircleAvatar(
backgroundColor: Colors.white,
backgroundImage: AssetImage("assets/images/social-logo.png"),
),
SizedBox(
width: 50,
),
Flexible(
child: Column(children: const <Widget>[
Text('Message From the Admins'),
Text(
'Keep your messages polite and do not abuse the channel. Try to keep your discussions within the community guidelines'),
]),
)
],
),
),
Expanded(
child: Container(
//margin: EdgeInsets.symmetric(horizontal: 5),
child: StreamBuilder<QuerySnapshot>(
stream: _firestore
.collection("messages")
.orderBy(
"timestamp",
)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData)
return Center(
child: CircularProgressIndicator(
backgroundColor: kPrimaryColor,
),
);
List<DocumentSnapshot> docs = snapshot.data.documents;
List<Widget> messages = docs
.map((doc) => Message(
user: doc.data['user'],
text: doc.data['text'],
timestamp: doc.data['timestamp'],
mine: userName == doc.data['user'],
))
.toList();
return ListView(
controller: scrollController,
children: messages,
);
}),
),
),
Container(
color: Colors.white,
child: Row(
children: <Widget>[
IconButton(
icon: FaIcon(
FontAwesomeIcons.image,
color: kPrimaryColor,
),
onPressed: sendChat,
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(10),
child: TextField(
style: TextStyle(
fontFamily: 'Poppins',
fontSize: 15,
),
onSubmitted: (value) => sendChat(),
controller: messageController,
keyboardType: TextInputType.multiline,
textInputAction: TextInputAction.newline,
maxLines: null,
cursorColor: kPrimaryColor,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20)),
filled: true,
hintText: "Say Something. Be Nice...",
hintStyle:
TextStyle(fontFamily: 'Montserrat', fontSize: 12),
),
),
),
),
IconButton(
icon: FaIcon(
FontAwesomeIcons.paperPlane,
color: kPrimaryColor,
),
onPressed: sendChat,
),
],
),
),
],
),
);
}
void logOut() async {
try {
await widget.auth.signOut();
widget.signedOut();
} catch (e) {
print("error :" + e.toString());
}
}
Future<void> sendChat() async {
if (messageController.text.length > 0) {
await _firestore.collection("messages").add({
'user': userName,
'text': messageController.text,
'timestamp': FieldValue.serverTimestamp(),
});
messageController.clear();
scrollController.animateTo(scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 300), curve: Curves.easeOut);
}
}
}
Screenshot of the chat screen:
To send images in a chat, you need a place to host those images. One way of doing this is by using file hosting services like Firebase Cloud Storage. This boils down to these steps.
Upload images on Cloud Storage. The image paths from the
device's local storage can be fetched using image_picker
Store the Cloud Storage path of the uploaded image i.e. using Cloud
Firestore
Display the image from the Cloud Storage path using Image.network()

Flutter problem size icon in tabbar in appbar?

I have a little problem I can't find the solution.
I created a TABBAR in an APPBAR, but I cannot resize it so that my icon of my tabbar is visible.
My tabbar its ok, but size of icon and tab not good...
I tried several ways but none worked ...
My problem: My probleme
My code:
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
TabController _tabcontroller;
#override
void initState() {
super.initState();
_tabcontroller = new TabController(length: 3, vsync: this);
_tabcontroller.addListener(() {
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
automaticallyImplyLeading: false,
elevation: 1,
title: new TabBar(
indicatorColor: Colors.transparent,
controller: _tabcontroller,
tabs: [
new SafeArea(
child: new Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(20.0)),
child: Center(
child: new Icon(
Icons.icecream,
color: _tabcontroller.index == 0
? Theme.of(context).primaryColor
: Colors.grey,
size: ScreenUtil().setSp(80.0),
),
),
),
),
new SafeArea(
child: new Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(20.0)),
child: Center(
child: new Icon(
Tinder_clone.iconfinder_338_tinder_logo_4375488__1_,
color: _tabcontroller.index == 1
? Theme.of(context).primaryColor
: Colors.grey,
size: ScreenUtil().setSp(80.0),
),
),
),
),
new SafeArea(
child: new Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(20.0)),
child: Center(
child: new Icon(
Tinder_clone.iconfinder_message_01_186393,
color: _tabcontroller.index == 2
? Theme.of(context).primaryColor
: Colors.grey,
size: ScreenUtil().setSp(80.0),
),
),
),
),
]),
),
Thanks for your help,
When placing TabBar within the AppBar, you should use the bottom property.
// ... other lines
return new Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
automaticallyImplyLeading: false,
elevation: 1,
bottom: new TabBar(
indicatorColor: Colors.transparent,
controller: _tabcontroller,
// ... other lines

Resources