Skip to content Skip to sidebar Skip to footer

Simple Expandable Column On Flutter Wont Have Title > Expandable Too

I'm trying to make an Expandable Column. That is, it has 2 children: the child and the expanded child that appears when the widget is expanded. In the picture below, you see the ch

Solution 1:

You were passing the function wrong. Please check the code now.

import 'package:flutter/material.dart';

final Color darkBlue = const Color.fromARGB(255, 18, 32, 47);

const double COLUMN_WIDTH = 150;
const double COLUMN_WIDTH_EXPANDED = COLUMN_WIDTH;
const double COLUMN_WIDTH_TOTAL_EXPANDED = COLUMN_WIDTH + COLUMN_WIDTH_EXPANDED;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
            child: Container(
                height: 300,
                child: ListView(scrollDirection: Axis.horizontal, children: [
                  ExpandableColumn(
                    title: "Expand",
                    child: Container(width: COLUMN_WIDTH, color: Colors.blue),
                    expandedChild: Container(
                        width: COLUMN_WIDTH_EXPANDED, color: Colors.red),
                    expanded: false,
                  ),
                  ExpandableColumn(
                    title: "Expand",
                    child: Container(width: COLUMN_WIDTH, color: Colors.green),
                    expandedChild: Container(
                        width: COLUMN_WIDTH_EXPANDED, color: Colors.purple),
                    expanded: false,
                  ),
                ]))),
      ),
    );
  }
}

class ExpandableColumn extends StatefulWidget {
  const ExpandableColumn(
      {Key key,
      this.title,
      @required this.child,
      this.expandedChild,
      this.onExpand,
      this.expanded})
      : super(key: key);
  final Widget child;
  final Widget expandedChild;
  final Function onExpand;
  final String title;
  final bool expanded;

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

class ExpandableColumnState extends State<ExpandableColumn>
    with TickerProviderStateMixin {
  bool expIcon = false;
  AnimationController _controller;
  Animation<double> _animation;
  //Animation<double> _animationT;
  Function onExpand;
  bool expanded;
  final Duration duration = const Duration(milliseconds: 200);

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

  @override
  void initState() {
    super.initState();
    onExpand = widget.onExpand;
    expanded = widget.expanded;
    _controller = AnimationController(
      duration: duration,
      vsync: this,
    );
    _animation = CurvedAnimation(
      parent: _controller,
      curve: Curves.fastOutSlowIn,
    );
  }

  updateExpansion() {
    // if (expanded) {
    //   _controller.forward();
    // } else {
    //   _controller.reverse();
    // }
    !expanded
        ? Future.delayed(duration).then((value) {
            expIcon = !expIcon;
            _controller.reverse();
            setState(() {});
          })
        : _controller
            .forward()
            .then((value) => setState(() => expIcon = !expIcon));
  }

  onPressed() {
    expanded = !expanded;
    updateExpansion();
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.topLeft,
      child: Container(
          child: Column(
              //mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
            ExpandableListTitle(
              title: widget.title,
              expanded: expanded,
              onPress: onPressed,
              expIcon: expIcon,
              columnWidth: expanded
                  ? (_animation.value * 150 + 150)
                  : expIcon
                      ? (_animation.value * 150 + 150)
                      : COLUMN_WIDTH,
              duration: duration,
              // onPress: () => {
              //   setState(() {
              //     expanded != null ? expanded = !expanded : expanded = true;
              //     updateExpansion();
              //     if (onExpand != null) onExpand(expanded);
              //   })
              // },
            ),
            Expanded(
                child: Container(
              child:
                  Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
                Container(
                  width: COLUMN_WIDTH,
                  child: widget.child,
                ),
                SizeTransition(
                    sizeFactor: _animation,
                    axis: Axis.horizontal,
                    axisAlignment: -1,
                    child: Container(
                        width: COLUMN_WIDTH, child: widget.expandedChild))
              ]),
            ))
          ])),
    );
  }
}

class ExpandableListTitle extends StatefulWidget {
  const ExpandableListTitle({
    Key key,
    this.title,
    this.expanded,
    this.onPress,
    this.expIcon,
    this.columnWidth,
    this.duration,
  }) : super(key: key);
  final String title;
  final bool expanded;
  final Function onPress;
  final bool expIcon;
  final double columnWidth;
  final Duration duration;
  @override
  _ExpandableListTitleState createState() => _ExpandableListTitleState();
}

class _ExpandableListTitleState extends State<ExpandableListTitle>
    with SingleTickerProviderStateMixin {
  bool _alignAnimationEnded = false;
  // bool expanded;
  // Function onPress;
  // String title;
  // @override
  // void initState() {
  //   super.initState();
  //   expanded = widget.expanded;
  //   onPress = widget.onPress;
  //   title = widget.title;
  // }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: widget.columnWidth,
      child: GestureDetector(
        behavior: HitTestBehavior.opaque,
        // onTap: () =>
        //     onPress != null ? onPress() : print('ExpandableListTitle tap'),
        onTap: () {
          _alignAnimationEnded = false;
          widget.onPress();
        },
        child: Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Container(
                child: Container(
              margin: const EdgeInsets.only(left: 12, top: 15),
              child: Text(this.widget.title,
                  style: const TextStyle(
                      fontSize: 20,
                      fontWeight: FontWeight.w700,
                      fontFamily: 'Roboto',
                      color: Colors.white)),
            )),
            Expanded(
              flex: 1,
              child: Container(
                margin: const EdgeInsets.only(right: 7, top: 15),
                child: AnimatedAlign(
                  onEnd: () => setState(() => _alignAnimationEnded = true),
                  duration: widget.duration,
                  alignment: widget.expanded && widget.expIcon
                      ? Alignment.centerRight
                      : Alignment.centerLeft,
                  child: widget.expanded
                      ? widget.expIcon && _alignAnimationEnded
                          ? const Icon(Icons.arrow_back_ios_outlined,
                              color: Colors.grey)
                          : const Icon(Icons.arrow_forward_ios,
                              color: Colors.grey)
                      : widget.expIcon
                          ? const Icon(Icons.arrow_back_ios_outlined,
                              color: Colors.grey)
                          : const Icon(Icons.arrow_forward_ios,
                              color: Colors.grey),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Post a Comment for "Simple Expandable Column On Flutter Wont Have Title > Expandable Too"