首页 > 解决方案 > 如何使用 listview builder flutter 实现 ExpansionPanelList?

问题描述

我想在ExpansionPanelList 中实现listview builder。在每个扩展磁贴下,它将有标签栏和标签栏视图。在 tabbarview 内,它将显示 listview。我已尝试实现,但视图未正确呈现。投掷错误

RenderBox was not laid out: RenderRepaintBoundary#92515 NEEDS-LAYOUT NEEDS-PAINT
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1930 pos 12: 'hasSize'

我的实现代码:

 List<bool> _isOpen =[true, false]

 ExpansionPanelList(
                  children: [
                    ExpansionPanel(
                      isExpanded: _isOpen[0],
                        headerBuilder: (context, isOpen){
                          return Text("Activities");
                        },
                        body:  Column(
                          children: [
                            Container(child: tabView()),
                            Flexible(child: tabBarView()),
                          ],
                        ),),
                    ExpansionPanel(
                      isExpanded: _isOpen[1],
                      headerBuilder: (context, isOpen){
                        return Text("Ports");
                      },
                      body:  Text("Test"),)
                  ],
                  expansionCallback: (i, isOpen) {
                    setState(() {
                      _isOpen[i] =!isOpen;
                    });
                  },

                ), 

选项卡视图小部件

  Widget tabView(){
    return PreferredSize(
        preferredSize: Size.fromHeight(70),
        child: Align(
          alignment: Alignment.centerLeft,
          child: Container(
            width: MediaQuery.of(context).size.width ,
            child: TabBar(
                isScrollable: true,
              labelPadding: EdgeInsets.symmetric(horizontal: 8),
              controller: _tabController,
                unselectedLabelColor: CustomColors.Black,
                indicatorSize: TabBarIndicatorSize.label,
                indicator: BoxDecoration(
                    borderRadius: BorderRadius.circular(50),
                    color: CustomColors.oldLace),
                tabs: tabNames),
          ),
        ));

     
  }

标签栏视图

  Widget tabBarView(){

    return TabBarView(controller: _tabController,
      children: [
        listItems(),
        Center(child: Text("Favorite list will be shown here")),
        Center(child: Text("Filter")),
      ],);
  }

标签: flutter

解决方案


将您的 ExpansionPanelList 包装在 SingleChildScrollView 中,并通过包装内部容器为您的 TabBarView 提供固定高度。

下面的完整代码片段

    import 'package:flutter/material.dart';

class Expand extends StatefulWidget {
  const Expand({Key? key}) : super(key: key);

  @override
  _ExpandState createState() => _ExpandState();
}

class _ExpandState extends State<Expand> with SingleTickerProviderStateMixin {
  List<bool> _isOpen = [false, false];

  late TabController _tabController;
  static const List<Tab> myTabs = <Tab>[
    Tab(text: 'LEFT'),
    Tab(text: 'RIGHT'),
  ];

  @override
  void initState() {
    super.initState();
    _tabController = TabController(vsync: this, length: myTabs.length);
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  Widget tabView() {
    return PreferredSize(
        preferredSize: Size.fromHeight(70),
        child: Align(
          alignment: Alignment.centerLeft,
          child: Container(
            width: MediaQuery.of(context).size.width,
            // height: 200,
            child: TabBar(
              isScrollable: true,
              labelPadding: EdgeInsets.symmetric(horizontal: 8),
              controller: _tabController,
              unselectedLabelColor: Colors.black,
              indicatorSize: TabBarIndicatorSize.label,
              indicator: BoxDecoration(
                borderRadius: BorderRadius.circular(50),
                // color: CustomColors.oldLace
              ),
              tabs: myTabs,
              // tabs: tabNames
            ),
          ),
        ));
  }

  Widget tabBarView() {
    return Container(
      height: 400,
      width: 400,
      child: TabBarView(
        controller: _tabController,
        children: [
          // listItems(),
          Center(child: Text("Favorite list will be shown here")),
          Center(child: Text("Filter")),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        // height: 400,
        // width: 500,
        child: ExpansionPanelList(
          children: [
            ExpansionPanel(
              isExpanded: _isOpen[0],
              headerBuilder: (context, isOpen) {
                return Text("Activities");
              },
              body: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  tabView(),
                  tabBarView(),
                ],
              ),
            ),
            ExpansionPanel(
              isExpanded: _isOpen[1],
              headerBuilder: (context, isOpen) {
                return Text("Ports");
              },
              body: Text("Test"),
            )
          ],
          expansionCallback: (i, isOpen) {
            setState(() {
              _isOpen[i] = !isOpen;
            });
          },
        ),
      ),
    );
  }
}

推荐阅读