一番簡単なFragmentの実装方法 生成と切り替え【Android】


前書き Fragmentとは


FragmentとはAndroidアプリ画面の断片を担当している、ビューです。

Activityのようにライフサイクルを持っています。

Activityについて詳しくは かんたんにわかるActivityの基礎 をご覧ください。

現在のAndroidアプリのほとんどが、Framgentを使ってUIを実装しています。

この記事では、

・ActivityからFragmentの生成

・FragmentからFragmentの切り替え

以上2点について、とてもシンプルなサンプルコードを使って解説していきます。

画面の生成、遷移以外の機能は最低限に絞っています。

Fragment を理解するための一番シンプルな実装となっています。


1.ActivityからFragmentの生成


1-1. ActivityとFragment のレイアウトxmlファイルの準備


MainActivity.javaではFragment を生成するだけなので、

Fragment を画面いっぱいに表示するための枠だけRelativeLayoutにて用意しておきます。


MainActivity.javaのレイアウト activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <RelativeLayout
        android:id="@+id/fragment_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_marginBottom="10dp"
        android:layout_marginRight="10dp"
        android:orientation="horizontal">

    </RelativeLayout>

</androidx.constraintlayout.widget.ConstraintLayout>


一つ目のFragment、FirstFragmentでは、

「テキスト」と二つ目のFragmentに遷移するための「ボタン」だけを用意しておきます。


一つ目のFragment.javaのレイアウト first_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <TextView
        android:id="@+id/first_fragment_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="@font/armata"
        android:text="Welcome to First Fragment!"
        android:textColor="#001D74"
        android:textSize="20sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.495"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.425" />

    <Button
        android:id="@+id/to_second_fragment_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:backgroundTint="#00BCD4"
        android:text="To Second Fragment"
        android:textColor="#FFFFFF"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.512"
        tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>


1-2.ActivityとFragmentのJavaファイルの準備


実際にFragment生成のロジックを担う、MainActivity.javaと

画面表示のロジックを担う、FirstFragment.javaのコードを記載します。


MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FirstFragment firstFragment = new FirstFragment();
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.add(R.id.fragment_container, firstFragment);
        transaction.commit();
    }
}


FirstFragment.java

public class FirstFragment extends Fragment {

    private static final String TAG = "FirstFragment";

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.first_fragment, container, false);
        return view;
    }
}


1-3.ActivityからFrgment生成コードの説明


MainActivity.javaより抜粋

FirstFragment firstFragment = new FirstFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.fragment_container, firstFragment);
transaction.commit();

FirstFragmentのインスタンス化。

Fragmentを生成するためのFragmentTransactionの準備。

add()でFirstFragmentの追加。

add()の第一引数には、Fragmentの表示を行う場所のid、第二引数は表示したいFragmentを指定します。

commit()で画面へ反映を行っています。

これにより、FirstFragment.javaのonCreateView()がスタートします。


FirstFragment.javaより抜粋

View view = inflater.inflate(R.layout.first_fragment, container, false);
return view;

LayoutInflatorにより、first_fragment.xmlのレイアウトを使えるようにしています。

onCreateView()はViewを返す必要があるので、inflateしたレイアウトをreturnします。

実行すると以下のような画面が表示されます。


2.FragmentからFragmentへの切り替え


2-1. 二つ目のFragment のレイアウトxmlファイルの準備

二つ目のFragment、SecondFragmentでは、

「テキスト」「画像」と、
一つ目のFragmentに遷移するための「Backボタン」だけを用意しておきます。


二つ目のFragment.javaのレイアウト second_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:id="@+id/textView"
        android:layout_width="340dp"
        android:layout_height="39dp"
        android:layout_centerInParent="true"
        android:fontFamily="@font/armata"
        android:text="Welcome to Second Fragment"
        android:textAlignment="center"
        android:textColor="#001D74"
        android:textSize="20sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.492"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.245" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="370dp"
        android:layout_marginTop="188dp"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/welcome_fragment"
        tools:layout_editor_absoluteX="0dp" />

    <Button
        android:id="@+id/back_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:backgroundTint="#00BCD4"
        android:text="Back"
        android:textColor="#FFFFFF"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.843"
        tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>


2-2.画面遷移のためにJavaファイルの準備


画面表示のロジックを担う、SecondFragment.javaのコードを記載します。


SecondFragment.java

public class SecondFragment extends Fragment {

    private static final String TAG = "SecondFragment";

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.second_fragment, container, false);
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button backButton = view.findViewById(R.id.back_button);
        backButton.setOnClickListener(clickView -> {
            Log.d(TAG, "BackButton pressed!");
            getFragmentManager().popBackStack();
        });
    }
}


一つ目のFragmentのボタンが押下された時に2つ目のFragmentに遷移したいため、

FirstFragment.javaファイルにボタンが押下されたときの処理を追記します。


FirstFragment.java

public class FirstFragment extends Fragment {

    private static final String TAG = "FirstFragment";

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.first_fragment, container, false);
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button toSecondButton = view.findViewById(R.id.to_second_fragment_button);
        toSecondButton.setOnClickListener(clickView -> {
            Log.d(TAG, "toSecondButton pressed!");
            SecondFragment secondFragment = new SecondFragment();
            FragmentTransaction transaction = getFragmentManager().beginTransaction();
            transaction.addToBackStack(null);
            transaction.replace(R.id.fragment_container, secondFragment);
            transaction.commit();
        });
    }
}


2-3.FragmentからFrgmentへ画面切り替えコードの説明


FirstFragment.javaより抜粋

Button toSecondButton = view.findViewById(R.id.to_second_fragment_button);
toSecondButton.setOnClickListener(clickView -> {
    Log.d(TAG, "toSecondButton pressed!");
       SecondFragment secondFragment = new SecondFragment();
       FragmentTransaction transaction = getFragmentManager().beginTransaction();
       transaction.addToBackStack(null);
       transaction.replace(R.id.fragment_container, secondFragment);
       transaction.commit();
});

Buttonとレイアウトをidによりリンクさせ、ボタンが押されたときの処理を、ラムダ式で記載しています。

ラムダ式によるonClick()の実装はこちら

ボタン押下を検知して、二つの目のFragmentであるSecondFragmentを生成しています。

transaction.addToBackStack(null);

今表示しているFragment(今回の例だとFirstFragment)を、Fragmentスタックに追加します。

遷移先のFragmentでBackボタンが押下された時に表示したい場合に使います。

引数には、表示したいFragmentが複数ない場合はnullを指定します。

transaction.replace(R.id.fragment_container, secondFragment);

add()は追加でしたが、replace()は

今あるFragmentを取り除いて、引数内のFragmentを新たに追加する

といった意味があります。


SecondFragment.javaより抜粋

backButton.setOnClickListener(clickView -> {
    Log.d(TAG, "BackButton pressed!");
       getFragmentManager().popBackStack();
});

SecondFragmentでは、Backボタンが押下された時にFragmentを非表示にする処理を実装しています。

getFragmentManager().popBackStack();

Fragmentスタックから現在表示しているFragmentを取り除くことになり、画面遷移が実現します。

Activityのfinish()処理と同じです。

実行すると以下のようになります。


まとめ

以上がFragmentの生成と遷移に関する非常にシンプルな実装でした。

FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.addToBackStack(null);
transaction.replace(R.id.fragment_container, secondFragment);
transaction.commit();

このようなソースコードはFragmentを実装する際には頻出するコードとなります。

それぞれどのような役割を持っているか理解して使えるようになりましょう!

ご精読ありがとうございました!!

一番簡単なFragmentの実装方法 生成と切り替え【Android】」への3件のフィードバック

  1. ピンバック: 【EditText】Androidでの入力受付方法 シンプルな実装例付き | Memento Mori Blog

  2. ピンバック: KotlinでのFragment実装方法 生成と切り替え | Memento Mori Blog

  3. ピンバック: INVISIBLEとGONEはどう違う?】viewの可視状態 | Memento Mori Blog

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です