Mary
Mary

Reputation: 20495

Can you change the height of an ExpansionTile in Flutter?

The ExpansionTile inherits from the ListTile, which has a fixed height. There are no input args for tile height.

I've tried wrapping the ExpansionTile in a Container widget with a hardcoded height, but that causes the children widgets to only take up the space within the hardcoded height. Currently, because the contents in the title widget are large, I have a "Column overflowed by 23 pixels" message.

Is there any way to change an Expansion Tile's height? Or is there another Widget I could use that has the expansion/accordion feature?

Upvotes: 11

Views: 25909

Answers (7)

MAJID .V
MAJID .V

Reputation: 31

Try this

Theme(
      data: Theme.of(context).copyWith(
        listTileTheme: ListTileTheme.of(context)
            .copyWith(dense: true, minVerticalPadding: 16),
      ),
      child: ExpansionTile(

Upvotes: 3

MoonKillCZ
MoonKillCZ

Reputation: 131

Came across this in 2023, it turns out the ListTile can be 'controlled' by a theme.

  /// Whether this list tile is part of a vertically dense list.
  ///
  /// If this property is null then its value is based on [ListTileTheme.dense].
  ///
  /// Dense list tiles default to a smaller height.
  ///
  /// It is not recommended to set [dense] to true when [ThemeData.useMaterial3] is true.
  final bool? dense;

Deep in the library you can find this code:

  double get _defaultTileHeight {
    final bool hasSubtitle = subtitle != null;
    final bool isTwoLine = !isThreeLine && hasSubtitle;
    final bool isOneLine = !isThreeLine && !hasSubtitle;

    final Offset baseDensity = visualDensity.baseSizeAdjustment;
    if (isOneLine) {
      return (isDense ? 48.0 : 56.0) + baseDensity.dy;
    }
    if (isTwoLine) {
      return (isDense ? 64.0 : 72.0) + baseDensity.dy;
    }
    return (isDense ? 76.0 : 88.0) + baseDensity.dy;
  }

So simply wrap the ExpansionTile in a Theme and set dense: true

Theme(
   data: Theme.of(context).copyWith(
            listTileTheme: ListTileTheme.of(context).copyWith(
            dense: true,
          ),
        ),
   child: ExpansionTile(...),
),

While not a full control, the height of 48 was exactly the value I was looking for.

Upvotes: 7

Saad
Saad

Reputation: 613

You can use the tilePadding Property

 ExpansionTile(
                title: Text("some Text"),
                tilePadding: EdgeInsets.all(30),
              ),

Upvotes: 0

user2131694
user2131694

Reputation: 11

wrap the 'ExpansionTile' inside a 'Container' and set the margin

Container(
                  margin: EdgeInsets.only(right: .5.sw),
                  decoration: BoxDecoration(
                      color: AppColor.profileBoarderColor,
                      borderRadius: BorderRadius.circular(10),
                      border: Border.all(color: AppColor.profileBoarderColor)
                  ),
                  child: ExpansionTile(
                    title: AppTextView(text: 'Seeson 01',),
                    children: List.generate(10, (index) {
                      return SizedBox(
                        width: 200,
                          child: ListTile(title: AppTextView(text: 'Seeson 01',),));
                    }
                    ),
                  )

Upvotes: -1

Chris Joseph
Chris Joseph

Reputation: 17

This is a workaround: you can use title of the ExpansionTile widget to render the entire content instead of using leading or trailing. You can add padding to title widget to increase height of the ExpansionTile.

Upvotes: -2

Rami Mohamed
Rami Mohamed

Reputation: 2765

You might want to try this package : configurable_expansion_tile

enter image description here

Example app :

import 'package:flutter/material.dart';
import 'package:configurable_expansion_tile/configurable_expansion_tile.dart';

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

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Configurable Expansion Tile Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ConfigurableExpansionTile(
              borderColorStart: Colors.blue,
              borderColorEnd: Colors.orange,
              animatedWidgetFollowingHeader: const Icon(
                Icons.expand_more,
                color: const Color(0xFF707070),
              ),
              headerExpanded:
                  Flexible(child: Center(child: Text("A Header Changed"))),
              header: Container(
                  color: Colors.transparent,
                  child: Center(child: Text("A Header"))),
              headerBackgroundColorStart: Colors.grey,
              expandedBackgroundColor: Colors.amber,
              headerBackgroundColorEnd: Colors.teal,
              children: [
                Row(
                  children: <Widget>[Text("CHILD 1")],
                ),
                Row(
                  children: <Widget>[Text("CHILD 2")],
                )
              ],
            )
          ],
        ),
      ),
    );
  }
}

It should get you the results you wanted.

Hope it helps,

Thanks

Upvotes: 2

Collin Jackson
Collin Jackson

Reputation: 116828

I would probably copy ExpansionTile and make your own version. Sizing ListTile is easy with a Container or SizedBox, but ExpansionTile is a material widget and it doesn't look like it was built with your use case in mind.

Upvotes: 8

Related Questions