How to show or hide trailing icons if there is description data and location data are not available?

Viewed 102

Here is the code from which I have achieved 1st two scenarios but have not been able to do 3rd one.

    class _WbEventScreen extends State<WbEventScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Theme.of(context).colorScheme.primaryVariant,
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.primaryVariant,
      ),
      body: Center(
          child: FutureBuilder(
              future: EventHandler().getEventData(),
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                if (snapshot.hasData) {
                  if (snapshot.data != null) {
                    return _eventList(context, snapshot.data);
                  } else {
                    return CircularProgressIndicator();
                  }
                } else if (snapshot.hasError) {
                  return Text('Something seems to be wrong with the events');
                } else {
                  return CircularProgressIndicator();
                }
              })),
    );
  }

  Widget _eventList(context, List<Event> events) {
    if (events == null || events.length == 0) {
      return Center(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Text("No events are currently planned."),
        ),
      );
    }

    final DateFormat formatter = DateFormat('dd-MM-yyyy');

    return LayoutBuilder(builder: (context, constraints) {
      //return Container(
      //child: [
      return ListView(padding: EdgeInsets.all(10), children: [
        ...events.map((item) {
          final eventDate =
              item.startdate != null ? formatter.format(item.startdate) : '';
          final eventTime = item.starttime == ''
              ? ''
              : item.endtime == ''
                  ? item.starttime
                  : '${item.starttime} - ${item.endtime}';

          final eventDateTime =
              eventTime != '' ? '${eventDate}\n${eventTime}' : eventDate;

          return Container(
            margin: EdgeInsets.all(2),
            //padding: EdgeInsets.all(5),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(10),
              color: Colors.grey[200],
            ),

            child: EventExpander(
              initialExpanded: false,
              //iconColor: Theme.of(context).colorScheme.onPrimary,
              title: ListTile(
                title: Text(
                  item.title ?? "",
                  textAlign: TextAlign.left,
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  softWrap: false,
                  style: Theme.of(context).textTheme.headline1.copyWith(
                        fontWeight: FontWeight.bold,
                        color: Theme.of(context).colorScheme.onPrimary,
                        fontSize: 20,
                      ),
                  textScaleFactor: FontSizeMultiplier.of(context),
                ),
                subtitle: Text(
                  eventDateTime,
                  textAlign: TextAlign.left,
                ),
                // trailing: ((item.desc != null || item.desc != '') &&
                //     item.location?.asCoords != null) ? Icon(Icons.expand_more) : null,
              ),
              content: _expanderContent(item, context),
            ),
          );
        }),
      ]);
      //],
      //);
    });
  }

  Widget _expanderContent(Event item, BuildContext context) {
    if (!_itemDescOrLocationAvailable(item)) return null;

    return Padding(
      padding: const EdgeInsets.only(left: 5),
      child: Column(
        children: [
          HtmlText(
            onLinkTap: launch,
            linkColor: Theme.of(context).colorScheme.secondary,
            textColor: Theme.of(context).colorScheme.onPrimary,
            data: item.desc ?? '',
          ),
          if (item.location?.asCoords != null)
            Align(
              alignment: Alignment.bottomRight,
              child: IntrinsicHeight(
                child: Padding(
                  padding: const EdgeInsets.all(14.0),
                  child: FloatingActionButton(
                    heroTag: null,
                    onPressed: () {
                      _openMapsSheet(context, item);
                    },
                    child: Icon(
                      Icons.near_me,
                    ),
                  ),
                ),
              ),
            )
        ],
      ),
    );
  }

  bool _itemDescOrLocationAvailable(Event item) {
    if ((item.desc == null || item.desc == '') &&
        item.location?.asCoords == null)
      return false;
    else
      return true;
  }

  _openMapsSheet(context, Event event) async {
    try {
      final coords = event.location.asCoords;
      final title = event.title;
      final availableMaps = await MapLauncher.installedMaps;
      if (availableMaps.length == 1) {
        availableMaps[0].showMarker(coords: coords, title: title);
      } else
        showModalBottomSheet(
          context: context,
          builder: (BuildContext context) {
            return SafeArea(
              child: SingleChildScrollView(
                child: Container(
                  child: Wrap(
                    children: <Widget>[
                      for (var map in availableMaps)
                        ListTile(
                          onTap: () => map.showMarker(
                            coords: coords,
                            title: title,
                          ),
                          title: Text(
                            map.mapName,
                            style: Theme.of(context)
                                .textTheme
                                .bodyText1
                                .copyWith(color: Colors.black),
                          ),
                          leading: Image(
                            image: map.icon,
                            height: 30.0,
                            width: 30.0,
                          ),
                        ),
                    ],
                  ),
                ),
              ),
            );
          },
        );
    } catch (e) {
      print(e);
    }
  }
}
      

    

For EventExpnder here is the code

import 'dart:math';

import 'package:flutter/material.dart';

class EventExpander extends StatefulWidget {
  final Color headerBackgroundColor;
  final Function(BuildContext, bool) trailingBuilder;
  final Color iconColor;
  final Widget content;
  final Widget title;
  final bool initialExpanded;
  final Function(bool expanded) onExpansionChanged;

  const EventExpander({
    Key key,
    this.onExpansionChanged,
    this.initialExpanded,
    this.headerBackgroundColor,
    this.trailingBuilder,
    this.iconColor,
    @required this.title,
    @required this.content,
  }) : super(key: key);

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

class _EventExpanderState extends State<EventExpander> with TickerProviderStateMixin {
  AnimationController _animationController;
  Animation _animation;
  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 200));
    _animation = Tween<double>(begin: 0, end: pi).animate(_animationController);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: widget.headerBackgroundColor,
      child: ExpansionTile(
          initiallyExpanded: widget.initialExpanded,
          onExpansionChanged: (expanded) {
            if (expanded)
              _animationController.forward();
            else
              _animationController.reverse();
            if (widget.onExpansionChanged != null) widget.onExpansionChanged(expanded);
          },
          title: widget.title,
          trailing: widget.trailingBuilder ??
              AnimatedBuilder(
                  animation: _animationController,
                  child: Icon(Icons.expand_more,
                      size: 50, color: widget.iconColor ?? Theme.of(context).textTheme.bodyText1.color),
                  builder: (context, child) => Transform.rotate(
                    angle: _animation.value,
                    child: child,
                  )),
          children: [
            Container(
              width: double.infinity,
              child: widget.content,
            )
          ]),
    );
  }
}

I want to achieve 3rd one in screenshots which are attached. when there is no decs and location then i do not want to show expand_more icon. please help!! click here for screenshot

1 Answers

You can check if location and desc are null.

this is how it could look like:

...
child: location == null && desc == null
  ? //if true
  null //child is null
  : //else
  ExpansionTile(....) //child is ExpansionTile
Related