kivyMDチュートリアル其の什 Components - Bottom Sheet篇

はい、皆さんおはこんばんは。
今日も元気にOSS活動、kivyMDのお時間です。

今週は特にこれといったことはないのですが、最近やっとkotlinのインプットも終わり
Flutterのインプットを始めました。まぁ、知らんよと突っ込みを入れられそうですが
これでようやく kivyMD vs Flutterの調査ができ始めます。ちょこちょこどちらの
性能がいいのかとか、どっちがアプリが作りやすいのかということも見ることが出来ます。
Flutterの方はまた今度の機会ということで。
\# 最近調子に乗っているので簡素なアプリでも作ろうかなとかイキがっています

はい、という前置きはどうでもよくて今週はBottom Sheetウィジェットの触れ込みに
なります。じゃあ、今週も元気にやっていきましょう。おー。(おそらく自分だけしか言ってない)

## Bottom Sheet

しつこいようですが、というか当たり前ですがMaterialDesignのリンクが冒頭にあります。
これも毎週のごとくここでは取り扱いません。と言っても、概要だけは見逃せないので少しだけ
触れておきます。マニュアルのキャプチャとか見ると、あぁあれねという声が聞こえそうなBottom
Sheetですが、アプリで下あたりによく見るものですね。別アプリとかで共有したいとかあったときに
出てくるあのやつです。

Bottom Sheetは2種類ほどあり、リストとグリッド形式とがあります。リストで表示するか2次元行列表示?
するかの2パターンということになりますかね。2つだけでなくそれ以外にカスタム形式というものもあります。
リストでもないグリッド表示でもない、本当にわがままに表示が出来ます。Usageとサンプルコードが同じに
なっているので、さっそくそっちに入りたいところですが、本日は汎用性が高いグリッド形式だけのコードの
触れ込みになります。詳細は後述しますが、リスト形式とグリッド形式はそれほど使い方に差がありません。

## Usage

ここで、サンプルコードを見てみましょう。今回は特にいじったところはありません。

```python:x/grid_bottomsheet.py
from kivy.lang import Builder

from kivymd.toast import toast
from kivymd.uix.bottomsheet import MDGridBottomSheet
from kivymd.app import MDApp

KV = '''
Screen:

    MDToolbar:
        title: 'Example BottomSheet'
        pos_hint: {"top": 1}
        elevation: 10

    MDRaisedButton:
        text: "Open grid bottom sheet"
        on_release: app.show_example_grid_bottom_sheet()
        pos_hint: {"center_x": .5, "center_y": .5}
'''


class Example(MDApp):
    def build(self):
        return Builder.load_string(KV)

    def callback_for_menu_items(self, *args):
        toast(args[0])

    def show_example_grid_bottom_sheet(self):
        bottom_sheet_menu = MDGridBottomSheet()
        data = {
            "Facebook": "facebook-box",
            "YouTube": "youtube",
            "Twitter": "twitter-box",
            "Da Cloud": "cloud-upload",
            "Camera": "camera",
        }
        for item in data.items():
            bottom_sheet_menu.add_item(
                item[0],
                lambda x, y=item[0]: self.callback_for_menu_items(y),
                icon_src=item[1],
            )
        bottom_sheet_menu.open()


Example().run()
```

### import

Bottom Sheetではこれまでと異なり、以下のパッケージをインポートする必要があります。

```python
from kivymd.uix.bottomsheet import MDGridBottomSheet
```

### kv側

今回のkv側は今後触れ込むという理由で、特に触れ込むところはないのですがButtonのイベントとして
Exampleクラスでメソッドを定義しているところがあります。

```python
MDRaisedButton:
    ~
    on_release: app.show_example_grid_bottom_sheet()
    ~
```

### Exampleクラス

buildメソッドとかはこれまで出てきたので、こちらも触れ込みませんが先に便宜上さっき出てきた
show_example_grid_bottom_sheetメソッドから触れ込みます。

#### show_example_grid_bottom_sheetメソッド

```
def show_example_grid_bottom_sheet(self):
        bottom_sheet_menu = MDGridBottomSheet()
        data = {
            "Facebook": "facebook-box",
            "YouTube": "youtube",
            "Twitter": "twitter-box",
            "Da Cloud": "cloud-upload",
            "Camera": "camera",
        }
        for item in data.items():
            bottom_sheet_menu.add_item(
                item[0],
                lambda x, y=item[0]: self.callback_for_menu_items(y),
                icon_src=item[1],
            )
        bottom_sheet_menu.open()
```

本日のメインディッシュになります。冒頭はMDGridBottomSheetクラスをインスタンス化していて、
bottom_sheet_menuに代入しています。リスト形式にするためには、ここをMDListBottomSheet
とします。カスタム形式にするためには、ここをMDCustomBottomSheetとしてカスタマイズしたクラス
を引数として迎え入れます。

その次にしていることでいうと、ディクショナリ型の変数に「表示名 : アイコンソース」という値を
代入しています。アイコンソースは後述するということで。

そして代入されたdataをイテレートして、bottom_sheet_menuが持っているadd_itemメソッドで
それぞれ値を設定しているようですね。add_itemの仕様としては以下になります。

`add_item(self, text, callback, icon_src)`
> Parameters: 
> > text – element text;
> > callback – function that will be called when clicking on an item;
> > icon_src – icon item;

※インデントができなくて引用をネストしています。

引数としては言うまでもないかもしれませんが、textはBottom Sheetでアイコンとともに表示させる
テキストになります。callbackにコールバックメソッドを指定しています。詳細は後ほどということで。
icon_srcは表示させるアイコンですね。表示させたいアイコンは過去のページだとかMaterialDesign
のサイトを見てもらえればと思います。

そして最後にインスタンスが持っているopenメソッドをおこないます。仕様としては以下の通り。


`open(self, *args)`

> Show the view window from the attach_to widget. If set, 
> it will attach to the nearest window. If the widget is 
> not attached to any window, the view will attach to 
> the global Window.

> When the view is opened, it will be faded in with an animation. 
> If you don’t want the animation, use:

> view.open(animation=False)

正直なところ前半にかけては、翻訳依頼をしてもよく分かりませんw
ただ後半部分は、デフォルトだとアニメーションをしているので、それをしたくなければ
openメソッドの中で上記のように引数を指定してくださいねということは分かります。
こちらのメソッドはMDBottomSheetで定義されているのでグリッドやリスト形式(カスタム含む)
関係なくopenメソッドを持ちます。でなければ表示されません。

#### callback_for_menu_itemsメソッド

で、今日最後の触れ込みですが、こちらはshow_example_grid_bottom_sheetメソッドでもあった
呼び出されるコールバックメソッドとなります。中身はtextを引数として単にtoastを呼び出している
だけです。toastはずっと先のBehaviors章の中でもあるのかな。まぁ詳細は今後触れるとして置いて
おきます。
\# 追加で見たのですがBehaviors章になくてAPIの方にありました
\# ここは対象外としているので時間があれば見るようにしておきます

> KivyMD » kivymd.toast » kivymd.toast.kivytoast » KivyToast
> https://kivymd.readthedocs.io/en/latest/api/kivymd/toast/kivytoast/kivytoast/

## 結果

といったところで、結果の方を見てみましょう。

![29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/7e509426-59f6-1c53-66c2-e7ea5cca9eb2.png)

![30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/9f7e6c84-5dd9-f84c-395c-ddf616b93bb4.png)

![31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/b254c276-2632-9639-e401-b8241c1c6ef1.png)

操作としては単純にBottom Sheetを表示して「Youtube」アイコンを押しているだけです。
toastの様子が伺えますね。

他のリスト形式とかカスタム形式はどうなってんのよ？という欲張りクォーターさんで好奇心旺盛な
方のために、触れ込みは省いているのですがこちらも実行した様子を載せておきます。

![32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/13518742-3d7d-f64b-7571-e43ca0d38d3d.png)


![33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/31e4447a-6d85-cba2-95fb-1d605d6340bc.png)

リスト形式の方は、アイコン表示出来ないのかと思い表示させるために少しコードを変更しています。
コードの詳細はgithubの方でということなのですが、こちらは注意が必要です。MDGridBottom-
Sheetではicon_srcという指定をしていましたが、こちらはiconという指定をする必要があります。
統一しなかったのかな...というか端折ったマニュアルの方で記載がありましたね。適宜そちらの方も
見てもらえると喜びます。

## まとめ

さぁ、今回はいかがだったでしょうか。Bottom Navigationとかを組み合わせると、もう立派な
スマホアプリになりそうです。何作ろうかなとワクワクしますね。出来るのはいつ頃かな、と悩みは
尽きないものですが。

少し、マニュアルの方が触れ込めなかったのが残念なところですが、他にも色々とカスタマイズ出来る
ところはあります。例えばアイコンのサイズを変更したりだとか、Bottom Sheetの角を丸みを帯び
させるだとか色々と見たいところはあるのですが、今週はこれでタイムアップということで。

であとは、来週からのことになりますが、順番通りに行くとBox Layoutになります。が、少しこの
あたりは他のレイアウトと一緒に触れ込めるのでまとめて取り扱っていきたいと思います。で、じゃあ
ButtonかCardなのかいと言われるとそうでもなくしようと思っています。だって量が多いもの。。
この辺りは比較的時間のあるゴールデンウィークあたりにやりたいなーと考えています。まぁ、ゴール
デンウィークがあればの話になりますが（泣）。

というわけで来週はCarouselからになります。時間も良いので、今日はこの辺で。

それでは、ごきげんよう。

## 参照

> Components » Bottom Sheet
> https://kivymd.readthedocs.io/en/latest/components/bottom-sheet/