Reputation: 47
I have this code for expansion panel list which is working fine but I am not able to extend the size of the expansion panel. Also, I want the expansion panel to have a border radius but I am not sure if border radius can be given
return Column(children: [
Stack(
clipBehavior: Clip.none,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 50),
child: ExpansionPanelList(
animationDuration: Duration(milliseconds: 1000),
children: [
ExpansionPanel(
headerBuilder: (context, isExpanded) {
return Column(
children: [
Text("Salmon Poké"),
Text("Rs. 2000"),
],
);
},
body: Text(
'This salmon sashimi is a delicious light appetizer served with fresh wasabi, ginger, soy sauce or a delicious side of soy yuzo citrus ponzu.',
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
),
isExpanded: _expanded,
canTapOnHeader: true,
backgroundColor: Colors.white),
],
dividerColor: Colors.grey,
expansionCallback: (panelIndex, isExpanded) {
_expanded = !_expanded;
setState(() {});
},
),
),
Positioned(
top: -55,
right: 240,
child: CircleAvatar(
radius: 105,
child: ClipOval(
child: Image(
image: AssetImage('assets/images/salmon.png'),
),
),
backgroundColor: Colors.transparent,
),
),
],
),
]);
} }
**Here is the UI for the given code **
Here is the output which I want. (This UI is made using container widgets but I want this layout using expansion panel list)
This is the output that I want
I really appreciate your help.
Upvotes: 3
Views: 4032
Reputation: 66
Wrap the ExpansionPanelList in a ClipRRect.
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: ExpansionPanelList(
children: [ExpansionPanel(body: Text('Hello World'))])
)
Upvotes: 5
Reputation: 354
For border radius we need to make custom expansion list
import 'package:flutter/material.dart';
const double _kPanelHeaderCollapsedHeight = 48.0;
const double _kPanelHeaderExpandedHeight = 64.0;
class CustomExpansionPanelList extends StatelessWidget {
const CustomExpansionPanelList(
{Key key,
this.children: const <ExpansionPanel>[],
this.expansionCallback,
this.animationDuration: kThemeAnimationDuration})
: assert(children != null),
assert(animationDuration != null),
super(key: key);
final List<ExpansionPanel> children;
final ExpansionPanelCallback expansionCallback;
final Duration animationDuration;
bool _isChildExpanded(int index) {
return children[index].isExpanded;
}
@override
Widget build(BuildContext context) {
final List<Widget> items = <Widget>[];
const EdgeInsets kExpandedEdgeInsets = const EdgeInsets.symmetric(
vertical: _kPanelHeaderExpandedHeight - _kPanelHeaderCollapsedHeight);
for (int index = 0; index < children.length; index += 1) {
if (_isChildExpanded(index) && index != 0 && !_isChildExpanded(index - 1))
items.add(new Divider(
key: new _SaltedKey<BuildContext, int>(context, index * 2 - 1),
height: 15.0,
color: Colors.transparent,
));
final Row header = new Row(
children: <Widget>[
new Expanded(
child: new AnimatedContainer(
duration: animationDuration,
curve: Curves.fastOutSlowIn,
margin: _isChildExpanded(index)
? kExpandedEdgeInsets
: EdgeInsets.zero,
child: new SizedBox(
height: _kPanelHeaderCollapsedHeight,
child: children[index].headerBuilder(
context,
children[index].isExpanded,
),
),
),
),
new Container(
margin: const EdgeInsetsDirectional.only(end: 8.0),
child: new ExpandIcon(
isExpanded: _isChildExpanded(index),
padding: const EdgeInsets.all(16.0),
onPressed: (bool isExpanded) {
if (expansionCallback != null)
expansionCallback(index, isExpanded);
},
),
),
],
);
double _radiusValue = _isChildExpanded(index)? 8.0 : 0.0;
items.add(
new Container(
key: new _SaltedKey<BuildContext, int>(context, index * 2),
child: new Material(
elevation: 2.0,
borderRadius: new BorderRadius.all(new Radius.circular(_radiusValue)),
child: new Column(
children: <Widget>[
header,
new AnimatedCrossFade(
firstChild: new Container(height: 0.0),
secondChild: children[index].body,
firstCurve:
const Interval(0.0, 0.6, curve: Curves.fastOutSlowIn),
secondCurve:
const Interval(0.4, 1.0, curve: Curves.fastOutSlowIn),
sizeCurve: Curves.fastOutSlowIn,
crossFadeState: _isChildExpanded(index)
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
duration: animationDuration,
),
],
),
),
),
);
if (_isChildExpanded(index) && index != children.length - 1)
items.add(new Divider(
key: new _SaltedKey<BuildContext, int>(context, index * 2 + 1),
height: 15.0,
));
}
return new Column(
children: items,
);
}
}
class _SaltedKey<S, V> extends LocalKey {
const _SaltedKey(this.salt, this.value);
final S salt;
final V value;
@override
bool operator ==(dynamic other) {
if (other.runtimeType != runtimeType) return false;
final _SaltedKey<S, V> typedOther = other;
return salt == typedOther.salt && value == typedOther.value;
}
@override
int get hashCode => hashValues(runtimeType, salt, value);
@override
String toString() {
final String saltString = S == String ? '<\'$salt\'>' : '<$salt>';
final String valueString = V == String ? '<\'$value\'>' : '<$value>';
return '[$saltString $valueString]';
}
}
Now use this widget in your application
import 'package:color_essence/customViews/CustomExpansionList.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class ExpansionPanelDemo extends StatefulWidget {
@override
_ExpansionPanelDemoState createState() => _ExpansionPanelDemoState();
}
class _ExpansionPanelDemoState extends State<ExpansionPanelDemo> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Expansion Panel Demo'),
),
body: Container(
padding: EdgeInsets.all(10),
child: ListView.builder(
itemCount: itemData.length,
itemBuilder: (BuildContext context, int index) {
return CustomExpansionPanelList(
animationDuration: Duration(milliseconds: 1000),
children: [
ExpansionPanel(
body: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipOval(
child: CircleAvatar(
child: Image.asset(
itemData[index].img,
fit: BoxFit.cover,
),
),
),
SizedBox(
height: 30,
),
Text(
itemData[index].discription,
style: TextStyle(
color: Colors.grey[700],
fontSize: 15,
letterSpacing: 0.3,
height: 1.3),
),
],
),
),
headerBuilder: (BuildContext context, bool isExpanded) {
return Container(
padding: EdgeInsets.all(10),
child: Text(
itemData[index].headerItem,
style: TextStyle(
color: itemData[index].colorsItem,
fontSize: 18,
),
),
);
},
isExpanded: itemData[index].expanded,
)
],
expansionCallback: (int item, bool status) {
setState(() {
itemData[index].expanded = !itemData[index].expanded;
});
},
);
},
),
),
);
}
List<ItemModel> itemData = <ItemModel>[
ItemModel(
headerItem: 'Android',
discription:
"Android is a mobile operating system based on a modified version of the Linux kernel and other open source software, designed primarily for touchscreen mobile devices such as smartphones and tablets. ... Some well known derivatives include Android TV for televisions and Wear OS for wearables, both developed by Google.",
colorsItem: Colors.green,
img: 'assets/images/android_img.png'
),
];
}
class ItemModel {
bool expanded;
String headerItem;
String discription;
Color colorsItem;
String img;
ItemModel({this.expanded: false, this.headerItem, this.discription,this.colorsItem,this.img});
}
Upvotes: 3