MenuThanksFragmentの改造
MenuListFragmentの改造が終了したところで、MenuThanksFragmentを改造していきます。考え方は、MenuListFragmentと同様です。画面サイズを判定するフラグを用意し、それに応じて分岐していきます。
画面判定
MenuListFragment同様、画面サイズ判定用フラグフィールドとして_isLayoutXLargeを用意し、その値を取得する処理を記述します。MenuThanksFragmentが使われる状況を考えると、10インチ画面の場合は、必ずリストフラグメントが同一アクティビティに存在します。しかも、MenuThanksFragmentが生成される時点ではすでにMenuListFragmentが存在します。一方、通常画面サイズの場合はMenuListFragmentは存在しません。この性質を利用し、onCreate()メソッドの段階で判定します。
以下のように、_isLayoutXLargeフィールドの追加とonCreate()メソッドへのソースコードの追加を行います。なお、(2)はすでに記述されているソースコードです。
public class MenuThanksFragment extends Fragment { private boolean _isLayoutXLarge = true; // (1) @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // (2) _parentActivity = getActivity(); // (2) FragmentManager manager = getFragmentManager(); // (3) MenuListFragment menuListFragment = (MenuListFragment) manager.findFragmentById(R.id.fragmentMenuList); // (4) if(menuListFragment == null) { // (5) _isLayoutXLarge = false; // (6) } } ~省略~ }
(1)は画面サイズ判定フラグフィールドです。
ポイントとなるのは、(4)です。(3)でFragmentManagerオブジェクトを取得していますが、このクラスのメソッドfindFragmentById()で同一アクティビティに属する他のフラグメントを取得できます。このメソッドを使って、MenuListFragmentを取得します。そして、取得したMenuListFragmentオブジェクトがnull、つまり、存在しない場合(リスト5の(5))は通常画面サイズとしてフラグをfalseにします(リスト5の(6))。
引き継ぎデータの取得
画面判定ができたところで、MenuListFragmentからの引継ぎデータの取得部分を画面サイズに応じた処理に改造していきましょう。これは、onCreateView()メソッド内の改造です。以下のようにソースコードを変更してください。なお、(1)と(6)は改造前から存在したソースコードです。
public class MenuThanksFragment extends Fragment { ~省略~ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_menu_thanks, container,false); // (1) String menuName = ""; String menuPrice = ""; if(_isLayoutXLarge) { // (2) Bundle extras = getArguments(); // (3) menuName = extras.getString("menuName"); //(4) menuPrice = extras.getString("menuPrice"); //(4) } else { // (5) Intent intent = _parentActivity.getIntent(); // (6) menuName = intent.getStringExtra("menuName"); // (6) menuPrice = intent.getStringExtra("menuPrice"); // (6) } TextView tvMenuName = (TextView) view.findViewById(R.id.tvMenuName); ~省略~ } ~省略~ }
ここでのポイントは(3)です。画面サイズ判定フラグの値で分岐しているのが(2)ですが、通常画面サイズの場合(リスト6の(5))はすでに記述されていますので、それをそのまま残します(リスト6の(6))。10インチ画面の場合は、Intent経由ではなく、フラグメントに直接渡されたBundleオブジェクトから取得します。これは、getArguments()メソッドを使います(リスト6の(3))。あとは、このBundleクラスのget○●()メソッドを使ってデータを取得します(リスト6の(4))。「○●」は取得するデータ型で変化します。引数は取得するデータのキーを指定します。
ボタンタップ処理
最後に「リストに戻る」ボタンをタップした時の処理も、以下のように画面サイズに応じての処理に変更しましょう。
public class MenuThanksFragment extends Fragment { ~省略~ public void onClick(View view) { if (_isLayoutXLarge) { // (1) FragmentManager manager = getFragmentManager(); // (2) FragmentTransaction transaction = manager.beginTransaction(); // (3) transaction.remove(MenuThanksFragment.this); // (4) transaction.commit(); // (5) } else { // (6) _parentActivity.finish(); // (7) } } } }
通常画面サイズの場合は、アクティビティを終了します。こちらのソースコードはすでに記述されていますので、それをelseブロックに入れます(リスト7の(6)と(7))。
一方、10インチ画面の場合(リスト7の(1))は、今表示されている注文完了フラグメント、つまり自分自身をmenuThanksFrameから削除します。フラグメントの追加削除ですので、FragmentManagerオブジェクトを取得し(リスト7の(2))、トランザクションを開始します(リスト7の(3))。フラグメントの削除はremove()メソッドですので、これを使い、引数として自分自身、つまり、MenuThanksFragmentに「.this」を付けて渡します(リスト7の(4))。最後にコミットします(リスト7の(5))。
これで、ひととおりのコーディングが終了しました。アプリを再起動して動作を確認してみてください。
できることなら、AVDを様々な画面サイズで用意し、動作を確認してみると面白いでしょう。
このように、フラグメントを利用すると、同一アプリで画面サイズに応じて最適な動作を実現することができます。
まとめ
前回と今回の2回にかけてフラグメントを紹介してきました。次回は非同期処理とクラウド連携を紹介します。