kivyMDチュートリアル其の玖 Components - Bottom Navigation篇

はい、今日もやって参りました。kivyMDのお時間です。
今日も元気にOSS活動！ということで今週もやっていこうと思います。

今週は何といっても、LI○Eの話題が多くありましたね。自分もある程度kivyMDを使いこなせる
ようになれば、メッセージ交換アプリとか作ろうかなぁと思った次第です。ただ、あそこまで
作り込むことは無理ゲーにはなりますが。

という横道も外れながらですが、早速やっていきたいと思います。
今週はBottom Navigationということで、よくスマホアプリとかで下あたりにあるUIパーツになります。

## Bottom Navigation

はい、毎週のごとくMaterial Designのリンクを見てよという案内からになります。
ここではこちらも毎週のごとく触れ込みは省きますが、一応概要だけ。

特に説明もなくとも、どんなことをするのかということはイメージしやすいと思いますが
Material Designのリンク上では目的地を表示させるものとあります。アイコンやテキスト
を併用して使用されることがよくあり、まさにこれはナビゲーションという用語がマッチする
なということがよく分かります。

## Usage

使い方は以下のようにするみたいです。

```python
<Root>>:

    MDBottomNavigation:

        MDBottomNavigationItem:
            name: "screen 1"

            YourContent:

        MDBottomNavigationItem:
            name: "screen 2"

            YourContent:

        MDBottomNavigationItem:
            name: "screen 3"

            YourContent:
```

MDBottomNavigationウィジェットの配下にまたMDBottomNavigationItemウィジェット
を配置させるという記法になっています。MDBottomNavigationウィジェットに見せたい
コンテンツを配置させるという記法も併せ持っています。

```
<Root>>:

    ScreenManager:

        Screen:
            name: "screen 1"

            YourContent:

        Screen:
            name: "screen 2"

            YourContent:

        Screen:
            name: "screen 3"

            YourContent:
```

分かりやすくすると、こうなるぜというのが上記の疑似コードだという説明があります。
分かりやすいか?と少し思ってしまいますが、まだまだkivy力が足りないんだと思うだけ
にここはしておきます。

## Example

ということで、サクサクと進んでいますがサンプルコードに入っていこうと思います。
今回はマニュアル通りだとつまらないので、少しこれまでに試したことも併せながら
コードを少し変更しています。

```python:ix/bottom_navigation.py
from kivymd.app import MDApp
from kivy.lang import Builder

### font package
from kivy.core.text import LabelBase
from kivymd.font_definitions import theme_font_styles

class Test(MDApp):

    def build(self):
        ### self.theme_cls.primary_palette = "Gray"
        
        ### add font info
        LabelBase.register(name="gomarice_mukasi_mukasi",fn_regular="gomarice_mukasi_mukasi.ttf")
        theme_font_styles.append('gomarice_mukasi_mukasi')
        self.theme_cls.font_styles["gomarice_mukasi_mukasi"] = ["gomarice_mukasi_mukasi", 32, 0.15]

        return Builder.load_string(
            '''
BoxLayout:
    orientation:'vertical'

    MDToolbar:
        title: 'Bottom navigation'
        #md_bg_color: .2, .2, .2, 1
        #specific_text_color: 1, 1, 1, 1

    MDBottomNavigation:
        #panel_color: .2, .2, .2, 1

        MDBottomNavigationItem:
            name: 'screen 1'
            text: 'season1'
            icon: 'human-male-female'

            MDLabel:
                text: 'いま今、あるところにおじいさんと\\nおばあさんがいました。'
                font_style: "gomarice_mukasi_mukasi"
                halign: 'center'

        MDBottomNavigationItem:
            name: 'screen 2'
            text: 'season2'
            icon: 'golf-cart'

            MDLabel:
                text: 'おじいさんは山でゴルフに、\\nおばあさんは近所の\\nコインランドリーへ。'
                font_style: "gomarice_mukasi_mukasi"
                halign: 'center'

        MDBottomNavigationItem:
            name: 'screen 3'
            text: 'end.'
            icon: 'clock-end'

            MDLabel:
                text: 'めでたし、めでたし。'
                font_style: "gomarice_mukasi_mukasi"
                halign: 'center'
'''
        )


Test().run()
```

さぁ、勘の良い方は何をするのか、ははーんとなるかもしれませんがそういうことになります。
何をするのか分からない方はもう少しお待ちください。

まず、今回も先週と同じようにkv側を中心に見ていきます。buildメソッドの方ではカスタムで
色々ごにょごにょやっていますが、こちらは以前にもやったフォントの取り込みなので興味が
ある方は以下リンクを見られてください。
[kivyMDチュートリアル其の伍 Themes - Icon Definitions篇](https://qiita.com/virty/items/97499128a205113431d5)
ただただこのメソッドは、kvで定義したものを読み取っているだけです。


```python
BoxLayout:
    orientation:'vertical'

    MDToolbar:
        title: 'Bottom navigation'
        #md_bg_color: .2, .2, .2, 1
        specific_text_color: 1, 1, 1, 1

    MDBottomNavigation:
        #panel_color: .2, .2, .2, 1

        MDBottomNavigationItem:
            name: 'screen 1'
            text: 'season1'
            icon: 'human-male-female'

            MDLabel:
                text: 'いま今、あるところにおじいさんと\\nおばあさんがいました。'
                font_style: "gomarice_mukasi_mukasi"
                halign: 'center'
```

ということで本日のメインディッシュであるkv側の触れ込みになります。

まず、BoxLayoutはもういいでしょうかね。こちらは縦積みをするレイアウトウィジェットに
なります。で、あとのMDToolbarもどうせ後でやるしで、ここでは触れ込んでいきません。

で、残ったMDBottomNavigationとMDBottomNavigationItemになりますが、こちらも
マニュアルのUsageであった通りになりますね。んー、実にシンプルな使用方法。

MDBottomNavigationですが、マニュアルの仕様だと以下のようになります。

### class kivymd.uix.bottomnavigation.MDBottomNavigation(**kwargs)

> A bottom navigation that is implemented by delegating all items to a ScreenManager.

`first_widget`
> first_widget is an MDBottomNavigationItem and defaults to None.

`tab_header`
> tab_header is an MDBottomNavigationHeader and defaults to None.

`text_color_normal`
> Text color of the label when it is not selected.
> text_color_normal is an ListProperty and defaults to [1, 1, 1, 1].

`text_color_active`
> Text color of the label when it is selected.
> text_color_active is an ListProperty and defaults to [1, 1, 1, 1].

(省略)

冒頭の説明は翻訳が非常に難しいものがありますが、全てのアイテムをScreenManagerに
移譲させることによって実装させるUIウィジェットとなる、そういったことになりますかね。
えぇ、どういうこと？w すみません、分かったフリして実は分かっていません。翻訳したもの
をさらにこっちの方かなという書き換えをやって載せただけで余計複雑になってしまいました。
ScreenManagerがInterface役??なのか。。MDBottomNavigationがScreenManager
と同じということ？？このままだと、謎がさらに謎を呼びそうなのであまり触れ込みすぎない
ようにします。\# よし、今後の課題っと

特にサンプルコード上のプロパティなどはpanel_color(これもマニュアル記載ない。。)
くらいで、触れ込む必要もなさそうです。ただし、上記でもあるtext_color_normalと
text_color_activeプロパティは注意が必要そうです。こちらは定義をしても動きません
でしたー。おそらく現状のissueリストとかでは挙げられているかもしれません。なぜなら
変な翻訳サイトでまさしくこちらが話題に挙がっていましたから。。

というわけでよく分からないまま、MDBottomNavigationItemに入っていきます。こちらの
仕様としては、以下になります。こちらはシンプルな情報量。

### class kivymd.uix.bottomnavigation.MDBottomNavigationItem(**kwargs)

> A tab is simply a screen with meta information that defines the content that goes in the tab header.

`header`
> header is an MDBottomNavigationHeader and defaults to None.

`on_tab_press(self, *args)`

`on_leave(self, *args)`

冒頭の説明としては、翻訳に依頼したものが信頼度は高そうなので依頼したものをそのまま
貼っておきます。

> A tab is simply a screen with meta information that defines the content that goes in the tab header.
> タブは、タブヘッダーに含まれるコンテンツを定義するメタ情報を含む単なる画面です。 

これも理解できないほどではありませんが、上記のようになるとのことです。
いきなり、タブがなぜ出てきた...？ということで自身はkivyのTabを継承しているのかとも
思っていますが、どうなのでしょうね。位置するところはMDTabsと同じなのか？こればかり
はまだはっきりとしてはいませんが、こちらはどちらかなのだろうと捉えるしかありません。

マニュアルには記載されていませんが、コード上でnameやtextプロパティを保持している
ところからやはりMDBottomNavigationItem=MDTabsということなのでしょうか。また、
今回はcontentとしてMDLabelが定義されています。これもおそらくScreenが配置できる
のであれば、Listだとか色々なウィジェットを配置出来そうです。ということで、触れ込み
はこの辺にしたいと思います。

## 結果

はよ、結果はよということを思われるかもしれないので、一気に結果の方を
載せていきたいと思います。論より証拠をということで以下にキャプチャを
添付します。

![26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/53cea486-e51f-481b-4a4c-2c61f221bd0e.png)

![27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/5cc74b44-f04e-cfc6-9f38-6d61a62e0783.png)

![28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82826/3d6231ed-8541-ea4e-53f1-b6848db27358.png)

ということで今日したかったことでいうと、以前に1画面で終わる昔話のストーリーを
アレンジということでした。なので、動かすときにはフォントを取得するようにして
おいてください。別に同じフォントを用意する必要はありませんが、その場合はコードを
変更するということもお忘れなく。前回はストーリーが直ぐに終わり、寂しかったものが
リッチになりました。あとは、いうまでもなくですが無意味にテーマをデフォルトにしています。

1つ補足というか注意点ですが、MDBottomNavigationItemにあるtextプロパティですが
こちらは日本語がうまく表示できませんでした。なのでアイテムを切り替えるときのアイコン
とともに表示されているテキストは英語表記をしなければいけないという制限ももれなく付いちゃいます。

## まとめ

さぁ、いかがだったでしょうか。使用方法は簡単でしたが、マニュアルを読み解くのに苦労する
かなぁと思ってしまいました。自分だけ思ってることであれば良いのですが。。それでも今後の
アプリ開発として使うには協力な武器になると思われます。これを動かしたときはあ、もうアプリが
出来たなと勝手に思い込んでしまいました。全然まだまだ、コンポーネントは限りないのですが。。

ということで今週はこれまでにしたいと思います。
それでは、ごきげんよう。

## 参照

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