Flutter abstract class with different widgets in a list view

Viewed 684

I'm trying to figure out how to show a list view with mixed items. I can't figure out how to show the list items. Please consider the following code. This should just run (except for the error on line 82 now.

I've created an abstract class and a class that implements a Text area and a class that implements a button area. I'm mixing them up as that would be the way the data flows in. Randomly.

So I can build the mixed class, I just don't know how to do the final display on my screen.

import 'package:flutter/material.dart';

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

abstract class  MixedWidgets{
  //Different type of widgets I want to mix randomly;
  Widget buildText(BuildContext context);
  Widget buildButton(BuildContext context);
}

//this should show some text
class TextClass implements MixedWidgets{
  Widget buildButton(BuildContext context) => null;

  TextClass({this.textStringToPrint});

  String textStringToPrint;

  Widget buildText(BuildContext context){
    return Container(
      child: Text(textStringToPrint),
    );
  }
}

//This should show a button
class ButtonClass implements MixedWidgets{
  Widget buildText(BuildContext context) => null;

  ButtonClass({this. buttonNumber});

  int buttonNumber;

  Widget buildButton(BuildContext context){
    return FlatButton(
        onPressed: null,
        child: Text('This is button number $buttonNumber'),
    );
  }
}

//List<MixedWidgets> myListOfMixedWidgets = [];
final firstN = ButtonClass(buttonNumber: 1);
final secondN = ButtonClass(buttonNumber: 2);
final thirdN = ButtonClass(buttonNumber: 3);
final fourthN = ButtonClass(buttonNumber: 4);
final fifthN = ButtonClass(buttonNumber: 5);

final firstT = TextClass(textStringToPrint: 'one');
final secondT = TextClass(textStringToPrint: 'two');
final thirdT = TextClass(textStringToPrint: 'three');
final fourthT = TextClass(textStringToPrint: 'four');



class MyApp extends StatelessWidget {
  //Mix up my different classes and widgets in here
  List<MixedWidgets> myListOfMixedWidgets = [
    firstN,
    secondN,
    firstT,
    thirdN,
    fourthN,
    secondT,
    thirdT,
    fourthT,
    fifthN,
  ];


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
      appBar: AppBar(),
      body: SafeArea(
        child: Container(
          child: ListView(
            //How do I do this?  I need to show the mixed list here?
            children: myListOfMixedWidgets,
          ),
        ),
      )
    )
    );
  }
}
1 Answers

The strategy you will want to use here is polymorphism. Use Widget, the super class of StatelessWidget and StatefulWidget, to create a heterogenous List of Widgets (List<Widget>).

If TextClass and ButtonClass inherit from some descendant of Widget then they can all be added to the list of widgets. This works for ListView because its children parameter is only aware of Widget.

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

  @override
  Widget build(BuildContext context) {
    return Text("Text!");
  }
}

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

  @override
  Widget build(BuildContext context) {
    return FlatButton(
      onPressed: null,
      child: Text("Button!");
    );
  }
}

final ButtonClass firstN = ButtonClass();
final TextClass firstT = TextClass();

class MyApp extends StatelessWidget {
  // Polymorphism here:
  List<Widget> myListOfMixedWidgets = [
    firstN,
    firstT,
  ];

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: myListOfMixedWidgets,
    );
  }
}
Related