【Android Studio】初心者用!ActivityやFragmentの基本まとめ
備忘録。情報は正確でない可能性がありますので特にご注意を。
Android StudioでFragmentを作ってみる
- 作成したいフォルダで右クリック→New→Fragment→Blank Fragment
- Fragmentのクラスやら、layout用のXMLの名前などを決める。
※比較用に別途List Fragmentと、New→Activity→Blank Activity with Fragment も作っておいたほうが後々無難
レイアウトから呼び出す
ここのXMLを参考に、とりあえずは組めばよろし。
Fragmentを使ってみる
android.view.InflateException: Binary XML file line #7: Error inflating class fragment
ItemFragmentは生成された時点でOnFragmentInteractionListenerというinterfaceが作られていて、Activityでこのinterfaceを実装しないと実装クラスとしてonAtachのときにActivityのインスタンスをキャストしているため例外で落ちてしまいます。
つまり、自動生成された***Fragment内にある、
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
をコメントアウトすればとりあえず処理落ちすることはなくなります。が、そもそも初心者がBlankをベースに作業するとややこしい。ListFragmentの自動生成コードが参考になるので別にサンプル用につくり、Blankと比較しながら直せれば早い。
で、これをコメントアウトせず、本来の用途に従ってActivityに実装するには。***Activity.javaを開いて、OnFragmentInteractionListenerを以下の様な形に実装してあげる。
public class ***Activity extends Activity
implements HeaderFragment.OnFragmentInteractionListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_****);
}
@Override
public void onFragmentInteraction(Uri uri) {
}
}
Javaに慣れていないと混乱しますが、onFragmentInteractionの引数が記事によっては(String id)のようなものになってます。ただ自分の環境でBlankで作成したときは(Uri uri)になっていたので、基本的な部分ですが間違わないようにしましょう。
あと、implementsというのは、「必ずコレ実装してね」っていう指示みたいなもの。interfaceで定義されたものに関しては、必ずつけてあげましょ。
そもそもActivityとFragmentって何?
includeでxmlの定義を使いまわすことは出来たけど、それだとコントローラのロジックを使いまわせない。そこで、UIとロジックをカプセル化してコンポーネントにしたのがFragment、ってことですかね。
ActivityはMVCでいうControllerの役割だけど、Controllerは極力小さくってのはWebフレームワークを学んだ今ならよくわかりますね。
ということは、FragmentはViewとControllerの仲立ちをするってことだから……ViewModelってことになるんだろうか?(もっとデザパタ勉強しよう……)
これが一番イメージわいた。
AndroidのFragmentとFragmentActivityの違いは何ですか?
AndroidでFragmentがサポートされたのは、Android 3.0(APIレベル11)以降です。APIレベル11以前のActivityクラスでは、Fragmentを操作するメソッドを使用することができません。それをカバーするために、Android Support Libraryというパッケージによって提供されているのがFragmentActivityです。Activityの代わりにFragmentActivityを用いることで、APIレベル11以前を対象にしたコードでも、Fragmentを操作するAPIを使用することができます。
ということで、理由が無い限りはFragmentActivityを使ったほうがいい気がする
Activity側でlayout_width=”wrap_content”してfragment側でmatch_parentした場合、Activity側の指定が優先されてしまう
fragment側の一番外側のLayoutは、Activity側の設定に上書きされてしまうようなので、innerとなるLayoutを用意すればOKかも
fragmentで画面遷移する
なぜかフラグメントでは直接インテントを生成する方法がなく、画面の遷移はアクティビティーで実装するというルールになっているので、いちいちフラグメントで紐付いているアクティビティーを取得した上で、画面遷移のイベントを発生させなきゃならないという、まどろっこしいことをしなければいけません。
Fragmentを利用して、画面遷移する世界一簡単なAndroidアプリを開発する [Android]いずれのパターンでも必ず一度だけ紐付けられるonAttach()が最も都合が良いわけですね。
FragmentのonAttach()はonCreate()より先に呼び出されるので、このタイミングはまだFragmentの状態は不完全であることに注意。リスナの登録のみ行うという認識であること。
FragmentとActivityの連携方法
ということなので要注意。
その他もろもろ
- XMLレイアウトで定義した(
で定義した)Fragment は FragmentTransaction の対象にしてはいけない - リスナーはActivityで定義する(メモリが足りなくなると再生成されるなど不具合が多い)
- まだ理解が浅いが、onCreateなどライフサイクルの中でActivityからFragmentに何かをsetするようなことは基本できず、Fragmentが呼ばれた時にActivityから何かをgetするような流れにしておくこと
http://y-anz-m.blogspot.jp/2012/06/fragment-activity.html