Is there a better way to write this code in Flutter?

Issue

I know I can apply switch-case operators but I think still looks a little bit verbose. Basically is a list of dynamic values wrapped in a Widget, and returns a BaseItemWidget to a ListView.

Here is the list:

class MyListView extends StatelessWidget {
  const MyListView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ReorderableListView(
      shrinkWrap: true,
      onReorder: provider.reorderList,
      children: provider.items.map((item) {
        return Dismissible(
          key: UniqueKey(),
          direction: DismissDirection.none,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              BaseItemWidget(item),
              const Divider(height: 0)
            ],
          ),
        );
      }).toList(),
    );
  }
}

Here is the widget inside that list:

class BaseItemWidget extends StatelessWidget {
  final dynamic item;

  const BaseItemWidget({Key? key, this.item}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    if (item is TextItem) {
      return TextItemWidget(item);
    } else if (item is EditableItem) {
      return EditableItemWidget(item);
    } else if (item is ImageItem) {
      return ImageItemWidget(item);
    } else if (item is BarcodeItem) {
      return BarcodeItemWidget(item);
    }
    return const SpaceItemWidget();
  }
}

The item inside all that widgets it’s also dynamic.

Solution

You could consider having each of your XItem classes extend an abstract BaseItem class, which has a widget method which constructs the right widget for the item. Something like this:

abstract class BaseItem {
  Widget widget();
}

class TextItem extends BaseItem {
  @override
  Widget widget() => TextItemWidget(this);
}

// Etc, for the other item types

class MyListView extends StatelessWidget {
  const MyListView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ReorderableListView(
      shrinkWrap: true,
      onReorder: provider.reorderList,
      children: provider.items.map((item) {
        return Dismissible(
          key: UniqueKey(),
          direction: DismissDirection.none,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              item.widget(),
              const Divider(height: 0)
            ],
          ),
        );
      }).toList(),
    );
  }
}

Answered By – Michael Horn

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published