FragmentはActivityと共に重要な機能を果たしていますが、いまいちわかりにくところがあります。最初に簡単なHello WorldをJavaコードで記述して表示させるところから始めてみましょう。
2021.2.1
Fragment
前回はタグ<fragment>を使って簡単にHello Worldを表示させました。
この場合使いにくい場合があるのでMainActivityからダイナミックにFragmentを追加、削除ができるようにコードを使って記述してみます。
FragmentManager
Activityが呼び出すレイアウト、Fragmentとして、androidx.fragment.app.FragmentContainerViewを使います。
activity_main.xmml
1 2 3 4 5 6 7 8 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout ... > <androidx.fragment.app.FragmentContainerView ... /> </androidx.constraintlayout.widget.ConstraintLayout> |
次に、ActvityにFragmentを設定していきます。Fragmentの設定には一連のオペレーションであるトランザクション(フラグメントの追加、削除、置換など)を施します。
-
- FragmentManagerのインスタンス生成
- FragmentTransactionのインスタンスを取得
- インスタンスに対して張り付け方を指定する
- commit()で張り付けを実行する
コードではこのようにします。
1 2 3 4 5 6 7 8 9 10 11 |
// FragmentManagerのインスタンス生成 FragmentManager fragmentManager = getSupportFragmentManager(); // FragmentTransactionのインスタンスを取得 FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); // インスタンスに対して張り付け方を指定する fragmentTransaction.replace(R.id.container, new SampleFragment()); // 張り付けを実行 fragmentTransaction.commit(); |
savedInstanceState == null
最初に、BundleのsavedInstanceStateがnull、何もないときだけ設定をするようにします。FragmentはActivityのライフサイクル中に何度でも呼ばれることが可能なので最初だけ設定をするようにします。
1 2 3 |
if(savedInstanceState == null){ ... } |
FragmentManager:
以前は android.support.v4.app.FragmentManager や android.app.FragmentManager がありましたがAndroidXからは
androidx.fragment.app.FragmentManager
になります。
FragmentManagerは生成されたFragmentのインスタンスの状況を管理して、再度呼ばれると復元してくれます。
getSupportFragmentManager()からこのインスタンスを生成できます。
FragmentTransaction:
追加、削除、置換などのメソッドが用意されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
add(int containerViewId, Fragment fragment) add(int containerViewId, Fragment fragment, String tag) remove(Fragment fragment) // 置き換え、remove()してadd()すること replace(int containerViewId, Fragment fragment) replace(int containerViewId, Fragment fragment, String tag) // Fragmentを非表示にする hide(Fragment fragment) // hideされたものを表示させる show(Fragment fragment) // UIからは外れるがFragmentMangerでactiveな状態として管理されている detach(Fragment fragment) // detachされたものをattachする attach(Fragment fragment) |
Ref: FragmentTransaction
Fragmentのレイアウトとクラスは前回と同様です。
https://akira-watson.com/android/fragment-simple.html
サンプルコード
以上をまとめて、分かりやすいように背景色を設定してみます。
SampleFragment.java
fragment_main.xml
を追加で作成
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
//package your.package.name import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(savedInstanceState == null){ // FragmentManagerのインスタンス生成 FragmentManager fragmentManager = getSupportFragmentManager(); // FragmentTransactionのインスタンスを取得 FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); // インスタンスに対して張り付け方を指定する fragmentTransaction.replace(R.id.container, new SampleFragment()); // 張り付けを実行 fragmentTransaction.commit(); } } } |
MainActivityで呼んでいるレイアウト
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?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" android:padding="20dp" android:background="#dfe" tools:context=".MainActivity"> <androidx.fragment.app.FragmentContainerView android:id="@+id/container" android:layout_width="match_parent" android:layout_height="300dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
Fragmentのクラスです。
SampleFragment.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
//package your.package.name import androidx.fragment.app.Fragment; import androidx.annotation.NonNull; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class SampleFragment extends Fragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_main, container, false); } } |
Fragmentが呼んでいるレイアウト
fragment_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#bdc" android:orientation="vertical" android:gravity="center" > <TextView android:text="@string/hello_fragment" android:layout_width="wrap_content" android:textSize="40sp" android:textColor="#063" android:layout_height="wrap_content"/> </LinearLayout> |
リソース
strings.xml
1 2 3 4 |
<resources> <string name="app_name">Your App Name</string> <string name="hello_fragment">Hello Fragment</string> </resources> |
これで実行させてみるとこのようになります。
関連ページ:
- Fragment をHello World から始める
- Fragment コードで記述する
- Activity と Fragment の画面遷移
- Fragment から別の Fragment に画面遷移させてみる
References:
androidx.fragment.app | Android Developers
FragmentTransaction
フラグメント | Android Developers