Add item to ListView android

You might need to create lists that display different types of content. For example, you might be working on a list that shows a heading followed by a few items related to the heading, followed by another heading, and so on.

Heres how you can create such a structure with Flutter:

  1. Create a data source with different types of items.
  2. Convert the data source into a list of widgets.

1. Create a data source with different types of items

Types of items

To represent different types of items in a list, define a class for each type of item.

In this example, create an app that shows a header followed by five messages. Therefore, create three classes: ListItem, HeadingItem, and MessageItem.

/// The base class for the different types of items the list can contain. abstract class ListItem { /// The title line to show in a list item. Widget buildTitle(BuildContext context); /// The subtitle line, if any, to show in a list item. Widget buildSubtitle(BuildContext context); } /// A ListItem that contains data to display a heading. class HeadingItem implements ListItem { final String heading; HeadingItem(this.heading); @override Widget buildTitle(BuildContext context) { return Text( heading, style: Theme.of(context).textTheme.headline5, ); } @override Widget buildSubtitle(BuildContext context) => const SizedBox.shrink(); } /// A ListItem that contains data to display a message. class MessageItem implements ListItem { final String sender; final String body; MessageItem(this.sender, this.body); @override Widget buildTitle(BuildContext context) => Text(sender); @override Widget buildSubtitle(BuildContext context) => Text(body); }

Create a list of items

Most of the time, you would fetch data from the internet or a local database and convert that data into a list of items.

For this example, generate a list of items to work with. The list contains a header followed by five messages. Each message has one of 3 types: ListItem, HeadingItem, or MessageItem.

final items = List.generate( 1000, (i) => i % 6 == 0 ? HeadingItem('Heading $i') : MessageItem('Sender $i', 'Message body $i'), );

To convert each item into a widget, use the ListView.builder() constructor.

In general, provide a builder function that checks for what type of item youre dealing with, and returns the appropriate widget for that type of item.

ListView.builder( // Let the ListView know how many items it needs to build. itemCount: items.length, // Provide a builder function. This is where the magic happens. // Convert each item into a widget based on the type of item it is. itemBuilder: (context, index) { final item = items[index]; return ListTile( title: item.buildTitle(context), subtitle: item.buildSubtitle(context), ); }, )

Interactive example

import 'package:flutter/material.dart'; void main() { runApp( MyApp( items: List.generate( 1000, (i) => i % 6 == 0 ? HeadingItem('Heading $i') : MessageItem('Sender $i', 'Message body $i'), ), ), ); } class MyApp extends StatelessWidget { final List items; const MyApp({Key? key, required this.items}) : super(key: key); @override Widget build(BuildContext context) { const title = 'Mixed List'; return MaterialApp( title: title, home: Scaffold( appBar: AppBar( title: const Text(title), ), body: ListView.builder( // Let the ListView know how many items it needs to build. itemCount: items.length, // Provide a builder function. This is where the magic happens. // Convert each item into a widget based on the type of item it is. itemBuilder: (context, index) { final item = items[index]; return ListTile( title: item.buildTitle(context), subtitle: item.buildSubtitle(context), ); }, ), ), ); } } /// The base class for the different types of items the list can contain. abstract class ListItem { /// The title line to show in a list item. Widget buildTitle(BuildContext context); /// The subtitle line, if any, to show in a list item. Widget buildSubtitle(BuildContext context); } /// A ListItem that contains data to display a heading. class HeadingItem implements ListItem { final String heading; HeadingItem(this.heading); @override Widget buildTitle(BuildContext context) { return Text( heading, style: Theme.of(context).textTheme.headline5, ); } @override Widget buildSubtitle(BuildContext context) => const SizedBox.shrink(); } /// A ListItem that contains data to display a message. class MessageItem implements ListItem { final String sender; final String body; MessageItem(this.sender, this.body); @override Widget buildTitle(BuildContext context) => Text(sender); @override Widget buildSubtitle(BuildContext context) => Text(body); }