Help us understand the problem. What is going on with this article?

【Flutter】人気なパッケージの使い方 〜flutter_slidable編〜

まえがき

2020年入ってからFlutterの勉強を初めてきました。
今後いろんなパッケージをもっと勉強していきたいと思ってるので、人気なものをアウトプットとして記事にしていきたいと思います。

今回はurl_launcherと言うパッケージを紹介します。

これまで載せた記事
- shared_preferencesの紹介
- url_launcherの紹介
- flutter_slidable←今これ

flutter_slidable

flutter_slidableはListTileに使うWidgetです。
ListTileを横にスライドさせることができるようになります。

スライドさせると、アイコン、タイトル文字、色、押した時の挙動を設定できます。

サンプル

簡単なTODOリストを作りました。
今回はFirestoreは使用していませんが、使った場合にも応用できるようにモデルクラスも作成しました。

flutter_slidable.gif

import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';

final toDoList = [
  {"title": "買い物にいく"},
  {"title": "犬の散歩"},
  {"title": "明日の準備"},
  {"title": "家族に電話する"},
];

class SampleSlidable extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => SampleSlidableState();
}

class SampleSlidableState extends State<SampleSlidable> {
  final itemController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('flutter_slidable'),
      ),
      body: ListView(
        children: toDoList.map((data) => _buildItem(context, data)).toList(),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          formForNewItem(context);
        },
      ),
    );
  }

  Widget _buildItem(BuildContext context, Map data) {
    Item toDoItem = Item.fromMap(data);
    //Slidableはここから
    return Slidable(
      actionExtentRatio: 0.2,
      actionPane: SlidableScrollActionPane(),
      // 左側に表示するWidget
      actions: <Widget>[
        IconSlideAction(
          caption: '重要',
          color: Colors.yellow,
          icon: Icons.star,
          onTap: () {},
        ),
        IconSlideAction(
          caption: '共有',
          color: Colors.blue,
          icon: Icons.share,
          onTap: () {},
        ),
      ],
      // 右側に表示するWidget
      secondaryActions: [
        IconSlideAction(
          caption: '削除',
          color: Colors.red,
          icon: Icons.remove,
          onTap: () {
            toDoList.remove(data);
            setState(() {});
          },
        ),
      ],
      // 一つ一つのアイテム
      child: Container(
        padding: EdgeInsets.only(left: 20),
        decoration: BoxDecoration(
            border: Border(bottom: BorderSide(width: 1.0, color: Colors.grey))),
        child: ListTile(
          leading: Icon(Icons.chevron_right),
          title: Text(toDoItem.title),
        ),
      ),
    );
  }

// アイテムを追加するダイアログ
  formForNewItem(BuildContext context) {
    showDialog(
      context: context,
      builder: (_) {
        return SimpleDialog(
          title: Text('新しく追加する'),
          children: [
            Container(
              padding: EdgeInsets.all(20),
              child: TextFormField(
                controller: itemController,
              ),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                FlatButton(
                  child: Text('キャンセル'),
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                ),
                FlatButton(
                  child: Text('OK'),
                  onPressed: () {
                    toDoList.add({"title": itemController.text});
                    Navigator.of(context).pop();
                    itemController.clear();
                    setState(() {});
                  },
                )
              ],
            )
          ],
        );
      },
    );
  }
}

// アイテムクラス
class Item {
  String title;
  bool star;

  Item({this.title, this.star});

  Item.fromMap(Map<String, dynamic> mapData) {
    this.title = mapData["title"];
    this.star = mapData["star"];
  }
}

説明

説明は、Slidableにします。他のコードは簡単なので読んで理解していただきたいです。。

  • actionExtentRatio:スライドさせたときに表示するWidgetの大きさの指定
  • actionPane:スライドさせた時のアニメーション(4種類あるのであとで詳細説明)
  • actions:左側に表示するWidget。IconSlideActionを使う
  • secondaryActions:右側に表示するWidget。IconSlideActionを使う

最低限これが使えれば大丈夫そう。

actionssecondaryActionsに使うIconSlideAction
- caption:タイトル文字
- color:Widgetの色
- icon:アイコン
- onTap:タップした時の挙動

を設定できます。
今回は削除だけタップした時の挙動をちゃんと作成しました。

IconSlideAction(
  caption: '削除',
  color: Colors.red,
  icon: Icons.remove,
  onTap: () {
    toDoList.remove(data);
    setState(() {});
  },
 ),

これで削除できます。

次にactionPaneの説明します。
公式ドキュメントの方がわかりやすいかもしれませんが、Gifも載せておきます。

  • SlidableBehindActionPane()

ListTileの後ろのWidgetが隠れているような表示されます。
しかしこれはListTileの文字が重なって見えてしまうので、僕はあまり好きではありません。
(僕の知識、技術不足でこうなってるかもしれないけど)

SlidableBehindActionPane.gif

  • SlidableScrollActionPane

ListTileの横にWidgetがついてるような表示されます。したがって、ただスライドさせてるようなアニメーションですね。

SlidableScrollActionPane.gif

  • SlidableDrawerActionPane

ListTileの横から引き出しのように表示されます。

SlidableDrawerActionPane.gif

  • SlidableStrechActionPane

ListTileの横からWidgetが延びるように表示されます。

SlidableStrechActionPane.gif

僕はSlidableScrollActionPaneが一番好きですね。

あとこのパッケージはスライドさせてSlidableを表示してる状態で縦にスクロールすると、自動でSlidableを閉じてくれたりするのも便利でいいですね〜〜

思いつく使い道

ListTileを使うところでつかいますよね

パッケージのソースコード読んでみた感想

Slidableクラスはアニメーションとかたくさん使ってて、まだすんなりとは読めない
IconSlideActionクラスは結構簡単でFlexible使ってるんだーって思いました。
あと、プロパティが他に何があるのか知る機会になりました。

iconWidgetって言うのもあって、

icon
iconWidget
caption

の順番い表示されてた。テキストはcaptionで十分だし特に使う機会はあまりなさそう。

パッケージのソースコードちゃんと見たのは初めてでしたが、すごい複雑でまだまだ理解しきれない。

ryota47
Flutterをはじめました。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした