如何将SearchField容器置于RefreshIndicator组件上方?Flutter/Dart
解决方案
方案1:搜索框固定在顶部(不随列表滚动)
将搜索框与RefreshIndicator放入Column容器,同时用Expanded包裹RefreshIndicator让其占据剩余空间。这种方式下搜索框会固定在界面顶部,下拉刷新仅作用于下方的列表区域。
完整代码示例:
Column( children: [ // 你的搜索框Container Container( height: widget.appController.queryData.size.height/12, width: widget.appController.queryData.size.width * (9/10), margin: EdgeInsets.all(5.0), decoration: BoxDecoration( color: widget.appController.themeController.appWhiteLightColor, boxShadow: [ BoxShadow( color: widget.appController.themeController.appGreyLightColor.withOpacity(0.6), spreadRadius: 1, blurRadius: 1, offset: Offset(0, 2), // changes position of shadow ), ], shape: BoxShape.rectangle, border: Border.all( color: Colors.transparent, ), borderRadius: BorderRadius.all(Radius.circular(10)) ), child:Row( mainAxisAlignment: MainAxisAlignment.center, children:[ Container( width: widget.appController.queryData.size.width * (7/10), child: searchTextField, ), Container( child: IconButton( color: widget.appController.themeController.appBlackDeepColor, tooltip: 'Search', icon: const Icon(Icons.search), iconSize: 32 * this.unitHeightValue, onPressed: () { this.evseSearchField = myController.text; showEvsePanels(); }, ), ), ] ), ), // 包裹Expanded的RefreshIndicator Expanded( child: RefreshIndicator( onRefresh: refresh, child: ListView.separated( separatorBuilder: (context, index) => Divider(), controller: controller, padding: const EdgeInsets.all(8), itemCount: evsePanels.length + 1, itemBuilder: (context, index) { if (index < evsePanels.length) { return evsePanels[index]; } else { return Padding( padding: const EdgeInsets.symmetric(vertical: 32), child: Center( child: hasMore ? const CircularProgressIndicator() : const Text('No more data to load'), ), ); } } ), ), ), ], )
方案2:搜索框随列表滚动(下拉刷新覆盖整个区域)
如果希望下拉刷新时搜索框也跟随列表滚动,可将搜索框作为ListView.separated的第一个列表项,让整个列表(包含搜索框)都处于RefreshIndicator的作用范围内。
修改后的代码示例:
RefreshIndicator( onRefresh: refresh, child: ListView.separated( separatorBuilder: (context, index) => Divider(), controller: controller, padding: const EdgeInsets.all(8), // 列表数量+2(原列表项+搜索框+底部加载提示) itemCount: evsePanels.length + 2, itemBuilder: (context, index) { // 第一个item显示搜索框 if (index == 0) { return Container( height: widget.appController.queryData.size.height/12, width: widget.appController.queryData.size.width * (9/10), margin: EdgeInsets.all(5.0), decoration: BoxDecoration( color: widget.appController.themeController.appWhiteLightColor, boxShadow: [ BoxShadow( color: widget.appController.themeController.appGreyLightColor.withOpacity(0.6), spreadRadius: 1, blurRadius: 1, offset: Offset(0, 2), // changes position of shadow ), ], shape: BoxShape.rectangle, border: Border.all( color: Colors.transparent, ), borderRadius: BorderRadius.all(Radius.circular(10)) ), child:Row( mainAxisAlignment: MainAxisAlignment.center, children:[ Container( width: widget.appController.queryData.size.width * (7/10), child: searchTextField, ), Container( child: IconButton( color: widget.appController.themeController.appBlackDeepColor, tooltip: 'Search', icon: const Icon(Icons.search), iconSize: 32 * this.unitHeightValue, onPressed: () { this.evseSearchField = myController.text; showEvsePanels(); }, ), ), ] ), ); } // 原列表项索引需减1 if (index - 1 < evsePanels.length) { return evsePanels[index - 1]; } else { return Padding( padding: const EdgeInsets.symmetric(vertical: 32), child: Center( child: hasMore ? const CircularProgressIndicator() : const Text('No more data to load'), ), ); } } ), );
内容的提问来源于stack exchange,提问作者Bill Tertis
相关产品推荐
相关产品推荐

