Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter:How to remove elevation from ExpansionPanelList?

I was trying to list dropdown like widget, but luckily found the expansion panel list widget to get my desired UX to feel.

So, I am using ExpansionPanelList in my flutter app, but don't require the default elevation/border-shadow it comes with.

I have no idea how to remove it, so as to make it look part of the body rather than an elevated container.

Currently looking like this:

mock

Following is my code:

class _PracticetestComp extends State<Practicetest> {
  var listofpracticetest;
  List<Item> _data = [
    Item(
      headerValue: 'Previous Question Papers',
      expandedValue: '',
    )
  ];


  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Color(0xffF8FDF7),
        appBar: AppBar(
          backgroundColor: Color(0xffF8FDF7), // status bar color
          brightness: Brightness.light,
          elevation: 0.0,
          leading: Container(
            margin: EdgeInsets.only(left: 17),
            child: RawMaterialButton(
              onPressed: () {
                Navigator.pushNamed(context, '/');
              },
              child: new Icon(
                Icons.keyboard_backspace,
                color: Colors.red[900],
                size: 25.0,
              ),
              shape: new CircleBorder(),
              elevation: 4.0,
              fillColor: Colors.white,
              padding: const EdgeInsets.all(5.0),
            ),
          ),
        ),
        body: Container(
          // height: 200,
          margin: EdgeInsets.only(top: 40),
          child: ListView(
            shrinkWrap: true,
            scrollDirection: Axis.vertical,
            children: [
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[

                  Container(
                      margin: EdgeInsets.only(top: 30),
                      child: Theme(
                          data: Theme.of(context)
                              .copyWith(cardColor: Color(0xffF8FDF7)),
                          child: _buildPanelPreviousPapers()))
                ],
              )
            ],
          ),
        ));
  }

  Widget _buildPanelPreviousPapers() {
    return ExpansionPanelList(
      expansionCallback: (int index, bool isExpanded) {
        setState(() {
          _data[index].isExpanded = !isExpanded;
        });
      },
      children: _data.map<ExpansionPanel>((Item item) {
        return ExpansionPanel(
          headerBuilder: (BuildContext context, bool isExpanded) {
            return ListTile(
              title: Text(item.headerValue),
            );
          },
          body: Container(

            child: ListTile(
              leading: Text(
                'Alegbra',
                style:
                    TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
              ),

              ),
            ),
          ),
          isExpanded: item.isExpanded,
        );
      }).toList(),
    );
  }
}

// stores ExpansionPanel state information
class Item {
  Item({
    this.expandedValue,
    this.headerValue,
    this.isExpanded = false,
  });

  String expandedValue;
  String headerValue;
  bool isExpanded;
}
like image 565
Gaurav Kumar Avatar asked Feb 29 '20 10:02

Gaurav Kumar


3 Answers

wrap your entire expansion widget child inside Material widget and change the elevation based on expansion child is expanded or not with method

   Material(
        elevation: isSelected ? 4 : 0,
        child: ExpansionTile(
         onExpansionChanged:(value){
                            isSelected=value;
                            setState(){};
                                   },

         title: getExpantionTitle(context),
          children: getChildrentList(),
              ),
            ),
        ),

in case if you don't like divider in ExpansionTile tile do some thing like this

        final theme = Theme.of(context).copyWith(dividerColor: 
        Colors.transparent);
     //use as a child 
 child:Theme(data: theme, child: ExpansionTile(...));  
like image 62
sourav pandit Avatar answered Oct 21 '22 15:10

sourav pandit


First, it isn't recommended to not use elevation for ExpansionPanelList according to Material design spec.

However, if you really want to do that, there are 2 solutions for you, either you create your own custom ExpansionPanelList, or get ready to add couple of lines to the source file. I'm providing you the latter solution.

  1. Open expansion_panel.dart file, go to the build() method of _ExpansionPanelListState and make following changes

    return MergeableMaterial(
      hasDividers: true,
      children: items,
      elevation: 0, // 1st add this line
    );
    
  2. Now open mergeable_material.dart file, navigate to _paintShadows method of _RenderMergeableMaterialListBody class and make following changes:

    void _paintShadows(Canvas canvas, Rect rect) {
    
      // 2nd add this line
      if (boxShadows == null) return;
    
      for (final BoxShadow boxShadow in boxShadows) {
        final Paint paint = boxShadow.toPaint();
        canvas.drawRRect(kMaterialEdges[MaterialType.card].toRRect(rect), paint);
      }
    }
    

Screenshot:

enter image description here

like image 36
CopsOnRoad Avatar answered Oct 21 '22 13:10

CopsOnRoad


Just add this line:

ExpansionPanelList(
      elevation: 0, // this line
      expansionCallback: ...

like image 3
Caspar Bm Avatar answered Oct 21 '22 14:10

Caspar Bm