2015.05.28

【Android SDK】Fragmentをうまく使う

使い慣れると便利ですよ。

Fragmentの成り立ち

最近のAndroidアプリはActivityを継承して作っていくのではなく
FragmentActivityを継承したもので作成していくのが基本になっている。
デフォルトではFragmentActivityを継承したActionBarActivityで作られることが多い。
Link:FragmentActivity | Android Developers
Link:ActionBarActivity | Android Developers

Activityでいいじゃんと思うわけですけど、全てがActivityに集中して
他での利用が出来なかったりと不便なところが多い。

それを解決するためにViewを分離して各画面ごとに処理を作成することで
ソースが分散されて再利用も可能になってハッピーになったという流れらしい。

いわゆるMVCになったということなのでしょう。
Link:Java Solution FAQ:MVCモデルという言葉をよく聞きますが何のことですか?

Fragmentの使い方

・Fragmentを継承したレイアウトの作成

Fragmentの動作を確認するならこれくらいでよい。

package com.example.frageasy;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragTest extends Fragment {

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		
		return inflater.inflate(R.layout.frag, container, false);
	}

}

onCreateViewをオーバーライドして表示したいViewを返せばそれが表示されます。
今回は簡単にinflateでレイアウトファイルをロードしています。

・Activityで表示を切り替える

作成したフラグメントをメインビューへ変更します。

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	
	FragmentManager fm;
	FragmentTransaction ft;
	
	FragTest fTest;
	
	fTest = new FragTest();
	
	fm = getSupportFragmentManager();
	ft = fm.beginTransaction();
	ft.replace(R.id.a_frag, fTest );
	ft.commit();
	
}

手っ取り早くActivity.onCreateで差し替えます。

まず、今回作成したフラグメントをおもむろに作成。

次にActivityが持っているFragmentManagerを取得。
FragmentManager.beginTransactionで切り替え処理の開始を宣言。
FragmentTransaction.replaceで切り替えるViewのIDと切り替えたいフラグメントを指定。
FragmentTransaction.commitで変更終了を通知。

これだけでフラグメントの切り替えは完成です。
細かい処理は新規作成したFragmentに書いていくことが出来ます。

画面のスタック構造も簡単に実装可能

これだけだと単なる画面の分割だけなので便利そうな機能を紹介。

FragmentTransactionの処理中に以下のものを入れる。

ft.addToBackStack(null);

さらに、Activity.onBackPressedをオーバーライドして
以下のような処理を記述。

/**
 * 戻るキーをおした時
 */
@Override
public void onBackPressed()
{
	int backStackCnt = getSupportFragmentManager().getBackStackEntryCount();

	//まだスタックあり
	if (backStackCnt != 0)
	{
		//BackStackに乗っているFragmentを戻す
		getSupportFragmentManager().popBackStack(); 
	}
	else
	{
		//最後の画面まで戻ってきたらアプリ終了
		super.onBackPressed();
	}
}

これを実行してバックボタンを押すと
1つ前の画面に戻り、終わったらアプリが終了するという
画面のスタック機能があっさりと実装出来ます。

画面がスタックされるかはFragmentTransaction.addToBackStackを呼ぶからしいので
単なる画面切り替えであれば呼ばなければスタックされずに画面切り替えだけになる。

これだけの処理で画面のスタック機能ができるのは便利ですね。

注意事項

自分のハマった問題点をまとめておく。

・Fragmentのバージョンを注意すること
GoogleはFragmentへの移行を積極的に推進しているので
昔のバージョンへの対応もしている。
しかし、新しいライブラリとは別枠で作ってあるので
importを間違えたり違うバージョンでやり取りを行うとあっさりとハングします。

Fragmentだとこんな感じで分かれています。
・android.app.Fragment
Link:Fragment | Android Developers
・android.support.v4.app.Fragment
Link:Fragment | Android Developers

もっとわかりにくいのはFragmentManagerの取得方法です。
・getFragmentManager()
Link:Activity | Android Developers
・getSupportFragmentManager()
Link:FragmentActivity | Android Developers

基本的には古いバージョンでも対応ができているv4のついたほうで処理していくのがいいと思う。
だけど、今後はFragment自体にアニメーション機能とかも実装されていくみたいなので
問題ないのであればandroid.app.Fragmentをつかったほうがいいと思います。

・Fragmentのライフサイクルを理解しておくこと
FragmentのライフサイクルはActivityに似ていますが相当ピーキーな動きをします。

画面を切り替えながらonCreateViewとonDestroyViewの動きを見ていると
表示されるときにonCreateViewが呼び出されて非表示になるとonDestroyViewが呼び出されています。

なのでTextView内部に残っているテキストなどはどこかに退避しておき
再表示時に再度設定して表示しないといけない作りになっています。

外部から呼び出すイベントでTextView等を更新するときも非表示時には
View自体削除されているのでアクセスするとハングする。
こういう所も対処していかないといけない。


Fragmentをある程度理解するために相当な時間が取られてしまいました。
いかんせん作るのが面倒だけど利点も大きいので便利に使っていきたいところです。

[aws asin="477416335X"]

ニャッキ格闘列伝 > プログラム >

前の記事:
次の記事:

関連記事

コメントリスト

コメントなし

コメント



*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

こんなタグが使えるみたいよ:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>