【Android】Fragmentを使う② - ActivityとFragmentの相互呼び出し -

前回 の記事でFragmentの簡単な実装について書きました。今回はそれの応用編です。

Fragmentに定義したメソッドをActvity側から呼び出したり、FragmentからAcitivityのメソッドを呼び出す方法をまとめます。

ActivityからFragmentのメソッドを実行する

まずは親レイアウトであるMainActivity側から、それぞれのFragmentに定義してあるメソッドを実行してみます。この場合Fragment側に特別な処理は必要なく、呼び出し元のMainActivityのみで完結します。

メインのレイアウトにボタンを追加する

activity_main.xml

<LinearLayout
    android:id="@+id/llButton"
    android:gravity="center_horizontal"
    android:orientation="horizontal"
    android:layout_below="@id/mainText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <Button
        android:id="@+id/buttonTest1"
        android:text=" Fragment 1 -> TEST "
        android:padding="5dp"
        android:layout_margin="5dp"
        android:textAllCaps="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/buttonTest2"
        android:text=" Fragment 2 -> TEST "
        android:padding="5dp"
        android:layout_margin="5dp"
        android:textAllCaps="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

MainActivityでの処理

MainActivity.java

次にActivity側では、getSupportFragmentManager().findFragmentById()メソッドにFragmentのレイアウトを指定してFragmentオブジェクトを取得します。

あとは取得したFragmentオブジェクトを対象クラスでCastし、目的のメソッドを実行します。

findViewById(R.id.buttonTest1).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment1);
        if (fragment != null && fragment instanceof Main1Fragment) {
            ((Main1Fragment) fragment).buttonTest();
        }
    }
});

findViewById(R.id.buttonTest2).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment2);
        if (fragment != null && fragment instanceof Main2Fragment) {
            ((Main2Fragment) fragment).buttonTest();
        }
    }
});

実行結果

ちょっと分かりにくいですが、実行結果でlayout_mainに設置されたボタンからFragmentのメソッドが実行されています。


修正したソースコードは以下になります。

https://github.com/s-watanabe-apps/android-fragmenttest/tree/develop/20180902

FragmentからActivityのメソッドを実行する

今度は逆にFragmentからActivityのメソッドを実行してみます。

これに関してはFragmentで使用する共通メソッドをMainActivityに定義しておき呼び出し、などといった対応が可能になります。

MainActivityに呼び出し用の共通メソッドを定義

MainActivity.java

MainActivityに単純なメソッドを一つ追加します。

public void mainMethod(String className) {
    Toast.makeText(this, className + " -> mainMthod!", Toast.LENGTH_SHORT).show();
}

Fragmentレイアウトにボタンを追加

fragment_main1.xml

Fragmentのレイアウトには、MainActivityに定義した共通メソッドを呼び出すボタンを一つ追加します。

<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <Button
        android:id="@+id/buttonTest"
        android:text="TEST"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/buttonCallMainMethod"
        android:text="MAIN"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

Fragmentでの処理

Fragmentクラスで buttonCallMainMethod が押されたときの処理を追加します。

getActivity() メソッドで自分が所属している Activity のインスタンスが取得できます。

あとはこれを使って呼び出すだけで、Activityのメソッドを呼び出すことができます。

Main{n}Fragment.java

@Click
void buttonCallMainMethod() {
    MainActivity activity = (MainActivity) getActivity();
    activity.mainMethod(getClass().getSimpleName());
}

実行結果

これもだいぶ分かりにくいですが、Fragmentに設置したボタンからMainActivityの共通メソッドを呼び出しています。


これらをうまく利用すれば、Fragment間のデータのやり取りなんかもできます。

ただしそれをしてしまうと、せっかくFragmentを使用して疎結合化しているのに密結合になってしまうためあまりよろしくないかもしれません。

修正したソースコードは以下になります。

https://github.com/s-watanabe-apps/android-fragmenttest/tree/develop/20180905

コメント

このブログの人気の投稿

docker-compose up で proxyconnect tcp: dial tcp: lookup proxy.example.com: no such host

docker-compose で起動したweb、MySQLに接続できない事象

【PHP】PHP_CodeSnifferを使う(コーディングルールのカスタマイズ)