ActivityとFragmentの連携を理解する【Android/Kotlin】



この記事はActivityとFragmentの連携の理解を深めるための忘備録である。

下図のように、2つの Fragment を1つの Activity で操作する実験を行ってみた。
できる限り最小限で簡単なサンプルプロジェクトにしたつもりだ。
以下プログラムの詳細を説明していく。








activity_main.xmlを用意する


まずFragmentを動的に追加するためのコンテナとして、空っぽの状態のレイアウトファイルを用意する。今回は1つだけしかActivityを使わないのでactivity_main.xmlを修正することにした。ConstraintLayoutidcontainerとしていることに注意しよう。







ActivityからFragmentを呼び出す


ActivityonCreateで最初に表示したいFragmentを設定するには次のようなコードを書くことになる。




ここではHogeFragmentクラスを用意することにした。HogeFragmentクラスの内容は次のとおりである。





HogeFragmentクラスでは、レイアウトファイルのonClick属性にメソッドを実装したかったのだが、実際にボタンを押すと次のようなエラーが出てしまった。

java.lang.IllegalStateException: Could not find method onButtonPressed(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'button'
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:424)
    


どうもHogeFragmentクラス内のメソッドを見つけてくれないようだ。仕方がないのでsetOnClickListenerでクラスに直接書き込むことにした。



このようにinflaterで生成したViewからfindViewByIdでボタンの参照を取得する。そしてsetOnClickListenerでボタンのクリックイベントを設定した。





Fragment内のViewにアクセスしたい


ところでFragment内のTextViewにアクセスしたい場合はどうすればよいだろうか?
最良の方法かどうかはわからないが、次のようにしてViewの参照を保持することで可能になった。考え方は先程のボタンイベントの設定のときと同じだ。




このTextViewを実装したのが次のFugaFragmentクラスである。







ActivityからFragmentへ値を渡す




このFugaFragmentにはcompanion objectというシングルトンの宣言がある。Android StudioFragmentを新規作成するときに、include fragment factory methods?にチェックを入れることでこのようにファクトリーメソッドが自動生成されるのだ。



ファクトリーメソッドを使ってActivityからFragmentを生成してみよう。

このようにファクトリーメソッドを使うことでFragmentActivityからパラメータを受けてることが出来る。





Fragmentの切り替えとバックスタックへ追加




FugeFragmentのボタンを押すとActivityonFugeFragmentAddFragment通知が届くようになっている。onFugeFragmentAddFragmentメソッドの中でFragmentFugaFragmentに切り替えてみることにしよう。次のように記述することでFragmentを切り替えることができる。




transaction.addToBackStack(null)の一行に注目しよう。この処理を書くことで、1つ前のHogeFragmentはバックスタックに積まれることになる。バックスタックに積んだことによって、FugaFragmentから1つ前のHogeFragmentへ戻ることが可能となるのだ。また端末の戻るボタンからも1つ前のFragmentへ戻ることができる。もしも戻ることを許可したくない場合にはaddToBackStackの一行を書かなければ良い。


ところでActivityFragmentのやり取りはインタフェースを介してやりとりしているが、ダイアログや[ネットワーク](https://www.101010.fun/entry/fragment-asynctask-networking)のサンプルでも説明してきたので今回は詳細は省略する。





1つ前のFragmentへ戻る




戻るときは簡単で、積んであるBackStackから(Popする)取り出せばよい。


BackStackからPopすると現在の表示されているFragmentonDetachが呼ばれ開放される。






まとめ


FragmentActivityのようなライフサイクルをもつ事ができるクラスだ。
Viewレイアウトをもつことも出来るが、[ネットワークサンプル](https://www.101010.fun/entry/fragment-asynctask-networking)で試したときのようにViewをまったく持たないFragmentも作ることが出来た。このことはFragment単位で様々な処理を分担できることを意味しており、つまりActivityからの制御を行いやすくすることができる。したがって重要な大まかな流れだけをActivityに書くことで、格段にメンテナンスがしやすくなるのだ。


今回のサンプルもまたGitHubへプッシュしておいたので参考に。
» AndroidExercise/TryFragment at master · araemon/AndroidExercise · GitHub

Kotlinプログラミング

Kotlinは、Javaとの相互運用を可能にし、Android OSでGoogleがフルサポートする静的型プログラミング言語です。この言語は、Javaだけでは十全ではない(Javaだけでは実装に手間がかかりすぎる)、軽量かつ豊かな表現形式や、他言語ではすでに実装されている最新の機能を盛り込んでいます。

KindleAmazon

基本からしっかり身につくAndroidアプリ開発入門

圧倒的な多数のユーザーが使っているヤフーのアプリ。その制作の最前線にいる黒帯エンジニアが、ユーザーが使いやすいアプリの大切な基本をしっかりと解説します。

KindleAmazon




参考


フラグメント (Android Developers/ドキュメント/ガイド)
Fragment上のonClickとかをFragment内で受け取る
Fragmentでのイベントハンドリング
FragmentのViewをいじってみる
[Android] アクティビティ内で動的にフラグメントを生成してレイアウトに追加する

あなたにおすすめ