如何在父小部件上显示 SizeTransition 小部件(而不是展开它)
我正在寻找在 Flutter 上为表单创建一个 DropDownMenu 。
此下拉菜单不会粘贴/折叠到值选择器。
因此,我实现了位于行下方的展开列表视图。
我希望我的 SizedTransition 小部件能够越过父小部件而不是移动显示。这可能吗?我该怎么做?
我有:
Column [
InkWell,
SizeTransition -> ListView
]
我希望我的 SizeTransition 应该显示在父小部件上(而不是展开它)。
这是我的小部件代码 app_drop_down_form.dart
: 该小部件将列表项显示在扩展列表中,并在未选择任何内容时显示默认标题。
class AppDropDownForm extends StatefulWidget {
const AppDropDownForm({
required this.defaultTitle,
required this.dropList,
Key? key,
}) : super(key: key);
final String defaultTitle;
final List<AppDropDownItem> dropList;
@override
_AppDropDownFormState createState() => _AppDropDownFormState();
}
class _AppDropDownFormState extends State<AppDropDownForm>
with SingleTickerProviderStateMixin {
bool enableList = false;
int? _selectedIndex;
late AnimationController _expandController;
late Animation<double> _expandAnimation;
@override
void initState() {
_expandController = AnimationController(
vsync: this, duration: const Duration(milliseconds: 300));
_expandAnimation =
CurvedAnimation(parent: _expandController, curve: Curves.easeInCubic);
super.initState();
}
@override
void dispose() {
_expandController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
Container selectedItemWidget = _buildHeaderForm();
return Column(children: <Widget>[
InkWell(
onTap: _performExpand,
child: Container(
decoration: BoxDecoration(
border: Border.all(color: AppTheme.lightGrey, width: 1),
borderRadius: enableList
? const BorderRadius.vertical(top: Radius.circular(10))
: const BorderRadius.all(Radius.circular(10)),
color: Colors.white),
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(child: selectedItemWidget),
const Icon(Icons.expand_more,
size: 24.0, color: AppTheme.thirdColor)
]))),
SizeTransition(
sizeFactor: _expandAnimation, child: _buildExpandableSelectableList())
]);
}
Container _buildHeaderForm() {
if (_selectedIndex == null) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 15),
child:
Text(widget.defaultTitle, style: AppTheme.dropDownHintTextStyle));
} else {
var selectItem = widget.dropList
.where((element) => element.index == _selectedIndex)
.first;
return Container(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Row(children: [
SizedBox(
height: 25,
width: 25,
child: SvgPicture.asset(selectItem.iconPath,
color: AppTheme.black)),
const SizedBox(width: 20),
Text(selectItem.name, style: AppTheme.dropDownSelectedTextStyle)
]));
}
}
Widget _buildExpandableSelectableList() {
return Container(
decoration: BoxDecoration(
border: Border.all(color: AppTheme.lightGrey, width: 1),
borderRadius:
const BorderRadius.vertical(bottom: Radius.circular(10)),
color: AppTheme.thirdColor),
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: const BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics()),
itemCount: widget.dropList.length,
itemBuilder: (context, position) {
return _buildExpandableItem(position);
}));
}
InkWell _buildExpandableItem(int position) {
var item =
widget.dropList.where((element) => element.index == position).first;
return InkWell(
onTap: () {
_onChanged(position);
},
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Row(children: [
SizedBox(
height: 25,
width: 25,
child:
SvgPicture.asset(item.iconPath, color: AppTheme.white)),
const SizedBox(width: 20),
Text(item.name, style: AppTheme.dropDownLightTextStyle)
])));
}
void _onChanged(int position) {
setState(() {
_selectedIndex = position;
_performExpand();
});
}
void _performExpand() {
enableList = !enableList;
if (enableList) {
_expandController.forward();
} else {
_expandController.reverse();
}
}
}
````
I am looking to create a DropDownMenu on Flutter for a form.
This DropDown menu is not pasted/collapse to the value selector.
So I implemented an Expand List View that comes just below the Row.
I want my SizedTransition widget to go over the parent widget and not shift the display. Is this possible? How do I do this?
I have :
Column [
InkWell,
SizeTransition -> ListView
]
I would like my SizeTransition should display over parent widget (not expand it).
There is my widget code app_drop_down_form.dart
:
This widget take a list to item to display in expanded list and a default title when nothing is selected.
class AppDropDownForm extends StatefulWidget {
const AppDropDownForm({
required this.defaultTitle,
required this.dropList,
Key? key,
}) : super(key: key);
final String defaultTitle;
final List<AppDropDownItem> dropList;
@override
_AppDropDownFormState createState() => _AppDropDownFormState();
}
class _AppDropDownFormState extends State<AppDropDownForm>
with SingleTickerProviderStateMixin {
bool enableList = false;
int? _selectedIndex;
late AnimationController _expandController;
late Animation<double> _expandAnimation;
@override
void initState() {
_expandController = AnimationController(
vsync: this, duration: const Duration(milliseconds: 300));
_expandAnimation =
CurvedAnimation(parent: _expandController, curve: Curves.easeInCubic);
super.initState();
}
@override
void dispose() {
_expandController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
Container selectedItemWidget = _buildHeaderForm();
return Column(children: <Widget>[
InkWell(
onTap: _performExpand,
child: Container(
decoration: BoxDecoration(
border: Border.all(color: AppTheme.lightGrey, width: 1),
borderRadius: enableList
? const BorderRadius.vertical(top: Radius.circular(10))
: const BorderRadius.all(Radius.circular(10)),
color: Colors.white),
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(child: selectedItemWidget),
const Icon(Icons.expand_more,
size: 24.0, color: AppTheme.thirdColor)
]))),
SizeTransition(
sizeFactor: _expandAnimation, child: _buildExpandableSelectableList())
]);
}
Container _buildHeaderForm() {
if (_selectedIndex == null) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 15),
child:
Text(widget.defaultTitle, style: AppTheme.dropDownHintTextStyle));
} else {
var selectItem = widget.dropList
.where((element) => element.index == _selectedIndex)
.first;
return Container(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Row(children: [
SizedBox(
height: 25,
width: 25,
child: SvgPicture.asset(selectItem.iconPath,
color: AppTheme.black)),
const SizedBox(width: 20),
Text(selectItem.name, style: AppTheme.dropDownSelectedTextStyle)
]));
}
}
Widget _buildExpandableSelectableList() {
return Container(
decoration: BoxDecoration(
border: Border.all(color: AppTheme.lightGrey, width: 1),
borderRadius:
const BorderRadius.vertical(bottom: Radius.circular(10)),
color: AppTheme.thirdColor),
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: const BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics()),
itemCount: widget.dropList.length,
itemBuilder: (context, position) {
return _buildExpandableItem(position);
}));
}
InkWell _buildExpandableItem(int position) {
var item =
widget.dropList.where((element) => element.index == position).first;
return InkWell(
onTap: () {
_onChanged(position);
},
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Row(children: [
SizedBox(
height: 25,
width: 25,
child:
SvgPicture.asset(item.iconPath, color: AppTheme.white)),
const SizedBox(width: 20),
Text(item.name, style: AppTheme.dropDownLightTextStyle)
])));
}
void _onChanged(int position) {
setState(() {
_selectedIndex = position;
_performExpand();
});
}
void _performExpand() {
enableList = !enableList;
if (enableList) {
_expandController.forward();
} else {
_expandController.reverse();
}
}
}
````
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论