さて、今回はデータの永続化について見ていきたいと思います。
一番簡単な方法はSharedPreferencesを使う方法なので、まずはこちらから。

簡単に使えますが、キーと値のペアを保存するだけなので、アプリの設定値などごく小さい単位のデータの保存に使います。
大きなデータには向かないのでご注意を。

今回はSharedPreferencesの使い方だけ見ていきたいと思うので、AndroidStudioのプロジェクトは作らずに、コードの紹介だけしたいと思います。
いろいろなサイトで紹介されていますが、Kotlinでの書き方を紹介します。

もくじ

1. SharedPreferencesを生成してみよう
2. データを読み込んでみよう
3. データを書き込んでみよう
4. 複数のSharedPreferencesを使ってみよう

1. SharedPreferencesを生成してみよう

まずはSharedPreferenceのインスタンスを生成する必要があります。と言っても簡単でActivityにgetPreferencesというメソッドが用意されているのでそれを使います。

引数はアクセス権限の指定で、いろいろモードはあるのですが、現在推奨されているのはMODE_PRIVATEのみなようです。このアプリ内のみで使う、といった指定ですね。

上記の例はActivityから使う場合の書き方です。
もし、Fragmentなどから使う場合にはContextの取得が必要なので、以下のように書いてください。

以降はActivity内で実行することを前提として話を進めます。

2. データを読み込んでみよう

SharedPreferenceからデータを読み込むにはgetInt()getString()といった具合に、取得したいデータのデータ型に応じたメソッドを使う必要があります。

例えば、「count」というキー値に対応しているデータを取得したい場合には以下のように書いてあげます。

1つ目の引数がキー値ですね。2つ目の引数はキーが存在しない場合のデフォルト値になります。

なので上の例だと、countというキーのデータがSharedPreferenceにあればそれを取得、もしキーがなければ0が取得できるというわけです。

3. データを書き込んでみよう

データの書き込みはちょっと面倒だったりします。
SharedPreferenceのインスタンスから、SharedPreferences.Editorというのを生成して上げる必要があります。
それから、putInt()putString() といったメソッドを使用してキーと値をセットしたあとに、commit()メソッドを使って保存する、といった流れになります。

上記の例は、SharedPreferencesからcountのデータを取得して、countを更新後、再びSharedPreferencesに書き込む、といったものです。

最後のcommit()は忘れがちなのでご注意を…。(私はそれでしばらく悩みましたw)

書き込むのが1つだけでshardPrefEditorとかいちいち変数を用意するのが面倒な場合は、下記のようにまとめて書いちゃうことも可能です。

4. 複数のSharedPreferencesを使ってみよう

保存する値が少ない場合などは今までのやり方で問題ないのですが、例えば画面毎に分けたいなどといった場合は、複数個生成することが可能です。

SharedPreferencesのインスタンスを作るときに、getSharedPreferences()というメソッドを使ってあげればOKです。

1つ目の引数は識別子になります。ここを変更することで複数のSharedPreferencesを持つことができるようになります。
識別子は「com.example.myapp.PREFERENCE_FILE_KEY」といったようにアプリを一意に識別できるような名前にすることが推奨されています。

2つ目の引数はgetPreferences()のときと同じようにアクセス権限を指定します。こちらもMODE_PRIVATEを使うようにしましょう。

読み書きは今までと同様です。
シンプルなサンプルですが、次のように使えばOKです。ここでは同じActivityで2つのSharedPreferencesを使うようになっています。

SharedPreferencesの識別子が違うものになっていれば、キー値は同じものが使えます。
このソースが実行されるたびに、count1は1ずつ、count2は2ずつカウントアップされていきます。
本来、アプリの設定値などを保存するためのものなので、このサンプルの使い方はそれとは違うものになっているので、動作の参考にとどめてくださいね。

簡単でしたが、SharedPreferencesのKotlinでの使い方の紹介でした。

前回からずいぶん間が空いてしまいました💦
色々立て込んでまして…。またぼちぼち更新していけたらなと思ってます。

さて、今回はOptionsMenu(オプションメニュー)の使い方について見ていきたいと思います。
最近はナビゲーションメニューが追加されて、あまり使われていないのかなぁとも思ったのですが、
Androidの設定画面やTwitterクライアントとかいろいろなところで地味に今でも使われているので
ちょっと扱ってみたいと思います。

さて、今回の目次はこんな感じになりました。

もくじ

1. 開発環境
2. プロジェクトを作ろう
3. 画面を作ろう
4. メニューを作ろう
5. メニューを選択してみよう
6. メニューのアイテムをアイコンで表示してみよう
7. メニューのアイテムを非表示、無効化してみよう

今回紹介したアプリのソースはGitHubにもあるので合わせてご参照ください。

1. 開発環境

  • AndroidStudio 3 Preview (Canary 3)
  • Kotlin
  • Java 1.8
  • macOS Sierra (10.12.6)

基本的にはAndroidStudio 2.3でも同じように作れます。

バージョンが変わるとエラーが出たり動かなくなったりするかもしれませんが、
エラーメッセージをよく読んで指示に従ったり、検索などして調べてみてくださいませ。

AndroidStudio と Java はすでにインストールされている前提で進めますのでご了承ください。

2. プロジェクトを作ろう

さて、プロジェクトを作っていくわけですが、前回までとちょっとだけ変わっているので、順を追って説明していこうと思います。

Kotlin Android OptionsMenu(オプションメニュー)を使ってみよう

「Application Name」は「OptionsMenuSample」にしました。お好きなものにしてくださいませ。
「Company Domain」は適当なものを指定してください。
「Include Kotlin support」には必ずチェックを入れてください。
「Project Location」は保存場所になるのでデフォルトの場所で大丈夫だと思います。
設定できたら、「Next」をクリックしましょう。

Kotlin Android OptionsMenu(オプションメニュー)を使ってみよう

ターゲットデバイスは今回は「Phone and Tablet」にチェックをします。

この画面ではターゲットOSのバージョンを決めるのですが、現状のシェア率を考慮したり、ご自分の端末に合わせるなど任意のバージョンを選択してください。
各OSがどの程度シェアがあるのかは、「Help me choose」から確認できるので、そちらも参考にしてみてください。

設定できたら「Next」で次に進みましょう。

Kotlin Android OptionsMenu(オプションメニュー)を使ってみよう

この画面ではプロジェクトのテンプレートを決めますが、ここが前回までと違うポイントです。
今回は「Basic Activity」を選択してください。

前回までは「Empty Activity」を選択していましたが、このテンプレートだとオプションメニューの設定が大変なので、もともと設定されている「Basic Activity」を使っていきましょう。

では、「Next」で進みましょう。

Kotlin Android OptionsMenu(オプションメニュー)を使ってみよう

この画面では作成されるActivityやLayoutの名前を決めることができますが、今回はこのままでOKでしょう。
「Finish」をクリックしましょう。

色々ごにょごにょとプロジェクトを作成してくれるので、しばしお待ちいただくと、プロジェクトが作成されると思います。

Android Studio 2.3をお使いの方は第1回の4. JavaをKotlinにしようまでを参考にしてプロジェクトの作成とKotlinの設定を行なってください。
Activityのテンプレートの作成はAndroid Studio3のときと同様に「Basic Activity」を選択してください。

3. 画面を作ろう

画面を作っていくのですが、今回はオプションメニューの操作だけに焦点を絞りたいので、画面上には何も表示させないようにしたいと思います。

では、レイアウトファイルを修正していきたいのですが、今回選んだBasic Activityはちょっと構成が変わっています。
layoutフォルダを見てみるとactivity_main.xmlcontent_main.xmlがあります。

ここでは詳しくは説明しませんが以前とActionBarの扱い方が変わっているからです。

content_main.xmlを編集しよう

まずは、content_main.xmlを開いてください。
TextViewが1つあると思いますが、今回は使わないので、削除してしまいましょう。

AndroidStudioのバージョンによってはDesignタブのプレビュー画面でエラーが出ていてる可能性があります。
その場合は「Component Tree」からTextViewを選択してdeleteキーで削除するか、
Textタブを選択して、xmlから<TextView .../>の記述を削除してください。

activity_main.xmlを編集しよう

次に、activity_main.xmlを開いてください。

Basic Activityを選択するとデフォルトでFloatingActionButtonが配置されています。
今回は使わないので削除しましょう。
この場合もプレビュー画面がエラー等が出ていて使えない場合はComponent TreeやTextタブから削除してください。

MainActivty.ktを編集しよう

activity_main.xmlからFloatingActionButtonを削除しましたが、MainActivity.ktにクリック時の処理が書かれているので、そこを削除しましょう。

onCreate()内の、以下のコードを削除してください。

FloatingActionButtonは最近のアプリでよく使われるので後々扱ってみたいと思います。

今回は画面についてはこれだけです。
オプションメニューに注力したいので、極力シンプルに…。

4. メニューを作ろう

さて、いよいよメニューを作ってみましょう!
といってもすでにできていたりもしますが…。

res/menuフォルダのなかに、menu_main.xmlというファイルがあるので開いてください。

オプションメニューはDesignで作っていくより、Textのほうが作りやすい気がするので、Textタブを開いてください。
そうすると、以下のようなソースになっていると思います。

ざっくり説明するとmenuタグがオプションメニューの大枠と思っていただいて、その中のitemタグがメニューの項目になります。

現状でエミュレータで確認してみると、右上にメニューアイコン(︙のアイコン)があって、

Kotlin Android OptionsMenu(オプションメニュー)を使ってみよう

クリックするとSettingsという項目があるはずです。

メニューを追加してみよう

では、メニューを追加してみたいのですが、その前にざっくりとitemのプロパティを説明しておきます。

android:id: 言わずもがなIDですね
android:orderInCategory: itemが複数のときの表示順を設定します
android:title: 表示される文字列ですね
app:showAsAction: 表示方法を指定します。複数指定可能。いろいろ設定値がありますがのちほど説明します。

ひとまず単純にメニューを増やしてみましょう。今あるitemをコピー&ペーストで次のように書いてみましょう。
(ハイライト部分が今回の追加箇所です)

上から、設定、追加、削除、保存といった項目になります。
android:orderInCategoryは上から順に1を足していった数値を書いておきます。
順番を変えたい場合はそれぞれ足したり引いたりしてお好きな順番にしてください。

android:titleは今はエラーになっていると思いますが、あとでstrings.xmlで設定していくのでとりあえずこのままでOKです。

app:showAsActionも今のところは初期設定のままにしておきましょう。

メニューも文字列を設定しよう

android:titleに設定する文字列を定義していきましょう。
もちろん直接書いてしまってもいいのですが、文字列はstrings.xmlに定義しておくことが推奨されているのでそれに従います。

res/values/strings.xmlを開いてください。

Settingsをコピー&ペーストして、action_addaction_deleteaction_saveを作成しましょう。
それぞれの設定値は以下のコードを参照してください。

これで、menu_main.xmlのエラーは消えていると思うので、確認してください。

もう一つstringを定義しておきたいと思います。ここではまだ使いませんがのちほど使うので…

メニューを表示しよう

メニューを表示してみましょう。と言っても、すでに表示されていますが…。

メニュー用のxmlファイルを作っても、もちろん自動で表示されるようになるわけではありません。
ソースから設定して上げる必要あります。

なので少し見ていきたいので、MainActivity.ktを開いてください。

onCreate()の下あたりに次のソースがあると思います。
(実際はコメントがたくさん書いてあるかもしれませんが、コメントは削除してもOKです)

onCreateOptionsMenu()というその名もズバリのメソッドが定義されています。
渡されてくるMenuに対して、menuInflater.inflate()を使って、レイアウトファイルを指定してあげればOKです。
Activityのときと同様ですね。
最後にreturn trueとするのはお忘れなく…(っていってもなにも返さなければエラーになりますがw)

では、ここまででエミュレータで確認してみましょう。

メニューアイコン(︙のアイコン)をクリックすると追加した項目も表示されるはずです。

Kotlin Android OptionsMenu(オプションメニュー)を使ってみよう

5. メニューを選択してみよう

無事にメニューが表示されるようになったので、次はメニューを選択してみましょう。

選択されたときの処理もMainActivity.ktに最初から書かれていたります。

onOptionsItemSelected()が選択されたときに呼ばれるメソッドです。

引数のitemに選択されたメニューの項目のオブジェクトが渡されるので、
whenでメニューのitemのIDを判定しています。
IDはmenu_main.xmlでつけてあげたIDですね。

ここでは該当するIDが会った場合はreturn trueとしていて、
該当するIDがなかった場合には親クラスを呼んで終了しています。

普通のアプリだったらメニューを選択したら違う画面に遷移したりすることが多いのですが、
今回はシンプルにToastを表示するだけにしておきます。
画面遷移する場合は普通にstartActivityをするだけなのでこちらの記事を参考にしてください♪

というわけで次のように書き換えてみましょう。

whenでIDを調べて分岐するのは先程と同じですが、ここではToastに表示するメッセージを返して、messageに代入しているだけです。
strings.xmlであとで使うので、と言って追加した文字列はここのelseのときのメッセージとして使っています。
(といっても、elseになることがそもそもないのですが…)

messageが作れたら、Toastを作って表示します。
最後はreturn trueとしてもいいと思いますが、一応親クラスを呼び出してその戻り値を返すようにしました。

ではここまでできたらエミュレータを起動して、動作を確認してみましょう。

メニューの項目を選んだときに該当のメッセージが表示されればOKです!

もう少し突っ込んだ使い方をしてみましょう。

最近はFloatingActionButtonが出てきて、少なくなってきた気もしますが、「︙」のメニュー以外にアイコンをActionBarに表示することも可能です。

その辺のやり方を見ていきましょう。とは言え簡単なのですが。

今回はAddのアイコンを「︙」の横に表示されるようにしてみます。
アイコンを使うにはandroid:icon属性を設定してあげます。今回はAndroidが標準で用意している@android:drawable/ic_menu_addというアイコンを使いましょう。

これだけだとアイコンが今までと同じように「︙」のなかにメニューが入るだけなので、ActionBarに表示されるように設定します。
そこで使うのがapp:showAsAction属性です。いままでneverと設定していた箇所ですね。

このshowAsAction属性は他にも種類があって、それらを使うことでアイコン表示できるようになります。
属性値は以下のようなものがあります。

属性値 意味
never 常に表示しない
ifRoom 表示する余裕があれば表示
always 常に表示
withText android:titleのテキストを表示

今まで使用していたneverは常に表示しない、なので、ActionBarには直接表示されていなかった、というわけです。
なので、Addアイコンを表示させるにはalwaysifRoomを使えばいいのですが、ifRoomが推奨されているようです。

これだけでもアイコンが表示されるのですが、ついでにwithText属性も追加してみましょう。(この属性は|を使用することで他の属性と同時に指定することが可能です。)
withText属性はスペースがあればandroid:titleの内容を表示してくれます。

というわけで変更したAddのitemは以下のようになります。

では、エミュレータで確認してみましょう。

Kotlin Android OptionsMenu(オプションメニュー)を使ってみよう

このように+マークのアイコンが表示されればOKです。

withText属性が効いているか確認するにはエミュレータを横向きにしてみましょう。

Kotlin Android OptionsMenu(オプションメニュー)を使ってみよう

そうするとアイコンの横に「ADD」とテキストが表示されるようになったかと思います。

7. メニューのアイテムを非表示、無効化してみよう

メニューのアイテムを状況に応じて非表示にしたり無効化したりすることもあると思うのでその辺もやってみましょう。

このような操作は動的に行うことが多いはずなので、プログラムから制御していくので、MainActivity.ktを開きましょう。

色々やり方はあると思いますが、オプションメニューが表示される前に呼ばれるonPrepareOptionsMenuというメソッドを使っていきましょう。

こんな感じになっています。Booleanを返す必要があるので、親クラスを呼んでそのままreturnすればいいでしょう。

アイテムを非表示にする

ではまずは非表示にする方法から見ていきましょう。
本来はここで何かしらの条件分岐をすることになると思いますますが、今回はやり方の紹介だけなのでいきなり非表示にします(笑)

たとえば、deleteメニューを非表示にしたい、という場合はmenuからアイテムを取得して、isVisibleプロパティをfalseにしてあげればOKです。

menuからアイテムを取得するにはmenu?.findItem(アイテムのID)で取得できます。
ちなみにmenuはnullable型で渡されるので、?を使って安全に処理をしてあげる必要があります。

次のように書いてあげればOKです。

アイテムを無効化する

では次に無効化にする方法を見ていきましょう。
こちらもはやり方の紹介だけなのでいきなり無効化します。

今度は、saveメニューを無効化したいとしましょう。
非表示のときの同じようにmenuからアイテムを取得して、isEnabledプロパティをfalseにしてあげればOKです。

次のように書いてあげればOKです。

これで実行するとdeleteメニューは表示されなくなり、saveメニューは無効化されて押せなくなるはずです。

Kotlin Android OptionsMenu(オプションメニュー)を使ってみよう

こうですね。deleteはなくなり、saveは薄く表示されていてクリックしても反応しないはずです。

といったわけでざっくりではありましたが、オプションメニューの使い方について見てみました。