コンテキスト
ところで、Androidでは「コンテキスト」という考え方がいろいろなところで登場することは、この連載中に紹介してきています。その際、「…Activity.this」とアクティビティオブジェクトを指定しました。
では、フラグメント中ではどのように記述すればいいのでしょうか。注意すべきは、フラグメントはコンテキストにはなりえないという点です(FragmentクラスはContextクラスを継承していないからです)。そこで、現在のフラグメントが所属しているアクティビティを取得して使います。これは、FragmentクラスのgetActivity()メソッドを使用します。この処理を追記してみましょう。
MenuListFragmentに以下のようにフィールドとonCreate()メソッドを追加しましょう。
public class MenuListFragment extends Fragment {
private Activity _parentActivity; // (1)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_parentActivity = getActivity(); // (2)
}
~省略~
}
コンテキストは頻繁に使用される可能性があるので、MenuListFragmentのフィールドとして定義します。それがリスト2の(1)です。そのフィールドの中身を用意しているのがリスト2の(2)です。この所属先Activityの取得処理をどのメソッドに記述するかですが、図5のフラグメントのライフサイクルから考えて、Activityの関連付けが終了したonAttach()以降のメソッドになりますが、一方でonCreateView()以降のメソッドはフラグメントの状態に応じて何度か呼び出される可能性があります。となると、onAttach()かonCreate()メソッドがよいでしょう。ここでは一般的な初期化処理に使われるonCreate()に記述します。
さて、ついでに、リストデータの生成処理をにonCreateView()に追記しましょう。リスト1の(2)と(3)の間に以下のソースコードを追加してください。といっても、IntentSampleとほぼ同じ内容なのでそのままコピーしてください。「~menuListデータ生成処理~」部分に関しても同様です。
ただし、1点だけ変更があります。それが(4)です。SimpleAdapterをnewするときの第1引数としてコンテキストを指定しますが、ここで、フィールドに設定した_parentActivityを使います。
public class MenuListFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_menu_list, container, false); // (1)
ListView lvMenu = (ListView) view.findViewById(R.id.lvMenu); // (2)
List<Map<String, String>> menuList = new ArrayList<Map<String, String>>();
~menuListデータ生成処理~
String[] from = {"name", "price"};
int[] to = {android.R.id.text1, android.R.id.text2};
SimpleAdapter adapter = new SimpleAdapter(_parentActivity, menuList, android.R.layout.simple_list_item_2, from, to); // (4)
lvMenu.setAdapter(adapter);
return view; // (3)
}
}
これで、フラグメント部分は一応完成です。
アクティビティへの埋め込み
といっても、このままでは画面は起動しません。起動はあくまでアクティビティ単位だからです。なので、アクティビティにフラグメントを組み込む必要があります。これは、レイアウトxmlに記述します。activity_menu_list.xmlを以下の内容に書き換えてください。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="@+id/fragmentMenuList"
android:name="com.websarva.wings.android.fragmentsample.MenuListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
入力できた段階で、一度アプリをスマホサイズのAVDで起動してみてください。IntentSampleと同じリスト画面が表示されるはずです。
フラグメントをアクティビティに組み込むには<fragment>タグを使用します。その際、android:name属性として、組み込むFragmentクラスの完全修飾名を指定します。これだけで、アクティビティにフラグメントが組み込まれます。
