CodeZine(コードジン)

特集ページ一覧

イベントリスナーの追加とMapFragmentのカスタマイズ

Web APIで楽々Androidアプリ(7)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2014/01/16 14:00
目次

MapFragmentをカスタマイズする

 Google Mapを表示するクラスは、Fragmentで提供されています。今度は、このFragmentを利用して、タブレットとスマートフォンで画面構成を変えてみましょう。

 ここまでは、あまりFragmentを意識せずに、従来どおりActivityにすべてを実装する形にしていました。画面の構成が1画面であれば、これでも構わないのですが、複数のFragmentを利用する場合では、UIの処理をFragment自身に実装するほうがすっきりするでしょう。

 そこで今回は、まず地図のUI処理を、MapFragmentを継承した独自のFragmentクラスに移してみることにします。

Fragmentのライフサイクル

 具体的なコードを紹介する前に、Fragmentのライフサイクルについて、ざっと説明しておきましょう。

 通常では、ActivityとFragmentのライフサイクルは次のような関係になっています。

ActivityとFragmentのライフサイクル
ActivityとFragmentのライフサイクル

 Fragmentは、単独で存在することはできません。必ず紐付いているActivityが必要です。そのActivityのライフサイクルに応じた、Fragmentのライフサイクルがあります。

 Fragmentでは、Activityよりも多くのコールバックメソッドがあります。次の表に、Fragmentだけにあるメソッドのうち、主なものをあげてみました。

Fragmentの主要コールバックメソッド
メソッド名 タイミングなど
onAttach() Activityに紐付けられたときに(一度だけ)呼ばれる
onCreateView() View階層に関連付けられるときに呼ばれる。表示するViewを返す
onActivityCreated() 紐付いているActivityのonCreate()が呼ばれた直後に呼ばれる
onDetach() Activityとの紐付けが解除されたときに呼ばれる

 onCreateメソッドは、Fragment自身の初期化時に呼ばれるメソッドです。従来ActivityのonCreateメソッドで記述していた処理は、onActivityCreatedメソッドに記述するようにします。

MyMapFragmentクラス

 最初に、MapFragmentを継承したMyMapFragmentクラスを作成します。このクラスには、もとのActivityから、LoaderCallbacksインターフェースを実装したメソッド以外、すべてを移します。

MyMapFragment.javaの一部
public class MyMapFragment extends MapFragment {

    ~中略~

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ekiMarkerMap = new HashMap<Marker, EkiInfo>();
        setRetainInstance(true); // フラグメントを保存する
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        try {
            // マップオブジェクトを取得する
            googleMap = getMap();

            // 初期設定がまだなら(1)
            if (centerPosition == null) {
                mapInit();
            }

            // 地図の中心位置を取得する
            centerPosition = googleMap.getCameraPosition();

            // 最寄り駅情報を取得する
            execMoyori(centerPosition);

            // 地図を移動したときのリスナー
            googleMap.setOnCameraChangeListener(new OnCameraChangeListener() {
                ~中略~
            });

            googleMap.setOnInfoWindowClickListener(
                ~中略~
            );
        }
        // GoogleMapが使用できないとき
        catch (Exception e) {
        }
    }
    ~後略~

 前述のとおり、onCreateメソッドのみに記述していた処理を、MyMapFragmentでは、onCreateメソッドとonActivityCreatedメソッドに分けています。

 なお、FragmentをsetRetainInstanceメソッドで保存するように設定した場合、ライフサイクルに注意が必要です。Fragmentを保存していると、Activityの状態にかかわらず、インスタンスが破棄されなくなります。端末を回転させた場合でも破棄されないため、onCreateメソッドは、起動時の一度きりしか呼ばれません(onDestroyメソッドも同様に呼ばれない)。ただしそれ以外のメソッドは、Activityの状態に応じてコールバックされます。

 また、Fragmentを保存していると、onActivityCreatedの引数savedInstanceStateも、常にNULLになります。このサンプルでは、Fragmentがすでに生成されているかどうかを、フィールドのcenterPositionの値で判断するようにしています(1)

Loaderの処理

 Loaderは、Fragmentでも利用することができます。

MyMapFragment.javaの一部
public void execMoyori(CameraPosition centerPosition) {
    ~中略~
    // LoaderManagerの初期化(1)
    getLoaderManager().restartLoader(0, bundle, (MainActivity)getActivity());
}

 今回は、LoaderのコールバックのみをActivityに実装し、restartLoaderメソッドの第3引数を、Activityに変更します(1)

最後に

 今回は、Google Mapsのイベントリスナー処理と、MapFragmentをカスタマイズする方法を解説しました。次回は、最寄り駅の一覧を表示するFragmentを追加して、タブレットとスマートフォンで異なる画面構成にしてみましょう。



  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:Web APIで楽々Androidアプリ

もっと読む

著者プロフィール

  • WINGSプロジェクト 高江 賢(タカエ ケン)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5