ListTile

Последнее обновление: 19.02.2021

Хотя в качестве элементов в ListView мы можем использовать различные виджеты, например, Container или Text, но более удобно использовать специально предназначенный виджет ListTile. ListTile представляет строку фиксированной высоты, которая обычно содержит некоторый текст и иконку, хотя это необязательно.

ListTile имеет следующий конструктор:

ListTile({Key key, Widget leading, Widget title, Widget subtitle, Widget trailing, bool isThreeLine: false, 
bool dense, VisualDensity visualDensity, ShapeBorder shape, EdgeInsetsGeometry contentPadding, 
bool enabled: true, GestureTapCallback onTap, GestureLongPressCallback onLongPress, MouseCursor mouseCursor, 
bool selected: false, Color focusColor, Color hoverColor, FocusNode focusNode, bool autofocus: false, 
Color tileColor, Color selectedTileColor})

Основные параметры конструктора:

  • autofocus: представляет тип bool и указывает, получит ли данный виджет фокус (при значении true)

  • contentPadding: устанавливает внутренние отступы между содержимым и границами контейнера в виде объекта EdgeInsetsGeometry

  • enabled: представляет тип bool и указывает, доступен ли элемент для взаимодействия

  • focusColor: устанавливает цвет Color, который принимает виджет при получении фокуса

  • hoverColor: устанавливает цвет Color, который принимает виджет при наведении указателя мыши

  • isThreeLine: представляет тип bool и указывает, будет ли элемент списка содержать трехстрочный текст

  • leading: виджет, который помещается перед элементом списка

  • mouseCursor: форма курсора, которую получает указатель мыши при наведении на данный элемент списка. Представляет тип MouseCursor

  • onLongPress: функция типа GestureLongPressCallback, которая вызывается при долгом нажатии на данный элемент списка

  • onTap: функция типа GestureTapCallback, которая вызывается при нажатии на данный элемент списка

  • selected: представляет тип bool и указывает, будет ли выделен данный элемент списка

  • selectedTileColor: устанавливает цвет, который получит ListTile при выделении

  • subtitle: устанавливает дополнительный виджет, который располагается под основным содержимым

  • tileColor: устанавливает цвет ListTile, когда виджет не выделен

  • title: устанавливает виджет, который представляет основное содержимое ListTile

  • trailing: устанавливает виджет, который отображается после основного содержимого

Основное содержимое в ListTile задается с помощью параметра title, в качестве которого может выступать любой виджет, но чаще всего применяется виджет Text:

import 'package:flutter/material.dart';

final List<String> users = ["Tom", "Alice", "Sam", "Bob", "Kate"];
void main() {
  runApp(MaterialApp(
      home:  Scaffold(
      body: ListView.separated(
          padding: const EdgeInsets.all(8),
          itemCount: users.length,
          separatorBuilder: (BuildContext context, int index) => Divider(),
          itemBuilder: (BuildContext context, int index) {
            return ListTile(title: Text(users[index], style:TextStyle(fontSize: 22)));
          }
      ),
        appBar: AppBar(title: Text("METANIT.COM")),)
  ));
}
ListTile в ListView в Flutter

С помощью параметра leading можно установить виджет, который будет отображаться перед виджетом из параметра title. Например, отобразим перед основным содержимым иконку:

import 'package:flutter/material.dart';

final List<String> users = ["Tom", "Bob", "Sam", "Mike"];
final List<IconData> icons = [Icons.face, Icons.tag_faces, Icons.work, Icons.book];

void main() {
  runApp(MaterialApp(
      home:  Scaffold(
      body: ListView.separated(
          padding: const EdgeInsets.all(8),
          itemCount: users.length,
          separatorBuilder: (BuildContext context, int index) => Divider(),
          itemBuilder: (BuildContext context, int index) {
            return ListTile(
                title: Text(users[index], style:TextStyle(fontSize: 22)),
                leading: Icon(icons[index]),
            );
          }
      ),
        appBar: AppBar(title: Text("METANIT.COM")),)
  ));
}

В данном случае использованы встроенные иконки, которые представляют объект IconData и которые передаются в виджет Icon() для отображения слева от заголовка ListTile:

Icons в ListTile в ListView в Flutter

Или, к примеру, добавим параметры trailing и subtitle, которые устанавливают соответственно виджеты после виджета title и под ним:

import 'package:flutter/material.dart';

final List<String> users = ["Tom", "Bob", "Sam", "Mike"];
final List<String> companies = ["Google", "Microsoft", "Apple", "JetBrains"];

void main() {
  runApp(MaterialApp(
      home:  Scaffold(
      body: ListView.separated(
          padding: const EdgeInsets.all(8),
          itemCount: users.length,
          separatorBuilder: (BuildContext context, int index) => Divider(),
          itemBuilder: (BuildContext context, int index) {
            return ListTile(
                title: Text(users[index], style:TextStyle(fontSize: 22)),
                leading: Icon(Icons.face),
                trailing: Icon(Icons.phone),
                subtitle: Text("Works in ${companies[index]}")
            );
          }
      ),
        appBar: AppBar(title: Text("METANIT.COM")),)
  ));
}
subtitle и trailing в ListTile в ListView в Flutter

Обработка выбора элемента

ListTile с помощью параметров onTap и nLongPress позволяет задать обработчики нажатия. В целом техника выбора элемента похожа на ту, что была описана в прошлой теме. В частности, определим следующий код:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
        home:  Scaffold(
        body: UsersList(),
        appBar: AppBar(title: Text("METANIT.COM")),)
  ));
}

class UsersList extends StatefulWidget {
  @override
  _UsersListState createState() => _UsersListState();
}
class _UsersListState extends State<UsersList> {
  final List<String> _users = ["Tom", "Alice", "Sam", "Bob", "Kate"];
  int _selectedIndex = -1;

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
        children: [
        Text(
            _selectedIndex==-1?"Не выбрано": "Выбрано: ${_users[_selectedIndex]}",
            style: TextStyle(fontSize: 30)),
        Expanded(child: ListView.builder(
          itemCount: _users.length,
          itemBuilder: (BuildContext context, int index) =>
              ListTile(
                onTap: () {
                  setState(() {
                    // устанавливаем индекс выделенного элемента
                    _selectedIndex = index;
                  });
                },
                title: Text(_users[index], style: TextStyle(fontSize: 24)),
                selected: index == _selectedIndex,
                selectedTileColor: Colors.black12,
              ),
        ))
      ]);
  }
}

В данном случае ListView инкапсулирован в отдельном виджете UsersList. В классе состояния виджета _UsersListState определяем данные, которые будут отображаться в ListView - список users и переменную _selectedIndex для отслеживания индекса выбранного элемента. По умолчанию _selectedIndex равен -1 для индикации, что на начальном этапе ни одного элемента не выбрано.

С помощью параметра onTap в конструкторе ListTile изменяем состояние - изменяем индекс выбранного элемента:

onTap: () {
  setState(() {
    // устанавливаем индекс выделенного элемента
    _selectedIndex = index;
  });
},

Чтобы указать, что элемент выделен, устанавливаем параметр selected:

selected: index == _selectedIndex,

И, кроме того, мы можем установить цвет выделенного элемента с помощью параметра selectedTileColor:

selectedTileColor: Colors.black12,

Результат работы программы:

select и onTap в ListTile в ListView в Flutter
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850