ListView

ListView component is a base component used to render Lists of items, as well as a featured first item with a unique layout. This component is also used by GridView to create Grid-like menu structures. Under the hood, it uses React Native’s FlatList and SectionList.

ListView example

API

Props

  • autoHideHeader: bool
    • Prop defining if ListView header should automatically hide
  • data: array
    • Prop containing items that will be rendered by the ListView component
  • loading: bool
    • Prop that defines whether the ListView should render loading spinner (to indicate it’s still loading data) or actual items (when the data is successfully loaded)
  • onLoadMore(): function
    • Called when the ListView is scrolled all the way to the bottom of the first page.
    • In this function you should update data array (state) with additional items
  • onRefresh(): function
    • Called when the ListView is pulled down, triggering the refresh action.
    • In this function you should update data array (state) with new items
    • If this function is declared, the Component will be considered refreshable
  • getSectionId(): function
    • Function that returns the section ID, this ID is used to group the items into a section
  • sections: array
    • Prop containing an array of individual sections to be rendered, as defined here
  • renderRow(item: Object): function
    • Function that renders each item (row) from data
  • renderHeader(): function
    • Function that renders the Header content
  • renderFooter(): function
    • Function that renders the Footer content
  • renderSectionHeader(): function
    • Function that renders the Section Header content
  • hasFeaturedItem: bool
    • Prop that defines whether or not the ListView being rendered has a featured item
  • renderFeaturedItem(): function
    • Function that renders
    • Note: If passing a sections prop, renderFeaturedItem will be ignored, since you can simply create a section containing the featured item along with it’s render function.

Style

  • list
    • These Props are passed to Style Prop of underlying React-Native ListView component
  • listContent
    • These Props are passed to contentContainerStyle Prop of underlying React-Native ListView component
  • loadMoreSpinner
    • These Props are passed to Style Prop of the Spinner component that appears during initial content loading
  • refreshControl
    • These Props are passed to Style Prop of the RefreshControl component.
    • You can also define refreshControl.tintColor prop in this Style, which is passed to the tintColor prop of the RefreshControl component.

Examples

ListView example

Simple list example


JSX declaration

constructor(props) {
  super(props

  this.renderRow = this.renderRow.bind(this);

  this.state = {
    restaurants: [
      {
        "name": "Gaspar Brasserie",
        "address": "185 Sutter St, San Francisco, CA 94109",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-1.jpg" },
      },
      {
        "name": "Chalk Point Kitchen",
        "address": "527 Broome St, New York, NY 10013",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-2.jpg" },
      },
      {
        "name": "Kyoto Amber Upper East",
        "address": "225 Mulberry St, New York, NY 10012",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-3.jpg" },
      },
      {
        "name": "Sushi Academy",
        "address": "1900 Warner Ave. Unit A Santa Ana, CA",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-4.jpg" },
      },
      {
        "name": "Sushibo",
        "address": "35 Sipes Key, New York, NY 10012",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-5.jpg" },
      },
      {
        "name": "Mastergrill",
        "address": "550 Upton Rue, San Francisco, CA 94109",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-6.jpg" },
      }
    ],
  }
}

renderRow(restaurant) {
  if (!restaurant) {
    return null;
  }

  return (
    <View>
      <ImageBackground
        styleName="large-banner"
        source={{ uri: restaurant.image.url }}
      >
        <Tile>
          <Title styleName="md-gutter-bottom">{restaurant.name}</Title>
          <Subtitle styleName="sm-gutter-horizontal">{restaurant.address}</Subtitle>
        </Tile>
      </ImageBackground>
      <Divider styleName="line" />
    </View>
  );
}

render() {
  const { restaurants } = this.state;

  return (
    <Screen>
      <NavigationBar
        title="Restaurants"
        styleName="inline"
      />
      <ListView
        data={restaurants}
        renderRow={this.renderRow}
      />
    </Screen>
  );
}


JSX declaration

constructor(props) {
  super(props

  this.renderRow = this.renderRow.bind(this);
  this.renderFeaturedItem = this.renderFeaturedItem.bind(this);

  this.state = {
    restaurants: [
      {
        "name": "Gaspar Brasserie",
        "address": "185 Sutter St, San Francisco, CA 94109",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-1.jpg" },
      },
      {
        "name": "Chalk Point Kitchen",
        "address": "527 Broome St, New York, NY 10013",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-2.jpg" },
      },
      {
        "name": "Kyoto Amber Upper East",
        "address": "225 Mulberry St, New York, NY 10012",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-3.jpg" },
      },
      {
        "name": "Sushi Academy",
        "address": "1900 Warner Ave. Unit A Santa Ana, CA",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-4.jpg" },
      },
      {
        "name": "Sushibo",
        "address": "35 Sipes Key, New York, NY 10012",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-5.jpg" },
      },
      {
        "name": "Mastergrill",
        "address": "550 Upton Rue, San Francisco, CA 94109",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-6.jpg" },
      }
    ],
  }
}

renderFeaturedItem(restaurant) {
  if (!restaurant) {
    return null;
  }

  return (
    <View styleName="sm-gutter featured">
      <ImageBackground
        styleName="featured placeholder"
        source={{ uri: restaurant.image.url }}
      >
        <Tile>
          <Title>{(restaurant.name || '').toUpperCase()}</Title>
          <View styleName="horizontal md-gutter-top" virtual>
            <Caption
              styleName="collapsible"
              numberOfLines={1}>
              {restaurant.address}
            </Caption>
          </View>
        </Tile>
      </ImageBackground>
    </View>
  );
}

renderRow(restaurant) {
  if (!restaurant) {
    return null;
  }

  return (
    <View>
      <ImageBackground
        styleName="large-banner"
        source={{ uri: restaurant.image.url }}
      >
        <Tile>
          <Title styleName="md-gutter-bottom">{restaurant.name}</Title>
          <Subtitle styleName="sm-gutter-horizontal">{restaurant.address}</Subtitle>
        </Tile>
      </ImageBackground>
      <Divider styleName="line" />
    </View>
  );
}

render() {
  const { restaurants } = this.state;

  return (
    <Screen>
      <NavigationBar
        title="Restaurants"
        styleName="inline"
      />
      <ListView
        data={restaurants}
        renderFeaturedItem={this.renderFeaturedItem}
        renderRow={this.renderRow}
      />
    </Screen>
  );
}

Rendering sections example


JSX declaration

constructor(props) {
  super(props

  this.renderRow = this.renderRow.bind(this);

  this.state = {
    restaurants: [
      {
        "name": "Gaspar Brasserie",
        "address": "185 Sutter St, San Francisco, CA 94109",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-1.jpg" },
      },
      {
        "name": "Chalk Point Kitchen",
        "address": "527 Broome St, New York, NY 10013",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-2.jpg" },
      },
      {
        "name": "Kyoto Amber Upper East",
        "address": "225 Mulberry St, New York, NY 10012",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-3.jpg" },
      },
      {
        "name": "Sushi Academy",
        "address": "1900 Warner Ave. Unit A Santa Ana, CA",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-4.jpg" },
      },
      {
        "name": "Sushibo",
        "address": "35 Sipes Key, New York, NY 10012",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-5.jpg" },
      },
      {
        "name": "Mastergrill",
        "address": "550 Upton Rue, San Francisco, CA 94109",
        "image": { "url": "https://shoutem.github.io/static/getting-started/restaurant-6.jpg" },
      }
    ],
  }
}

renderRow(restaurant) {
  if (!restaurant) {
    return null;
  }

  return (
    <View>
      <ImageBackground
        styleName="large-banner"
        source={{ uri: restaurant.image.url }}
      >
        <Tile>
          <Title styleName="md-gutter-bottom">{restaurant.name}</Title>
          <Subtitle styleName="sm-gutter-horizontal">{restaurant.address}</Subtitle>
        </Tile>
      </ImageBackground>
      <Divider styleName="line" />
    </View>
  );
}

render() {
  const { restaurants } = this.state;

  const sections = {[
    { title: 'New York', data: { restaurants[1], restaurants[2], restaurants[4] }},
    { title: 'San Francisco', data: { restaurants[0], restaurants[5] }},
    { title: 'Santa Ana', data: { restaurants[3] }},
  ]};

  return (
    <Screen>
      <NavigationBar
        title="Restaurants"
        styleName="inline"
      />
      <ListView
        sections={sections}
        renderRow={this.renderRow}
      />
    </Screen>
  );
}