flutter-expandable icon indicating copy to clipboard operation
flutter-expandable copied to clipboard

Expand one, collapse the other for ListView

Open LiangLuDev opened this issue 4 years ago • 6 comments

how to use

LiangLuDev avatar Jan 21 '21 01:01 LiangLuDev

I need like this.

heinzan avatar Apr 19 '21 15:04 heinzan

I need like this too

salahturkmen avatar May 06 '21 21:05 salahturkmen

I have some issue. Any advice?

FetFrumos avatar Jun 14 '21 07:06 FetFrumos

Any update?

eliasjtg avatar Sep 11 '21 22:09 eliasjtg

I need like this.

yj229201093 avatar Nov 22 '21 08:11 yj229201093

While there are no updates here, I finally figured out how to do it. Here's the workaround. Here's the sample code This is the parent widget

return ListView.builder(
            itemCount: taskCardExpanded.length, //  List<bool> taskCardExpanded = List.generate(3, (index) => false);
            itemBuilder: (context, index) {
              return Column(
                children: [
                  TaskCard(
                    index: index,
                    isExpanded: taskCardExpanded[index],
                    onExpandedChanged: (isExpanded) { // to check if one of them expanded, and reset the others.
                      WidgetsBinding.instance.addPostFrameCallback((_) {
                        if (isExpanded) { // set current expanded value to true and reset the others
                          setState(() {
                            for (int i = 0; i < taskCardExpanded.length; i++) {
                              if (i == index) {
                                taskCardExpanded[i] = true;
                              } else {
                                taskCardExpanded[i] = false;
                              }
                            }
                          });
                        } else { 
                          setState(() {
                            taskCardExpanded[index] = false;
                          });
                        }
                      });
                    },
                  ),
                  const SizedBox(height: 10),
                ],
              );
            },
          ),

Here's the child code. I used the listener to tell the parent that the child changed it's value


class TaskCard extends StatefulWidget {
  final bool isExpanded;
  final void Function(bool isExpanded)? onExpandedChanged;

  const TaskCard({
    super.key,
    this.isExpanded = false,
    this.onExpandedChanged,
  });

  @override
  State<TaskCard> createState() => _TaskCardState();
}

class _TaskCardState extends State<TaskCard> {
  bool isExpanded = false;
  late ExpandableController _controller;

  @override
  void initState() {
    super.initState();
    _controller = ExpandableController(initialExpanded: widget.isExpanded);
    _controller.addListener(() {
      setState(() {
        isExpanded = !isExpanded;
      });
      widget.onExpandedChanged?.call(isExpanded);
    });
  }

  @override
  void didUpdateWidget(covariant TaskCard oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.isExpanded != isExpanded) {
      _controller.toggle(); // the expansion/collapse happens cause of this 
    }
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.white,
      clipBehavior: Clip.antiAliasWithSaveLayer,
      borderRadius: BorderRadius.circular(15),
      child: InkWell(
        onTap: () => _controller.toggle(), // the expansion/collapse happens cause of this
        child: Container(
          padding: const EdgeInsets.symmetric(vertical: 5),
          clipBehavior: Clip.antiAliasWithSaveLayer,
          decoration: BoxDecoration(
            color: Colors.transparent,
            borderRadius: BorderRadius.circular(20),
            border: Border.all(
              width: isExpanded ? 1.3 : 1,
            ),
          ),
          child: Padding(
            padding: const EdgeInsets.fromLTRB(10, 0, 10, 10),
            child: ExpandableNotifier(
              controller: _controller,
              child: ExpandablePanel(
                theme: const ExpandableThemeData(
                  tapBodyToExpand: false,
                  hasIcon: false,
                  tapHeaderToExpand: false,
                ),
                header: _buildHeader(),
                collapsed: _buildCollapsed(),
                expanded: _buildExpanded(),
              ),
            ),
          ),
        ),
      ),
    );
  }
  }

hawkeye-sama avatar Sep 06 '23 19:09 hawkeye-sama