Is there a way to put tabs inside a drawer in Flutter? - android

I currently am new in Flutter and is looking for help for a feature I'm trying to implement. I have too many information in my drawer currently so I am trying to put tabs inside the drawer so people can access different kinds of information inside the drawer. I photoshopped a picture to show the idea that I have in my head. Drawer with Tab Pictures shown here. So far, I've tried the DefaultTabController but couldn't get it to work so if anyone has any other ideas or a different way of approaching it I would be really grateful.
Thanks in advance!

You can copy paste run full code below
You can wrap DefaultTabController with Drawer
code snippet
return Scaffold(
...
drawer: Drawer(
child: DefaultTabController(
length: 3,
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
),
Container(
height: 50,
color: Colors.black12,
child: TabBar(
labelColor: Colors.deepOrange,
unselectedLabelColor: Colors.white,
tabs: [
Tab(text: "First"),
Tab(text: "Second"),
Tab(text: "Third"),
]),
),
Expanded(
child: Container(
color: Colors.green,
child: TabBarView(children: [
Container(
child: Text("First Body"),
),
Container(
child: Text("Second Body"),
),
Container(
child: Text("Third Body"),
),
]),
),
),
],
),
),
),
working demo
full 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,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
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),
),
drawer: Drawer(
child: DefaultTabController(
length: 3,
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
),
Container(
height: 50,
color: Colors.black12,
child: TabBar(
labelColor: Colors.deepOrange,
unselectedLabelColor: Colors.white,
tabs: [
Tab(text: "First"),
Tab(text: "Second"),
Tab(text: "Third"),
]),
),
Expanded(
child: Container(
color: Colors.green,
child: TabBarView(children: [
Container(
child: Text("First Body"),
),
Container(
child: Text("Second Body"),
),
Container(
child: Text("Third Body"),
),
]),
),
),
],
),
),
),
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

Unexpected Line between Containers Flutter

Many Times in flutter I Found a Line between two Containers in flutter.
Code example
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Column(
children: [
Container(
color: Colors.red,
width: double.infinity,
child: Column(
children: [
Container(
height: 150,
child: const Center(
child: Text('cdccd'),
),
),
Container(
height: 20,
color: Colors.red,
),
buildSeperator()
],
),
),
Container(
height: 300,
width: double.infinity,
child: Text('cdcdcd'),
),
],
),
),
);
}
///Build Seperator
Widget buildSeperator() {
return Stack(
children: [
Container(
height: 24,
color: Colors.red,
),
Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
topRight: Radius.circular(50),
),
color: Colors.white,
),
height: 24,
width: double.infinity,
),
],
);
}
}
Reference Image:
If It's a Flutter Issue: Flutter Team Request you to Resolve it.
Work Around but not final Solution,
Add Another Container Above the Container with a border with a higher height.
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
backgroundColor: Color(0xFF842247),
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Column(
children: [
Container(
color: const Color(0xFF842247),
height: 56,
),
Container(
color: const Color(0xFF842247),
width: double.infinity,
child: Column(
children: [
Container(
height: 24,
child: const Center(
child: Text('cdccd'),
),
),
buildSeperator()
],
),
),
Container(
height: 300,
// width: double.infinity,
child: Text('cdcdcd'),
),
],
),
),
);
}
///Build Seperator
Widget buildSeperator() {
return Stack(
clipBehavior: Clip.none,
children: [
Container(
height: 24,
color: const Color(0xFF842247),
),
Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
topRight: Radius.circular(50),
),
color: Colors.white,
),
height: 24,
width: double.infinity,
),
],
);
}
}

How to slide pages under appbar flutter

I've been trying so hard to build page view system for quotes app. I want the page to flow full screen from top to bottom and bottom to top scrollable/swipe able to navigate between different quotes each time
like this. The scroll will bring new page each time its not casual scroll. I haven't found any guide regarding this on internet so far.
I don't know about how to build it, nothing is popping in my mind for days now. I've tried pageview with gesture detector for swiping up and down, it doesn't works as desired and appbar is static too and the bottom containers as well I don't want this. What I want is the page/screen to flow under the appbar or even a button on top right corner and under 2 buttons on the bottom.
Create a column of Containers where each Container's height and width equals the height and width of the screen. You can do that by using:
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
Also, make sure to wrap your code with a SingleChildScrollView widget to scroll vertically.
Here's the code:
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(child: Text('Quote number one')),
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(icon: Icon(Icons.share), onPressed: () {}),
IconButton(
icon: Icon(Icons.favorite), onPressed: () {})
],
),
)
],
),
),
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
children: [
Text('Quote number two'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(icon: Icon(Icons.share), onPressed: () {}),
IconButton(icon: Icon(Icons.favorite), onPressed: () {})
],
)
],
),
)
],
),
),
),
);
}
}
You can use PageView to get this type of view
Drive Video link
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
PageController pageController;
PageView pageView;
List<String> quotes = [
'#Quote 1\n\n“I\'m selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can\'t handle me at my worst, then you sure as hell don\'t deserve me at my best.” ',
'#Qoute 2\n\nSo many books, so little time.',
'#Quote 3\n\n A room without books is like a body without a soul'
];
#override
void initState() {
super.initState();
pageController = PageController();
final _quotes = List.generate(quotes.length, (index) => quoteWidget(index));
pageView = PageView(
children: _quotes,
controller: pageController,
scrollDirection: Axis.vertical,
);
}
Widget quoteWidget(int index) {
return Scaffold(
backgroundColor: Colors.black,
body: Column(
children: [
Expanded(
flex: 3,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Center(
child: Text(
quotes[index],
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w300,
color: Colors.white,
),
),
),
),
),
Expanded(
flex: 1,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
FloatingActionButton(
onPressed: () {},
child: Icon(Icons.share),
),
const SizedBox(width: 20),
FloatingActionButton(
onPressed: () {},
child: Icon(Icons.favorite_border),
),
],
),
),
Expanded(child: Container())
],
),
);
}
#override
void dispose() {
pageController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
brightness: Brightness.dark,
title: Text(widget.title),
),
body: SafeArea(
child: Stack(
alignment: Alignment.bottomCenter,
children: [
pageView,
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: Row(
children: [
RaisedButton.icon(
icon: Icon(Icons.menu_book),
label: Text('General'),
onPressed: () {},
),
const Spacer(),
Container(
width: 50,
height: 50,
margin: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
child: Icon(Icons.color_lens),
),
Container(
width: 50,
height: 50,
margin: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
child: Icon(Icons.person),
),
],
),
)
],
),
),
);
}
}

Open page two inside the body of page one using Cupertino Segmented Control

I am using Cupertino Segmente Control , I created a tab using three swings and assigned three widgets to the front page body. When selecting any of the tabs, it displays the body of the new widget. So far, everything works fine. Products are loaded inside each page, and when we select a product, it must go to the second page .The second page opens, but inside the body of the first page. If you help me, thank you very much
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int groohEntkhabi = 1;
final Map<int, Widget> logoBala = const <int, Widget>{
0: Text("کشاورزی" ,style: TextStyle(fontSize: 14),),
1: Text("خرید فروش" ,style: TextStyle(fontSize: 14),),
2: Text("رهن و اجاره" ,style: TextStyle(fontSize: 14),),
};
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.blue),
//centerTitle: true,
title: Container(
child: Row(
children: [
Expanded(
child: CupertinoSegmentedControl(
padding: EdgeInsets.all(0.0),
groupValue: groohEntkhabi,
onValueChanged: (changeFromGroupValue) {
setState(() {
groohEntkhabi = changeFromGroupValue;
});
},
children: logoBala,
),
),
],
)
),
actions: [
IconButton(icon: Icon(Icons.search), onPressed: (){}),
],
),
drawer: MyDraver(),
bottomNavigationBar: MyBottomNavigation(),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {}, label: Text("ثبت رایگان آگهی",style: TextStyle(color: Colors.white),), icon:Icon(Icons.add,color: Colors.white,),backgroundColor: Colors.blue,
),
// floatingActionButton: FloatingActionButton(onPressed: (){
// // Navigator.of(context).push(MaterialPageRoute(
// // builder: (context) => Shoab()
// // ));
// },
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
// backgroundColor: Colors.deepOrange,
// child:Center(child: Text("ثبت رایگان آگهی")),),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
body:
(
_childern(groohEntkhabi)
),
),
);
}
Widget _childern(index){
List<Widget> page_screen=[];
page_screen.add(_keshavarzi());
page_screen.add(kharidFroosh());
page_screen.add(_ejare());
return page_screen[index];
}
Widget kharidFroosh(){
return MaterialApp(
debugShowCheckedModeBanner: false,
localizationsDelegates: [
// ... app-specific localization delegate[s] here
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''), // farsi
],
home: ListView.builder(padding: EdgeInsets.only(top: 3.0,left: 3.0,right: 3.0),
itemBuilder: mycard_view1,itemCount: 5,));
}
Widget mycard_view1(BuildContext context ,int index){
String mogheiatt ="کوی ملا نفس";
String mogheiat = mogheiatt.length>14 ? mogheiatt.substring(0,14):mogheiatt;
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),),
elevation: 1.0,
//color: Colors.blue,
child: InkWell(
onTap: (){
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => Safhe2_kharid_froosh()));
},
child: Stack(
children: <Widget> [
Container(margin: EdgeInsets.fromLTRB(50.0, 5.0, 5.0, 5.5),
height: 160.0,
width: double.infinity,
decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(20.0)),
child: Padding(
padding: EdgeInsets.fromLTRB(100.0,10.0,10.0,2.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Text("فروش ویلایی",style: TextStyle(fontFamily: "shabnammedium",fontSize: 15.0),),
SizedBox(
height: 7.0,
),
Text("قیمت : 850 م تومان",style: TextStyle(fontFamily: "shabnammedium",fontSize: 15.0),),
SizedBox(
height: 7.0,
),
Text("متراژ : 85 متر ",style: TextStyle(fontFamily: "shabnammedium",fontSize: 15.0),),
SizedBox(
height: 30.0,
),
Row(
//crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
decoration: BoxDecoration(color: Color(0xffe1f5fe),borderRadius: BorderRadius.circular(10.0),),
child: Center(child: Padding(
padding: EdgeInsets.only(left: 3.0,right: 3.0),
child: Row(
children: [
Text("روز پیش",style: TextStyle(fontFamily: "shabnamlight",color: Colors.black87),),
Text("5",style: TextStyle(fontFamily: "shabnamlight",color: Colors.black87),),
],
),
)),
// width: 70.0,
),
Container(
child: Row(
children: [
Text("...",style: TextStyle(fontFamily: "shabnamlight",color: Colors.black87),),
Text(mogheiat,style: TextStyle(fontFamily: "shabnamlight",color: Colors.black87),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
//width: 100.0,
),
],
),
],
),
),
),
Positioned(
left: 10.0,
top: 5.0,
bottom: 5.0,
child: ClipRRect(borderRadius: BorderRadius.circular(15.0),
child:Image.asset("images/home.jpg",width: 130,fit: BoxFit.cover,),
),
),
],
),
),
);
}
Widget _keshavarzi(){
return Keshavarzi();
}
Widget _ejare(){
return Ejare();
}
}
this is my images app
this is my secend page inside a first page body
and this my first pages

Flutter Drawer: Is it possible to scroll only part of the drawer?

I'm trying to build an app where you could open a drawer and scroll only content below DrawerHeader(). When I have DrawerHeader as a child of ListView, naturally it scrolls with the whole list. I've tried
Drawer(child:Column(children: <Widget>[DrawerHeader(), ListView()]))
but seems that it crashes the app.
test drawer
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text('Projects related tools'),
decoration: BoxDecoration(color: Colors.blue),
),
ExpansionTile(
title: Text('Project 1'),
children: <Widget>[
Text('Property 1'),
Text('Property 2'),
],
),
],
),
),
body: SafeArea(child: ListView()),
));
}
}
Wrap your ListView with an Expanded:
Drawer(
child: Column(
children: <Widget>[
DrawerHeader(
...
),
Expanded(
child: ListView(
...
),
),
],
),
),

Custom button with FAB style

I want to make a set of buttons with the ripple effect, elevation and shape like a FAB button. I read that I can only use one FAB button per screen, so I need to create my owns instead of using a set of FAB buttons.
How can I achieve the effect? It's possible to modify the FAB code to this?
So if you want the fabs in a vertical order wrap them in a Column like this
class RandomFabScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FloatingActionButton(
child: Icon(Icons.home, color: Colors.white,),
onPressed: (){},
backgroundColor: Colors.cyan,
),
SizedBox(height: 10,),
FloatingActionButton(
child: Icon(Icons.playlist_play, color: Colors.white,),
onPressed: (){},
backgroundColor: Colors.red,
),
SizedBox(height: 10,),
FloatingActionButton(
child: Icon(Icons.person, color: Colors.white,),
backgroundColor: Colors.yellow,
onPressed: (){},
),
SizedBox(height: 10,),
FloatingActionButton(
child: Icon(Icons.warning, color: Colors.white,),
onPressed: (){},
backgroundColor: Colors.blue,
),
],
),
);
}
}
The output:
And if you want them in the horizontal order, wrap them in a Row
like this
class RandomFabScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FloatingActionButton(
child: Icon(Icons.home, color: Colors.white,),
onPressed: (){},
backgroundColor: Colors.cyan,
),
SizedBox(width: 10,),
FloatingActionButton(
child: Icon(Icons.playlist_play, color: Colors.white,),
onPressed: (){},
backgroundColor: Colors.red,
),
SizedBox(width: 10,),
FloatingActionButton(
child: Icon(Icons.person, color: Colors.white,),
backgroundColor: Colors.yellow,
onPressed: (){},
),
SizedBox(width: 10,),
FloatingActionButton(
child: Icon(Icons.warning, color: Colors.white,),
onPressed: (){},
backgroundColor: Colors.blue,
),
],
),
);
}
}
The output:
You can use Row to wrap FloatingActionButton
code snippet
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FloatingActionButton(
onPressed: () {
print("click 1");
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
),
FloatingActionButton(
onPressed: () {
print("click 2");
},
child: Icon(Icons.event),
backgroundColor: Colors.red,
),
FloatingActionButton(
onPressed: () {
print("click 3");
},
child: Icon(Icons.gradient),
backgroundColor: Colors.yellow,
),
FloatingActionButton(
onPressed: () {
print("click 4");
},
child: Icon(Icons.album),
backgroundColor: Colors.blue,
),
]),
working demo
full 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(title: 'Flutter Demo Home Page'),
);
}
}
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>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FloatingActionButton(
onPressed: () {
print("click 1");
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
),
FloatingActionButton(
onPressed: () {
print("click 2");
},
child: Icon(Icons.event),
backgroundColor: Colors.red,
),
FloatingActionButton(
onPressed: () {
print("click 3");
},
child: Icon(Icons.gradient),
backgroundColor: Colors.yellow,
),
FloatingActionButton(
onPressed: () {
print("click 4");
},
child: Icon(Icons.album),
backgroundColor: Colors.blue,
),
]),
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),
),
);
}
}

Categories

Resources