1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Flutter】リストの作り方まとめ

Posted at

概要

Flutterでのいろいろなリストの作り方まとめ

普通のリスト

「ListVIew.builder」を使用する

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

  @override
  Widget build(BuildContext context) {
    final _data = ['data1', 'data2', 'data3', 'data4', 'data5'];
    return ListView.builder(
        itemCount: _data.length,
        itemBuilder: (BuildContext context, int index) {
          return ListTile(
            title: Text(_data[index]),
          );
        });
  }
}

区切り線付きのリスト

「ListView.separated」を使用する

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

  @override
  Widget build(BuildContext context) {
    final _data = ['data1', 'data2', 'data3', 'data4', 'data5'];
    return ListView.separated(
        itemCount: _data.length,
        separatorBuilder: (BuildContext context, int index) {
          return const Divider(
            color: Colors.grey,
            indent: 10,
            endIndent: 10,
          );
        },
        itemBuilder: (BuildContext context, int index) {
          return ListTile(
            title: Text(_data[index]),
          );
        });
  }
}

スワイプで削除できるリスト

「Dismissible」ウィジェットを使用する

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

  @override
  Widget build(BuildContext context) {
    final _data = ['data1', 'data2', 'data3', 'data4', 'data5'];
    return ListView.builder(
        itemCount: _data.length,
        itemBuilder: (BuildContext context, int index) {
          return Dismissible(
            key: Key(_data[index]),
            background: Container(
              color: Colors.red,
            ),
            confirmDismiss: (direction) async {
              // 削除の確認
              // falseの場合削除できない
              return true;
            },
            onDismissed: (direction) {
              // 削除が完了し、リサイズ終了時に呼ばれる
            },
            child: ListTile(
              title: Text(_data[index]),
            ),
          );
        });
  }
}

アニメーション付きリスト

「AnimatedList」を使用する

class SizeAnimatedListScreen extends StatefulWidget {
  const SizeAnimatedListScreen({Key? key}) : super(key: key);

  @override
  State<SizeAnimatedListScreen> createState() => SizeAnimatedListScreenState();
}

class SizeAnimatedListScreenState extends State<SizeAnimatedListScreen> {
  final GlobalKey<AnimatedListState> _listKey = GlobalKey();
  final _data = ['data1', 'data2', 'data3', 'data4', 'data5'];

  @override
  Widget build(BuildContext context) {
    return AnimatedList(
      key: _listKey,
      initialItemCount: _data.length,
      itemBuilder: (context, index, animation) {
        return _buildItem(_data[index], animation);
      },
    );
  }

  Widget _buildItem(String item, Animation<double> animation) {
    return SizeTransition(
      sizeFactor: animation,
      child: ListTile(
        title: Text(item),
        onTap: () {
          int insertIndex = _data.length;
          _data.add('data' + (insertIndex + 1).toString());
          _listKey.currentState?.insertItem(insertIndex,
              duration: const Duration(milliseconds: 100));
        },
        onLongPress: () {
          int removeIndex = _data.indexOf(item);
          _data.removeAt(removeIndex);

          _listKey.currentState?.removeItem(removeIndex, (context, animation) {
            return _buildItem(item, animation);
          }, duration: const Duration(milliseconds: 100));
        },
      ),
    );
  }
}

スライド動作させる場合は↓

class SlideAnimatedListScreen extends StatefulWidget {
  const SlideAnimatedListScreen({Key? key}) : super(key: key);

  @override
  State<SlideAnimatedListScreen> createState() =>
      SlideAnimatedListScreenState();
}

class SlideAnimatedListScreenState extends State<SlideAnimatedListScreen> {
  final GlobalKey<AnimatedListState> _listKey = GlobalKey();
  final _data = ['data1', 'data2', 'data3', 'data4', 'data5'];

  @override
  Widget build(BuildContext context) {
    return AnimatedList(
      key: _listKey,
      initialItemCount: _data.length,
      itemBuilder: (context, index, animation) {
        return _buildItem(_data[index], animation);
      },
    );
  }

  Widget _buildItem(String item, Animation<double> animation) {
    return SlideTransition(
      position: animation.drive(
          Tween<Offset>(begin: const Offset(1.0, 0), end: Offset.zero)
              .chain(CurveTween(curve: Curves.bounceInOut))),
      child: ListTile(
        title: Text(item),
        onTap: () {
          int insertIndex = _data.length;
          _data.add('data' + (insertIndex + 1).toString());
          _listKey.currentState?.insertItem(insertIndex,
              duration: const Duration(milliseconds: 200));
        },
        onLongPress: () {
          int removeIndex = _data.indexOf(item);
          _data.removeAt(removeIndex);

          _listKey.currentState?.removeItem(removeIndex, (context, animation) {
            return _buildItem(item, animation);
          }, duration: const Duration(milliseconds: 200));
        },
      ),
    );
  }
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?