This is my widget tree,
Before adding center,
After adding center,
My code showing the SignInButton and other things in tree to reproduce the issue.,
class SignInButton extends StatelessWidget {
SignInButton({Key? key, required this.onPressed}) : super(key: key);
final void Function() onPressed;
#override
Widget build(BuildContext context) {
return ElevatedButton.icon(
onPressed: onPressed,
icon: Image(
image: AssetImage("assets/images/google.png"),
color: null,
height: 20,
),
style: ElevatedButton.styleFrom(
primary: Colors.white, onPrimary: Colors.black),
label: Text("Sign in with Google"));
}
}
Scaffold(
backgroundColor: Colors.indigo,
body: Center(
child: Wrap(
alignment: WrapAlignment.center,
direction: Axis.vertical,
spacing: 5,
children: [
SizedBox(
width: MediaQuery.of(context).size.width,
child: Text(
'Text',
style: TextStyle(
color: Colors.orange.shade400,
fontSize: 26,
),
textAlign: TextAlign.center,
),
),
SizedBox(
width: MediaQuery.of(context).size.width,
child: Center(
child: SignInButton(onPressed: () async {
User? user =
await Authentication.signInWithGoogle(context: context);
Navigator.push(
context,
MaterialPageRoute(
builder: ((context) => SignUpScreen())));
}),
),
),
],
),
),
);
After adding code of Center widget, the sign in button just disappears. I am not sure why this is happening, it is available in tree of Flutter Inspector.
It looks like there is no bound in height axis. Please try to define some value to height, in SizedBox or inside SignInButton.
Related
I need to use a GestureDetector because it can detect many more types of user interactions than InkWell, but unlike InkWell it doesn't provide any visual response when a user taps or long presses on it.
Is it possible to add a ripple effect for tap/long press while still handling user interactions in the GestureDetector?
Just use this plugin
touch_ripple_effect: ^2.2.4
Touch ripple effect
TouchRippleEffect(
borderRadius: _helloRadius,
rippleColor: Colors.white60,
onTap: (){
print("Anand !");
},
child: Container(
width: 110,
height: 50,
alignment: Alignment.center,
decoration: BoxDecoration(color: Colors.pink, borderRadius: _helloRadius),
child: IconButton(
iconSize: 24.0,
icon: Icon(Icons.search,color: Colors.white, size: 36,),
onPressed: null
),)
),
Touch Feedback effect
TouchFeedback(
onTap: (){
print(" I am Aditya");
},
rippleColor: Colors.blue[200],
child: Container(
width: 120,
height: 40,
alignment: Alignment.center,
decoration: BoxDecoration(color: Colors.yellow, borderRadius: BorderRadius.circular(5),),
child: Text(
"Hit me !",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)
)
),
)
if you want a quick hack, check this:
class Test extends StatelessWidget {
const Test({
Key? key,
this.onTap,
}) : super(key: key);
final void Function()? onTap;
#override
Widget build(BuildContext context) {
final width = MediaQuery.of(context).size.width;
return Scaffold(
body: GestureDetector(
onTap: onTap,
child: SizedBox(
width: width * 0.2,
height: 70,
child: Card(
color: Colors.red,
child: InkWell(
onTap: () {},
),
),
),
),
);
}
}
Try the following code:
InkWell(
onLongPress: () {
// Do what you want to do
},
child: child,
),
I am using ShowModalBottomSheet . I want to open it from left side not from bottom in flutter..
To achieve you desire UI requirements , you should create a custom modal sheet.
It is very simple , you just have to make a container and use tween animation to make it visible and it works like a modal sheet,You can change the direction of the container from its start animating and many more.
I will try to add a code for it later.
This package help you to achieve side modal sheet.
https://pub.dev/packages/side_sheet
Or there is one more way, you should visit this link,I hope it will fullfill your requirements.
https://pub.dev/packages/modal_side_sheet
I think the first package can be more helpfull for you because it has some customization options like you can choose the side etc.
in case someone still needs help. You can use a combination of overlay and Tween to create a custom side sheet.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Custom Sidesheet',
theme: ThemeData(useMaterial3: true),
home: const MyHomePage(title: 'Custom Sidesheet'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
OverlayEntry? sideSheetOverlayEntry;
final sideSheetOverlayLayerLink = LayerLink();
bool isSidebarShown = false;
#override
void initState() {
super.initState();
}
void showSideSheet() {
final sideSheetOverlay = Overlay.of(context)!;
sideSheetOverlayEntry = OverlayEntry(
builder: (context) => Positioned(
height: MediaQuery.of(context).size.height,
child: isSidebarShown
? CompositedTransformFollower(
link: sideSheetOverlayLayerLink,
child: TweenAnimationBuilder(
tween: Tween<double>(begin: 150, end: 300),
duration: const Duration(milliseconds: 300),
builder: (BuildContext context, double size, Widget? child) {
return Material(
child: SafeArea(
child: Container(
width: size,
padding: const EdgeInsets.all(10.0),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
InkWell(
onTap: () {
setState(() {
isSidebarShown = false;
showSideSheet();
});
},
onHover: (value) {},
child: const Icon(
Icons.close,
color: Colors.redAccent,
size: 25.0,
),
)
],
),
Column(
children: [
Container(
child: Text(
"Custom Side Sheet",
overflow: TextOverflow.ellipsis,
style: const TextStyle(color: Colors.blueGrey),
),
),
const Divider(
height: 5.0,
color: Colors.black,
),
Container(
child: Row(children: [
Icon(
Icons.dashboard,
size: 25.0,
color: Colors.blueGrey,
),
Text(
"Home",
overflow: TextOverflow.ellipsis,
style: TextStyle(color: Colors.blueGrey, fontSize: 25.0, fontWeight: FontWeight.w300),
)
]),
)
],
)
],
)),
),
);
},
))
: SizedBox.shrink(),
),
);
sideSheetOverlay.insert(sideSheetOverlayEntry!);
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
leading: GestureDetector(
onTap: () {
setState(() {
isSidebarShown = true;
showSideSheet();
});
},
child: Icon(
Icons.menu_sharp,
size: 30.0,
),
),
),
body: Container(
color: Color.fromRGBO(223, 230, 233, 1.0),
)),
);
}
}
side sheet not active image
side sheet active image
How can I make individual buttons turn grey when I click on approve?
The screenshot is below
Below is the List Tile widget code
Widget pendingList({
required String title,
required String subtitle,
required String leading,
onTap,
}) {
return Row(
children: [
Expanded(
flex: 6,
child: Card(
child: ListTile(
leading: Container(
padding: const EdgeInsets.only(left: 15.0),
alignment: Alignment.center,
height: 50,
width: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.0),
image: DecorationImage(
image: NetworkImage(
'therul'),
fit: BoxFit.cover,
),
),
),
title: Text(
title,
style: TextStyle(
fontSize: BtnFnt2,
fontWeight: FontWeight.w600,
),
),
subtitle: Text(
subtitle,
style: TextStyle(
fontSize: littleTexts,
),
),
),
),
),
Expanded(
flex: 2,
child: Bounce(
duration: const Duration(milliseconds: 100),
onPressed: onTap,
child: Container(
padding: const EdgeInsets.all(15.0),
color: appOrange,
child: Text(
'Approve',
style: TextStyle(
color: white,
fontWeight: FontWeight.w500,
),
),
),
),
),
],
);
}
How can I make individual buttons turn grey when I click on approve?
Any idea will be appreciated. Kindly refer to the screenshot and assist if you can.
One way, is to make the card into a stateful widget, like (simplified)
class ColorCard extends StatefulWidget {
const ColorCard({
Key? key,
}) : super(key: key);
#override
State<ColorCard> createState() => _ColorCardState();
}
class _ColorCardState extends State<ColorCard> {
Color col = Colors.white;
#override
Widget build(BuildContext context) {
return Card(
color: col,
child: ListTile(
title: const Text('title'),
subtitle: const Text('subtitle'),
trailing: ElevatedButton(
onPressed: () {
setState(() => col = Colors.grey);
},
child: const Text('click'),
),
),
);
}
}
Alternatively the color could be based on a value stored in an object that extends or 'mixin'-s ChangeNotifier if you want more comprehensive integration.
I am facing a problem with my custom app bar. I would like it to have a drawer but it doesn't work. I just don't know how to make it being able to open.
It is a custom app bar widget named Pasek (which stands for top bar in my language).
It has a logo picture which on click moves you to the first page of the app.
Next to it there is humburger menu with a drawer but I do not know why it doesn't work. I click on it and nothing happens.
Any ideas?
class Pasek extends StatelessWidget with PreferredSizeWidget {
#override
Size get preferredSize => Size.fromHeight(50.0);
const Pasek({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return AppBar(
actions: <Widget>[
Padding(
padding: EdgeInsets.only(right: 35.0),
child: ElevatedButton(
child: Icon(Icons.menu, color: Colors.white),
onPressed: () {
Scaffold(
endDrawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: const <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.black,
),
child: Text(
'Menu',
style: TextStyle(
color: Colors.pink,
fontSize: 24,
),
),
),
ListTile(
leading: Icon(Icons.message),
title: Text('Messages'),
),
ListTile(
leading: Icon(Icons.account_circle),
title: Text('Profile'),
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings'),
),
],
),
),
);
},
)),
],
backgroundColor: Colors.black,
title: GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => FirstPage(),
),
);
}, // Image tapped
child: Image.asset(
'images/logo.png',
fit: BoxFit.scaleDown,
height: 30,
width: 200,
),
));
}
}
im trying to make my button open up something similar to this: FAB version of what i want
This is what my code looks like:
return Card(
color: Colors.yellow[100],
child: ListTile(
trailing: IconButton(icon: Icon(Icons.more_vert),
onPressed: () {},
),
leading: Text(document['date'] + '\n' + document['time'], textAlign: TextAlign.center,),
subtitle: Text(
'Loctaion: ' + document['location'],
),
title: Text(document['name'],
textAlign: TextAlign.left, style: TextStyle(fontSize: 20.0)),
),
);
}
I want the IconButton to open up something similar to the SpeedDial, to make the user choose between accept, deny, or choose later for the event.
My ListTile with the Icon.more_vert that i want to be able to open a speeddial
You can copy paste run full code below
You can use https://pub.dev/packages/flutter_portal
Basically use Overlay and show circle button
You can change childAnchor and menuAnchor, and circle button size per your request
It's too long to describe all the detail, please see working demo and full code below
code snippet
ListTile(
trailing: IconButton(
icon: Icon(Icons.more_vert),
onPressed: () => setState(() => showMenu = true),
),
...
return ModalEntry(
visible: showMenu,
onClose: () => setState(() => showMenu = false),
childAnchor: Alignment.topRight,
menuAnchor: Alignment.bottomRight,
menu: Menu(
children: [
ClipOval(
child: Material(
color: Colors.blue, // button color
child: InkWell(
splashColor: Colors.red, // inkwell color
onTap: () {
setState(() => showMenu = false);
},
child: SizedBox(width: 40, height: 40, child: Icon(Icons.menu)),
),
),
),
working demo
full code
import 'package:flutter/material.dart';
import 'package:flutter_portal/flutter_portal.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
builder: (_, child) => Portal(child: child),
home: Scaffold(
appBar: AppBar(
title: const Text('Example'),
),
body: Container(
padding: const EdgeInsets.all(10),
alignment: Alignment.centerLeft,
child: ContextualMenuExample(),
),
),
);
}
}
class ContextualMenuExample extends StatefulWidget {
ContextualMenuExample({Key key}) : super(key: key);
#override
_ContextualMenuExampleState createState() => _ContextualMenuExampleState();
}
class _ContextualMenuExampleState extends State<ContextualMenuExample> {
bool showMenu = false;
#override
Widget build(BuildContext context) {
return ModalEntry(
visible: showMenu,
onClose: () => setState(() => showMenu = false),
childAnchor: Alignment.topRight,
menuAnchor: Alignment.bottomRight,
menu: Menu(
children: [
ClipOval(
child: Material(
color: Colors.blue, // button color
child: InkWell(
splashColor: Colors.red, // inkwell color
onTap: () {
setState(() => showMenu = false);
},
child: SizedBox(width: 40, height: 40, child: Icon(Icons.menu)),
),
),
),
ClipOval(
child: Material(
color: Colors.blue, // button color
child: InkWell(
splashColor: Colors.red, // inkwell color
onTap: () {
setState(() => showMenu = false);
},
child: SizedBox(
width: 40, height: 40, child: Icon(Icons.description)),
),
),
),
ClipOval(
child: Material(
color: Colors.blue, // button color
child: InkWell(
splashColor: Colors.red, // inkwell color
onTap: () {
setState(() => showMenu = false);
},
child: SizedBox(
width: 40, height: 40, child: Icon(Icons.settings)),
),
),
)
],
),
child: Container(
child: Card(
color: Colors.yellow[100],
child: ListTile(
trailing: IconButton(
icon: Icon(Icons.more_vert),
onPressed: () => setState(() => showMenu = true),
),
leading: Text(
"date time",
textAlign: TextAlign.center,
),
subtitle: Text(
'Loctaion',
),
title: Text('name',
textAlign: TextAlign.left, style: TextStyle(fontSize: 20.0)),
),
),
),
);
}
}
class Menu extends StatelessWidget {
const Menu({
Key key,
#required this.children,
}) : super(key: key);
final List<Widget> children;
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 10),
child: Card(
elevation: 8,
child: IntrinsicWidth(
child: Column(
mainAxisSize: MainAxisSize.min,
children: children,
),
),
),
);
}
}
class ModalEntry extends StatelessWidget {
const ModalEntry({
Key key,
this.onClose,
this.menu,
this.visible,
this.menuAnchor,
this.childAnchor,
this.child,
}) : super(key: key);
final VoidCallback onClose;
final Widget menu;
final bool visible;
final Widget child;
final Alignment menuAnchor;
final Alignment childAnchor;
#override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: visible ? onClose : null,
child: PortalEntry(
visible: visible,
portal: menu,
portalAnchor: menuAnchor,
childAnchor: childAnchor,
child: IgnorePointer(
ignoring: visible,
child: child,
),
),
);
}
}