FragmentはActivityと共に重要な機能を果たしていますが、いまいちわかりにくところがあります。最初に簡単なHello Worldを表示させるところから始めてみましょう。
2021.2.1
Fragment
AndroidではActivityは重要な機能を司っていますが、勢いなんでもかんでもActivityに機能を入れてしまって巨大なActivityが出来上がってしまいます。これではメンテナンスがやりにくいコードになってしまい、チームでの開発がより困難になります。
Fragmentは「断片」という意味ですが、ActivityのUI部分を肩代わりでき、いくつものFragmentをActivityから開いたり閉じたりできます。
また、複数のActivityから使いまわすような再利用も可能です。
Activityには以下の役割があります
- Viewの生成と制御
- リソースを取得したりするContextのタスク
- コンポーネントとしてIntentを受け取る
ActivityにはActivityにしか出来ない事を担わせて、View生成と制御の部分はFragmentに任せようということです。
タグ<fragment>
レイアウトに <fragment> タグを使ってHello Worldを表示させます。
ただしこの方法は静的なので拡張性があまりないのですが、Fragmentを理解するためにあえて簡単なところから始めます。
<androidx.fragment.app.FragmentContainerView .. />
MainActivityからsetContentViewで呼び出すレイアウトです。ボタンなどのViewと同じようにタグを設定します。
nameには パッケージ名 + Fragmentクラス名 を入れます。
この例ではパッケージ名:com.example.testfragment
Fragmentクラス名:SampleFragment
なので
com.example.testfragment.SampleFragment
(このままコピペしないように)
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 |
... <androidx.fragment.app.FragmentContainerView android:id="@+id/fragment" android:name="com.example.testfragment.SampleFragment" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> ... |
Fragment クラス: 次にFramentを継承したクラスを作成します。
SampleFragment.java
1 2 3 4 5 6 7 8 9 10 11 12 |
... public class SampleFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_main, container, false); } } |
onCeateView():
ActivityのようにFragmentにもライフサイクルがありViewを生成するタイミングで呼ばれるのが onCeateView() です。onCreateViewで渡される LayoutInfrater にFragmentのレイアウトをinflate(挿入)して返します。
Fragment のレイアウト:
レイアウトにTextViewを入れて定番のHello World(の代わりに”Hello Fragment”)の文字列をリソースから呼びます。
fragment_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?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:gravity="center" > <TextView android:text="@string/hello_fragment" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_height="wrap_content"/> </LinearLayout><strong style="background-color: #ffffff; font-family: 'Lucida Grande', 'Hiragino Kaku Gothic ProN', Meiryo, sans-serif; font-size: 16px;"> </strong> |
サンプルコード
以上をまとめて、分かりやすいように背景色を設定してみます。
SampleFragment.java
fragment_main.xml
を追加で作成
MainActivityは特に何も追加しません。
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//package your.package.name; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } } |
MainActivityで呼んでいるレイアウト
android:nameには パッケージ名 + Fragmentクラス名 を入れます
背景色とFragmentの範囲を300dp高くしてみます
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?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/fragment" android:name="com.example.testfragment.SampleFragment" android:layout_width="match_parent" android:layout_height="300dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="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 |
//package your.package.name; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.fragment.app.Fragment; public class SampleFragment extends Fragment { @Override public View onCreateView(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">YourAppName</string> <string name="hello_fragment">Hello Fragment</string> </resources> |
これで実行させてみるとこのようになります。
全体のMainActivityの画面の中にある、Hello Fragmentの背景がグレーの矩形範囲がFragmentになります。
関連ページ:
- Fragment をHello World から始める
- Fragment コードで記述する
- Activity と Fragment の画面遷移
- Fragment から別の Fragment に画面遷移させてみる
References:
androidx.fragment.app | Android Developers
フラグメント | Android Developers