Vinay Bakle
Vinay Bakle

Reputation: 155

How to implement ExpansionPanelList with listview builder flutter?

I want to implement listview builder inside ExpansionPanelList. Under each expansion tile it will have tabbar and tabbarview. Inside the tabbarview it will display listview. I have tried to implemented but the view is not rendering properly. Throwing error

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

My Implemented code:

 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;
                    });
                  },

                ), 

tabview widget

  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),
          ),
        ));

     
  }

tabbarView

  Widget tabBarView(){

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

Upvotes: 1

Views: 2409

Answers (2)

Yashraj
Yashraj

Reputation: 999

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Expansion Panel List',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  TabController _tabController;

  @override
  void initState() {
    _tabController = TabController(length: 2, vsync: this);

    super.initState();
  }

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

  List<bool> _isOpen = [true, false];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Draggable Test'),
        ),
        body: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            ExpansionPanelList(
              children: [
                ExpansionPanel(
                    isExpanded: _isOpen[0],
                    headerBuilder: (context, isOpen) {
                      return Text("Activities");
                    },
                    body: Column(
                      children: [
                        Container(child: tabView()),
                        tabBarView(),
                      ],
                    )),
                ExpansionPanel(
                    isExpanded: _isOpen[1],
                    headerBuilder: (context, isOpen) {
                      return Text("Ports");
                    },
                    body: Column(
                      children: [
                        Container(child: tabView()),
                        tabBarView(),
                      ],
                    ))
              ],
              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: Colors.blue,
              indicatorSize: TabBarIndicatorSize.label,
              indicator: BoxDecoration(borderRadius: BorderRadius.circular(50), color: Colors.black),
              tabs: [
                Tab(text: 'Activities'),
                Tab(text: 'Ports'),
              ],
            ),
          ),
        ));
  }

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

Upvotes: 1

Musab
Musab

Reputation: 261

Wrap your ExpansionPanelList in SingleChildScrollView and Give fix height to your TabBarView by Wraping Inside Container.

Full Code Snippet below

    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;
            });
          },
        ),
      ),
    );
  }
}

Upvotes: 2

Related Questions