Flutter Slider 未在 ExpansionPanel 内部重建
Posted
技术标签:
【中文标题】Flutter Slider 未在 ExpansionPanel 内部重建【英文标题】:Flutter Slider not rebuilding inside of ExpansionPanel 【发布时间】:2020-04-08 04:30:10 【问题描述】:我正在尝试在 ExpansionPanelList
中使用多个 ExpansionPanel
s 创建一个表单。
我最初使用initState
在页面中设置表单。
现在我遇到的主要问题是将Slider
小部件实现到ExpansionPanel
之一。
Slider
按钮 UI 不会在更改时更新,但滑块的值 _colorValue
是。
我认为问题在于 ExpansionPanel
body
在重建时没有更新,但我不确定如何解决它。
我已经在没有真正帮助的情况下阅读了文档。
这是我的代码:
import ...
/// stores ExpansionPanel state information
class Panel
Panel(
this.expandedValue,
this.headerValue,
this.isExpanded = false,
);
Widget expandedValue;
String headerValue;
bool isExpanded;
class AddReviewScreen extends StatefulWidget
static const String route = 'add_review_screen';
@override
_AddReviewScreenState createState() => _AddReviewScreenState();
class _AddReviewScreenState extends State<AddReviewScreen>
final _formKey = GlobalKey<FormState>();
double _colorValue = 1.0;
List<Panel> _panels;
@override
void initState()
super.initState();
_panels = _getPanels();
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Add Review', style: Theme.of(context).textTheme.display4),
backgroundColor: kAppBarBackgroundColor,
),
backgroundColor: kScaffoldBackgroundColor,
body: SafeArea(
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(8.0),
child: Form(
key: _formKey,
child: _buildForm(),
),
),
),
),
);
List<Panel> _getPanels()
return [
Panel(...),
Panel(
headerValue: 'Sensory Features',
expandedValue: Column(
children: <Widget>[
Slider(
value: _colorValue,
min: 0.0,
max: 2.0,
divisions: 20,
onChanged: (double newValue)
setState(()
_colorValue = newValue;
print(_colorValue);
);
,
),
TextFormField(...),
TextFormField(...),
TextFormField(...),
],
),
),
];
Widget _buildForm()
return ExpansionPanelList(
expansionCallback: (int index, bool isExpanded)
setState(()
_panels[index].isExpanded = !isExpanded;
);
,
children: _panels.map<ExpansionPanel>((Panel panel)
return ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded)
return ListTile(
title: Text(panel.headerValue),
);
,
body: panel.expandedValue,
isExpanded: panel.isExpanded,
);
).toList(),
);
任何帮助将不胜感激! 如果有任何问题,请告诉我,我会尽力解答。
【问题讨论】:
【参考方案1】:问题和我想的一样,在body: panel.expandedValue
行。每当触发重建时,面板就会从 _panels
列表中重新绘制,因此会返回到它们的初始状态。
我如何设法解决它是首先从_getPanels
的面板中提取每个expandedValue
到它们自己的单独函数中。然后,我将 ExpansionPanelList
的子项从动态 Map/List 重构为 ExpansionPanel
s 的静态列表,因为我知道列表的大小将来不会改变,因此没有理由动态功能。
因此,基本上现在无论何时发生重建,UI 都不会回退到其初始状态。相反,它会更新提取的 Widget 函数中的“脏”值。
这是我的解决方案:
/// Construct the initial List of Panels.
List<Panel> _getPanels()
return [
Panel(
headerValue: 'Panel 1',
expandedValue: _panel1(),
isExpanded: true,
),
Panel(
headerValue: 'Panel 2',
expandedValue: _panel2(),
),
];
Function _expansionPanelHeaderBuilderCallback(String title)
return (BuildContext context, bool isExpanded)
return ListTile(
title: Text(title),
);
;
Widget _buildForm()
return ExpansionPanelList(
expansionCallback: (int index, bool isExpanded)
setState(()
_panels[index].isExpanded = !isExpanded;
);
,
children: [
ExpansionPanel(
headerBuilder: _expansionPanelHeaderBuilderCallback(_panels[0].headerValue),
body: _panel1(),
isExpanded: _panels[0].isExpanded,
canTapOnHeader: true,
),
ExpansionPanel(
headerBuilder:
_expansionPanelHeaderBuilderCallback(_panels[1].headerValue),
body: _panel2(),
isExpanded: _panels[1].isExpanded,
canTapOnHeader: true,
),
],
);
Widget _panel1()
return Padding(...);
Widget _panel2()
return Column(...);
如果找到更好的解决方案(我确信有),请在此处发布,我会将其标记为正确答案。
【讨论】:
以上是关于Flutter Slider 未在 ExpansionPanel 内部重建的主要内容,如果未能解决你的问题,请参考以下文章
iOS 设备中 Flutter TabBarView 覆盖底部区域(Slider)