如何将 Flutter 的 ExpansionPanelList 小部件的默认框装饰更改为圆角矩形框
How to change the default box decoration to rounded rectangular box for ExpansionPanelList widget of Flutter
Flutter 的扩展面板列表(https://docs.flutter.io/flutter/material/ExpansionPanelList-class.html)没有装饰。如何创建圆边扩展面板列表?请看附图。
没有直接的方法使扩展面板的角变圆,但是 flutter 是完全开源的,您可以轻松获得 ExpansionPanelList class 的实现并复制并制作 CustomExpansionPanelList 以使 UI 为根据您的要求。这是 CustomExpansionPanelList 的简单代码,您只需将 ExpansionPanelList 小部件替换为 CustomExpansionPanelList
即可使用
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]';
}
}
你不能。我复制了 class ExpansionPanelList 并制作了我自己的 (CustomExpansionPanelList)。然后我删除了阴影并改变了颜色。我没有找到如何添加边界半径,但我能够在其中使用 Container 和 Border radius 来做同样的事情。结果看起来不错:
Border radius at ExpandedPanelList
还有另一种简单的方法可以达到同样的效果。
设置
海拔:0
将 ExpansionPanelList 包装在 ClipRRect 中..
return ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: ExpansionPanelList(..)
Flutter 的扩展面板列表(https://docs.flutter.io/flutter/material/ExpansionPanelList-class.html)没有装饰。如何创建圆边扩展面板列表?请看附图。
没有直接的方法使扩展面板的角变圆,但是 flutter 是完全开源的,您可以轻松获得 ExpansionPanelList class 的实现并复制并制作 CustomExpansionPanelList 以使 UI 为根据您的要求。这是 CustomExpansionPanelList 的简单代码,您只需将 ExpansionPanelList 小部件替换为 CustomExpansionPanelList
即可使用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]';
}
}
你不能。我复制了 class ExpansionPanelList 并制作了我自己的 (CustomExpansionPanelList)。然后我删除了阴影并改变了颜色。我没有找到如何添加边界半径,但我能够在其中使用 Container 和 Border radius 来做同样的事情。结果看起来不错:
Border radius at ExpandedPanelList
还有另一种简单的方法可以达到同样的效果。
设置 海拔:0
将 ExpansionPanelList 包装在 ClipRRect 中..
return ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: ExpansionPanelList(..)