Jake Pucan
Jake Pucan

Reputation: 646

From function Widget to StatelessWidget in Flutter

I'm working on firestore from Google Lab example. What I want to happen is convert _buildList() and _buildListItem() function Widget into StatelessWidget including parameters because I red an article that splitting into function Widget is performance antipattern. But I don't know where to start. Anyone who can give a shed of light to this problem. Thank You.

class _VideoListState extends State<VideoList> {
  @override
  Widget build(BuildContext context) {
    ...
    body: StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection(widget.category).snapshots(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) return LinearProgressIndicator();
        // I want StatelessWidget not function widget
        return _buildList(context, snapshot.data.documents);
      },
    ),
  );
}

Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
    return ListView(
        // I want StatelessWidget not function widget
        children: snapshot.map((data) => _buildListItem(context, data)).toList(),            
  );
}

Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
  final record = Record.fromSnapshot(data);

  return Column(
    children: <Widget>[
        Text(record.title),
        YoutubePlayer(
             source: record.videoId.toString(),
             quality: YoutubeQuality.LOW,
             autoPlay: false,
             context: context
        );
    } 
}

Upvotes: 2

Views: 7201

Answers (1)

Marcos Boaventura
Marcos Boaventura

Reputation: 4741

It's simple. Take a look at the source code and read the comments. The source is auto explained by itself. I have used your methods names as class names.

// the method buildList into a stateless widget
class BuildListWidget extends StatelessWidget{
  final List<DocumentSnapshot> snapshotList;

  BuildListWidget({this.snapshotList}){} // you can use this approach to initialize your snapshotList. 
  // Here there parameter is already the member of class snapshotList

  @override
  Widget build(BuildContext context) {
    //building a listView in this way allows you build items on demand.
    return ListView.builder(
        itemCount: snapshotList.length, // number of items in list
        itemBuilder: (BuildContext context, int index){
          //creating list members. Each one with your DocumentSnapshot from list
          return BuildListItemWidget(
            dataSnapshot: snapshotList[index], // getting DocumentSnapshot from list
          );
        }
    );
  }
}


// the mehtod _buildListItem into a stateless widget
class BuildListItemWidget extends StatelessWidget {
  final DocumentSnapshot _data; // just if you want to hold a snapshot...
  final Record _record; // your record reference

//here another approach to inicialize class data using named parameters and
// initialization list in class contructor
  BuildListItemWidget({@required DocumentSnapshot dataSnapshot}) :
      _record = Record.fromSnapshot(dataSnapshot),
      _data = dataSnapshot;

  @override
  Widget build(BuildContext context) {
    return Column(
        children: <Widget>[
          Text(record.title),
          YoutubePlayer(source: _record.videoId.toString(),
            quality: YoutubeQuality.LOW,
            autoPlay: false,
            context: context
          );
    }
}

// usage...
class _VideoListState extends State<VideoList> {
  @override
  Widget build(BuildContext context) {
    ...
    body: StreamBuilder<QuerySnapshot>(
    stream: Firestore.instance.collection(widget.category).snapshots(),
    builder: (context, snapshot) {
    if (!snapshot.hasData) return LinearProgressIndicator();
    // so here you have a statelessWidget
    return  BuildListWidget( snapshotList: snapshot.data.documents );
    },
    ),
  }
}

Upvotes: 1

Related Questions