Flutter Collapsible / Expansible card - flutter

I am trying to match this design
on tap the card should expand
I cannot use a card wrapping an expansion tile because the expansion tile is basically only one row, I was trying to follow this example
flutter_catalog
I googled a lot and could not find an example of what I am trying to achieve, the closest thing I could find on stackoverflow was this other question is there not in flutter a collapsible / expansible card?

You can absolutely use a Card wrapping an ExpansionTile. The ExpansionTile has a title property which takes a Widget so you can pass any Widget you want into it.
Messy example code, but hopefully you get the idea:
class ExpandedTile extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15.0))),
elevation: 2,
margin: EdgeInsets.all(12.0),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ExpansionTile(
backgroundColor: Colors.white,
title: _buildTitle(),
trailing: SizedBox(),
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Text("Herzlich Willkommen"),
Spacer(),
Icon(Icons.check),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Text("Das Kursmenu"),
Spacer(),
Icon(Icons.check),
],
),
)
],
),
),
);
}
Widget _buildTitle() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Text("MODUL 1"),
Spacer(),
Text("Mehr"),
],
),
Text("Kursubersicht"),
Row(
children: <Widget>[
Text("6 Aufgaben"),
Spacer(),
FlatButton.icon(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15.0))),
padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 8.0),
color: Colors.blue,
textColor: Colors.white,
onPressed: () {},
icon: Icon(Icons.play_arrow),
label: Text("Fortsetzen"),
),
],
),
],
);
}
}
produces
and when tapped

Related

How can I add shadow and frame to button

My button looks like this,
How can I convert it to this?
My Code:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.bubble_chart_rounded),
),
const Text('Rear Camera')
],
),
This might be the most simplest way to achieve what you're trying to do here.
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Card( // The widget that is providing that shadow with elevation perameter.
elevation: 8, // Controls the shadow you're wanting to get.
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(80), // To achieve the circular shape around your button.
),
child: Padding(
padding: EdgeInsets.all(10),
child: IconButton(
onPressed: () {},
icon: Icon(Icons.bubble_chart_rounded),
),
),
),
const Text('Rear Camera')
],
),

Flutter: How can i put the text widget center in screen

I need to put the title' in the center even to fit any screen, I know can I sized box to move the title in the center, but when using the different device the dimensions surely will change and become the title the different places.
this is code :
class NotificationDoctor extends StatelessWidget {
TextStyles textStyles = TextStyles.HEADING;
Texts texts;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColorDark,
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(15.0))),
height: 130.h,
child: Padding(
padding: EdgeInsets.only(top: 40.h),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.only(
right: 15.w,
top: 15.h,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
FlatButton(
child: ArrowIcon(
arrowColor: Color(0xFFEEF4F9),
backgroundColor:
Theme.of(context).primaryColor.withOpacity(.9),
),
onPressed: () {
Navigator.pop(context);
},
),
// SizedBox(
// width: 55,
// ),
Center(
child: Texts(
'Notifications',
style: TextStyles.HEADING,
color: Color(0xFFEEF4F9),
),
),
],
),
),
],
),
),
),
));
}
}
use the padding like this
Padding(
padding: EdgeInsets.symmetric(vertical: 5.h, horizontal: 3.h),
child: Container(),
);
read more at https://pub.dev/packages/sizer

How to have Text with Icon in center Flutter?

I am using a package fab_circular_menu, That package is for an animated floating action button which opens up a circular menu. within it I want a widget as a menu item such that there is an icon and a text below. the icon is centered with text.
e.g.
How can I achieve this, as of now I am using the code below but it does not work well with different screen size.
FlatButton(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100),
),
padding: EdgeInsets.only(bottom: 15),
onPressed: () async {
await _auth.signOut().then((value) {
Navigator.of(context).popUntil((route) => route.isFirst);
});
},
child: Stack(
overflow: Overflow.visible,
children: <Widget>[
Icon(Icons.power_settings_new),
Positioned(
bottom: -12,
right: -10,
child: Text('Logout'),
),
],
),
),
Another Solution which could use in many ways
Wrap(
direction: Axis.vertical,
crossAxisAlignment: WrapCrossAlignment.center,
children: <Widget>[
Icon(Icons.power_settings_new),
Text('Logout'),
],
),
You can achieve this result with Column widget instead of Stack.
Here is the example:
.....
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(Icons.power_settings_new),
Text('Logout'),
],
),
Short answer:
Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.call),
SizedBox(height: 4), // spacing between two
Text('Call Icon'),
],
)
Long answer:
Copy this class:
class TextWithIcon extends StatelessWidget {
final IconData icon;
final String text;
final double spacing;
const TextWithIcon({Key key, this.icon, this.text, this.spacing = 2}) : super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon),
SizedBox(height: spacing),
Text(text),
],
),
);
}
}
Usage:
TextWithIcon(
icon: Icons.call,
spacing: 6, // Space between icon and text
text: 'Call Icon',
)
You can use columns for this like:
FlatButton(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100),
),
padding: EdgeInsets.only(bottom: 15),
onPressed: () async {
await _auth.signOut().then((value) {
Navigator.of(context).popUntil((route) => route.isFirst);
});
},
child: Column(
children: <Widget>[
Icon(Icons.power_settings_new),
SizedBox(height:10), // set height according to your needs
Text('Logout'),
],
),
),

Fill ListView tiles vertically by a container - Flutter

I have been trying to put a line indicator on the left most margin of the card in my flutter app. I've tried a lot of things but didn't work.
There's an exact question here, which is actually the same issue I've been trying to solve.
The problem with the accepted solution is that it restricts the height of the hardcoded value, which I don't want. Rather the color should automatically fill the height of the card.
The Problem
I've tried all the three solutions and none of them fit my use case.
Output from first solution
Here I've to hardcode the value to something larger so that all the text being displayed lies well inside it. That's something I feel is not a solution.
Card(
key: ObjectKey(noteList[index]),
elevation: 2.0,
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: 4,
color: Color(noteList[index].intcolor),
),
Flexible(
flex: 100,
child: ListTile(
~~~~~~~~~~~~~~~~~ SNIP ~~~~~~~~~~~~~~~~~~~~~~~~
chip goes outside
Output from Second solution
This doesn't show anything at all.
Card(
key: ObjectKey(noteList[index]),
elevation: 2.0,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
constraints: BoxConstraints.expand(),
color: Color(noteList[index].intcolor),
),
),
Flexible(
flex: 100,
child: ListTile(
~~~~~~~~~~~~~~~~~ SNIP ~~~~~~~~~~~~~~~~~~~~~~~~
No output at all
Output from last solution
There's no color from the container.
There's no color from the container
Thanks a lot.
Update 1 ( Monday, 6 April 2020 8:16 pm GMT )
Added code and repo for easy replication.
Repo
main.dart
import 'package:flutter/material.dart';
void main() {
List<String> notes = [
"fluttermaster.com",
"Update Android Studio to 3.3",
"Something long Something long Something long Something long Something long Something long",
];
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Simple Note ListView"),
),
body: Container(
color: Colors.white10,
padding: EdgeInsets.all(16.0),
child: HomePage(notes)),
),
));
}
class HomePage extends StatelessWidget {
final List<String> notes;
HomePage(this.notes);
Widget build(BuildContext context) {
return ListView.builder(
itemCount: notes.length,
itemBuilder: (context, pos) {
return Padding(
padding: EdgeInsets.only(bottom: 16.0),
child: Card(
elevation: 2.0,
child: Row(
// key: _cardKey,
children: <Widget>[
Flexible(
flex: 1,
child: Container(
// -------------------- This here ----------------------------------------------
// FixMe : This shouldn't be hardcoded, rather it should fill the height of it's parent element, in this case card
// https://medium.com/#diegoveloper/flutter-widget-size-and-position-b0a9ffed9407
height: 71,
color: Colors.green,
// -------------------- This here ----------------------------------------------
),
),
Flexible(
flex: 100,
child: ListTile(
// For center alignment from vertical and horizontal : https://stackoverflow.com/a/51546279
// Since using CircleAvatar does this but it decreases size of icon too : https://github.com/flutter/flutter/issues/16061
leading: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(Icons.receipt),
],
),
title: Text(
notes[pos],
),
subtitle: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(notes[pos].substring(0, 10)),
// What is the best way to optionally include a widget in a list of children
// https://github.com/flutter/flutter/issues/3783#issuecomment-506019822
if ((pos % 2) == 0)
Chip(
avatar: CircleAvatar(
backgroundColor: Colors.grey.shade800,
child: Icon(Icons.timer),
),
label: Text('2FA'),
),
],
),
trailing: Padding(
padding: EdgeInsets.all(10),
child: Wrap(
spacing: 10,
direction: Axis.vertical,
alignment: WrapAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(
Icons.check,
color: Colors.grey,
),
onPressed: () {},
)
]),
),
onTap: () {},
),
),
],
),
));
},
);
}
}
Perhaps one way of doing it is to use Stack
ListView.builder(
itemCount: notes.length,
itemBuilder: (context, pos) {
return Padding(
padding: EdgeInsets.all(8),
child: Stack(
children: <Widget>[
Card(
margin: EdgeInsets.zero,
child: ListTile(
leading: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(Icons.receipt),
],
),
title: Text(
notes[pos],
),
subtitle: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(notes[pos].substring(0, 10)),
if ((pos % 2) == 0)
Chip(
avatar: CircleAvatar(
backgroundColor: Colors.grey.shade800,
child: Icon(Icons.timer),
),
label: Text('2FA'),
),
],
),
trailing: Padding(
padding: EdgeInsets.all(10),
child: Wrap(
spacing: 10,
direction: Axis.vertical,
alignment: WrapAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(
Icons.check,
color: Colors.grey,
),
onPressed: () {},
)
]),
),
onTap: () {},
),
),
Positioned(
top: 0,
bottom: 0,
child: Container(
width: 5,
color: Colors.green,
),
)
],
),
);
},
)
Output

Flutter, how to get rid of raisedButton bottom margin?

So I'm trying to remove the bottom margin of raisedButton so it will look like it is merged with the card below it.
here's what it looks like
here is my code
Expanded(
child: Card(
elevation: 5,
// shape:
// RoundedRectangleBorder(borderRadius: BorderRadius.circular(22)),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Apakah anak sudah bisa ... ?",
style: TextStyle(fontWeight: FontWeight.bold)),
),
],
),
Row(
children: <Widget>[
Expanded(
child: RaisedButton(
child: Text(
"Iya",
style: TextStyle(color: Colors.white),
),
color: Colors.green[300],
onPressed: () {}),
),
Expanded(
child: RaisedButton(
child: Text(
"Tidak",
style: TextStyle(color: Colors.white),
),
color: Colors.red[200],
onPressed: () {}))
],
)
],
),
),
)
or do you guys have any other alternative solution to achieve that?
You can explicitly set your Row height to match the height of your RaisedButton. Simply wrap it inside a Container and add the height attribute.
If you want to, you can access the default height by using Theme.of(context).buttonTheme.height. Theme.of returns the ThemeData used in the current context.
Here a minimal example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Container(
child: Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Test'),
Container(
height: Theme.of(context).buttonTheme.height,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
RaisedButton(
onPressed: () {},
child: Text('Yes'),
color: Colors.green,
),
RaisedButton(
onPressed: (){},
child: Text('No'),
color: Colors.red,
)
],
),
),
],
)
),
),
)),
);
}
}
I had the same problem. NikasPor's answer didnt work for me, unfortunately. The way I fixed it is by seeting the crossAxisAlignment on the row to .stretch
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children:[ /* Buttons Here */]
)