Flutter FlatButton does not show tap animation / ripple effect - dart

I have the following code:
return new ListTile(
leading: new CircleAvatar(
backgroundColor: Colors.blue,
child: new Image.network(
"http://res.cloudinary.com/kennyy/image/upload/v1531317427/avatar_z1rc6f.png")),
title: new Row(
children: <Widget>[
new Expanded(child: new Text(message)),
new FlatButton(onPressed: null, child: new Text("Delete"))
]
),
subtitle: new Text(from),
);
which created a tile in my ListView.
Each tile should have a button.
When I tap the button - I don't see any ripple effect or animation that I actually clicked. I was pretty sure it's a part of the Material theme as a gesture for FlatButtons, but I tried a solution I found, using InkWell:
return new ListTile(
leading: new CircleAvatar(
backgroundColor: Colors.blue,
child: new Image.network(
"http://res.cloudinary.com/kennyy/image/upload/v1531317427/avatar_z1rc6f.png")),
title: new Row(
children: <Widget>[
new Expanded(child: new Text(message)),
InkWell(
child: FlatButton(onPressed: null, child: new Text("Delete"), color: Colors.amber))
]
),
subtitle: new Text(from),
);
But still - my listview button does not have any ripple effect when tapped.
Any idea?

Flutter buttons are disabled by default. To enable a button, set its onPressed or onLongPress properties to a non-null value.
The ripple is not visible because you've set the property of your onPressed to null.
new FlatButton(onPressed: null, child: new Text("Delete"))
Change the onPressed property to something like this:
new FlatButton(onPressed: (){}, child: new Text("Delete"))
To compare here is an example of a no-null onPressed and a null valued onPressed.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListTile(
leading: new CircleAvatar(
backgroundColor: Colors.blue,
child: new Image.network(
"http://res.cloudinary.com/kennyy/image/upload/v1531317427/avatar_z1rc6f.png")),
title: new Row(children: <Widget>[
//new Expanded(child: new Text(message)),
new TextButton(
onPressed: () {},
child: new Text("Delete"),
),
new TextButton(
onPressed: null,
child: new Text("Delete"),
)
]),
//subtitle: new Text(from),
),
);
}
}
*Note that the FlatButton is now deprecated so I've used TextButton in the example.

Related

Custom slider with emojis

I am building a flutter app and want to create a custom slider with emojis very similar to the reflectly app. I am attaching a screenshot , as you change the slider the emoji changes. I am pretty new to flutter and am struggling with the slider widget
You could do something like that:
I didn't use images for emojis faces but could put you in the right direction.
Full code:
import 'package:flutter/material.dart';
const _emojis = ['😃','😜','🤓','😁','😂','😞'];
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(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> {
double _value = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
decoration: BoxDecoration(
gradient: new LinearGradient(
colors: [Colors.teal, Colors.tealAccent],
begin: Alignment.bottomLeft,
end: Alignment.topRight
)
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'${_emojis[_value.toInt()]}',
style: Theme.of(context).textTheme.display1,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(_emojis[0], softWrap: true),
Expanded(
child: Slider(
value: _value,
//label: _emojis[_value.toInt()],
min: 0.0,
max: 5.0,
divisions: 5,
onChangeStart: (double value) {
print('Start value is ' + value.toString());
},
onChangeEnd: (double value) {
print('Finish value is ' + value.toString());
},
onChanged: (double value) {
setState(() {
_value = value;
});
},
activeColor: Colors.white,
inactiveColor: Colors.black45,
),
),
Text(_emojis[5], softWrap: true,)
],
),
),
),
],
),
),
),
);
}
}
This reviewpage animation is close to 90% of the reflectly animation.

Add on tap function flutter

hello guys i want to create an onTap option for my icon, my code is like this and I cant figure out how to do so can you help me.this is my code:
trailing: new Column(
children: <Widget>[
new Container(
child: new Icon(Icons.bookmark),
margin: EdgeInsets.only(top: 25.0),
)
],
),
Use IconButton instead.
new IconButton(
icon: new Icon(Icons.bookmark),
onPressed: () { /* Your code */ },
)
In your code, you can use like this
trailing: new Column(
children: <Widget>[
new Container(
child: new IconButton(
icon: new Icon(Icons.bookmark),
onPressed: () { /* Your code */ },
),
margin: EdgeInsets.only(top: 25.0),
)
],
),
Create the button and Wrap it in a GestureDetector with an onTap callback
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
final title = 'Gesture Demo';
return MaterialApp(
title: title,
home: MyHomePage(title: title),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
MyHomePage({Key key, this.title}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(child: MyButton()),
);
}
}
class MyButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
// Our GestureDetector wraps our button
return GestureDetector(
// When the child is tapped, show a snackbar
onTap: () {
final snackBar = SnackBar(content: Text("Tap"));
Scaffold.of(context).showSnackBar(snackBar);
},
// Our Custom Button!
child: Container(
padding: EdgeInsets.all(12.0),
decoration: BoxDecoration(
color: Theme.of(context).buttonColor,
borderRadius: BorderRadius.circular(8.0),
),
child: Text('My Button'),
),
);
}
}
Important : for user interactivity, you can use onPressed property.

How to customize the SliverAppBar widget in flutter?

I would like to add some more information in the green area, but when user scrolls up, I keep the _ SliverAppBar on the top..., like this:
Here is my current source code:
body: new CustomScrollView(slivers: <Widget>[
const SliverAppBar(
pinned: true,
expandedHeight: 300.0, // TODO: check out later
flexibleSpace: const FlexibleSpaceBar(
title: const Text('_SliverAppBar')
),
),
new SliverList(delegate: new SliverChildListDelegate(_galleryListItems()))
]),
The FlexibleSpaceBar has a background property the accepts any Widget
Use to build the information you need:
FlexibleSpaceBar(
title: Text('_SliverAppBar'),
background: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Info'),
],
),
),
Here is a more complete example that adds a subtitle and hides it when the user scrolls.
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'My Flutter Pad'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
const kExpandedHeight = 300.0;
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
leading: Icon(Icons.menu),
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.search),
highlightColor: Colors.white,
onPressed: () {},
),
],
expandedHeight: 200.0,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
background: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/bar.jpg"),
fit: BoxFit.cover)),
child: Column(
children: [
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('NEW GAME'),
Text('Sekiro: Shadows Dies Twice'),
RaisedButton(
onPressed: () {},
child: Text('Play'),
),
],
),
),
),
],
),
)),
),
];
},
body: Center(
child: Text("Sample Text"),
),
),
);
}
}

How to read data from Flutter elements

I've the below code for entering some data, I do not know how to handle it!
i.e. What shall I write at the onPressed for the IconButton so that the data is read from all the elements (name, birthday, ...)? and how to display it in Dialog to check if read correctly?
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.deepOrange,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var _value=false;
double _bodyHeight=0.0;
void onchange(bool value) {
setState(() {
_value = value;
this._bodyHeight = (value == true) ? 400.0 : 0.0;
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.grey[500],
appBar: new AppBar(
title: new Text(widget.title),
),
body: new SingleChildScrollView(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Card(
child: new Container(
height: 50.0,
child: new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new Text("Select me pls"),
new Switch(value: _value, onChanged: (bool value) => onchange(value)),
],
),
),
),
new Card(
child: new AnimatedContainer(
child: new ListView(
children: <Widget>[
new ListTile(
leading: const Icon(Icons.person),
title: new TextField(
decoration: new InputDecoration(
hintText: "Name",
),
),
),
new ListTile(
leading: const Icon(Icons.phone),
title: new TextField(
decoration: new InputDecoration(
hintText: "Phone",
),
),
),
new ListTile(
leading: const Icon(Icons.email),
title: new TextField(
decoration: new InputDecoration(
hintText: "Email",
),
),
),
const Divider(
height: 1.0,
),
new ListTile(
leading: const Icon(Icons.label),
title: const Text('Nick'),
subtitle: const Text('None'),
),
new ListTile(
leading: const Icon(Icons.today),
title: const Text('Birthday'),
subtitle: const Text('February 20, 1980'),
),
new IconButton(icon: const Icon(Icons.save),
onPressed: null
/*
*
* What shall I write here to read the data in the elements
*
*
*
* */
),
],
),
curve: Curves.easeInOut,
duration: const Duration(milliseconds: 500),
height: _bodyHeight,
// color: Colors.red,
),
),
],
),
),
);
}
}
One way is that TextFields take a property called TextEditingController which allow you to access the value of the TextField.
And to show a dialog you can just call showDialog() function.
class TextFieldExample extends StatefulWidget {
#override
_TextFieldExampleState createState() => new _TextFieldExampleState();
}
class _TextFieldExampleState extends State<TextFieldExample> {
TextEditingController c1;
TextEditingController c2;
#override
void initState() {
c1 = new TextEditingController();
c2 = new TextEditingController();
super.initState();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new TextField (
controller: c1,
),
new TextField(
controller: c2,
),
new OutlineButton(onPressed: () {
showDialog(child: new AlertDialog(
content: new Text("You entered ${c1.text} ${c2.text} ")
),
context: context
);
},
child: new Text("Show Dialog"),
)
],
),
),
);
}
}

How to hide drawer in flutter after changing Scaffold.body value

I am using the method in this question to change the body of a Scaffold in flutter:
Flutter Drawer Widget - change Scaffold.body content
The method described works perfectly. Now I would like just the drawer to automatically close after the users taps on one of the items.
I tried using the Navigator.pop() method, but it pops the entire screen, not just the drawer. It leaves me with a totally black screen.
Any suggestions?
Are you using exactly Navigator.of(context).pop()? I cannot reproduce your problem, can you post a minimal example to reproduce it?
The following code works as expected: the settings button pops away the drawer, while the other don't.
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String text = "Initial Text";
#override
Widget build(BuildContext context) {
return new Scaffold(
drawer: new Drawer(
child: new ListView(
children: <Widget>[
new Container(child: new DrawerHeader(child: new Container())),
new Container (
child: new Column(
children: <Widget>[
new ListTile(leading: new Icon(Icons.info),
onTap:(){
setState((){
text = "info pressed";
});
}
),
new ListTile(leading: new Icon(Icons.save),
onTap:(){
setState((){
text = "save pressed";
});
}
),
new ListTile(leading: new Icon(Icons.settings),
onTap:(){
setState((){
text = "settings pressed";
});
Navigator.of(context).pop();
}
),
]
),
)
],
),
),
appBar: new AppBar(title: new Text("Test Page"),),
body: new Center(child: new Text((text)),
));
}
}
create scaffoldKey
close drawer
_scaffoldKey.currentState.openEndDrawer(),
open drawer
scaffoldKey.currentState.openDrawer(),
Example
InkWell(
onTap: ()=> widget.scaffoldKey.currentState.openDrawer(),
child: Icon(
Icons.menu,
size: 38,
color: Color(0xFFFFFFFF),
),
),
If you are using a MaterialApp you need to use Scaffold.of(context).openEndDrawer() that way you do not need to create a GlobalKey.
class Menu extends StatelessWidget {
const Menu({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView(
padding: EdgeInsets.zero,
children: [
FlatButton(
onPressed: () {
Navigator.of(context).pushNamed('/');
Scaffold.of(context).openEndDrawer();
},
child: ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
),
),
FlatButton(
onPressed: () {
Navigator.of(context).pushNamed('/about');
Scaffold.of(context).openEndDrawer();
},
child: ListTile(
leading: Icon(Icons.question_answer),
title: Text('About'),
),
),
],
);
}
}
Simply:
ListTile(
title: const Text('Item 1'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),

Resources