フラグメント
Fragmentでモジュール化されたUIを構築します。フラグメントのライフサイクル、フラグメントでのViewBinding、引数の受け渡し、バックスタック管理、フラグメントとアクティビティ間の通信を学びます。
「フラグメント」はCoddyKit上の無料Android Academyレッスンです。 これはレッスン6/7です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAndroid Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Android Academyコースには全7レッスンが含まれています。
Fragmentとは
Fragmentは、Activity内で動作する再利用可能なUIモジュールです。独自のレイアウト、ライフサイクル、ロジックを持つサブActivityのようなものと考えてください。
Fragmentを使う理由:
- 複数のActivityでUIを再利用できる
- スマートフォンとタブレットで異なるレイアウトに対応できる
- 複数のActivityを使わずに複数画面のフローを構築できる
- Navigation Componentと自然に連携できる
Fragmentのライフサイクル
Fragmentには、Activityのライフサイクルとともに実行される独自のライフサイクルがあります。主なcallback:
onAttach— FragmentがActivityにアタッチされますonCreate— Fragmentが作成されます(まだViewはありません)onCreateView— レイアウトをinflateしますonViewCreated— Viewの準備が完了します。ここでUIを設定しますonDestroyView— Viewが破棄されます(Viewへの参照を解放します)onDetach— Fragmentがデタッチされます
Fragmentを作成する
Fragmentを継承するクラスを作成し、onCreateViewをoverrideしてレイアウトをinflateします。
import androidx.fragment.app.Fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
class HomeFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_home, container, false)
}
}FragmentでViewBindingを使う
FragmentでViewBindingを使用します。ただし、メモリリークを防ぐため、onDestroyViewでbindingを解放してください。
class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.tvTitle.text = "Welcome!"
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null // prevent memory leak
}
}FragmentのレイアウトXML
Activityのレイアウトと同じように、res/layout/fragment_home.xmlを作成します。ルートViewがFragmentのViewになります。
<!-- res/layout/fragment_home.xml -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:text="Home" />
</LinearLayout>ActivityにFragmentを追加する
ActivityにFragmentを追加する方法は2つあります。
- 静的(XML) —
<fragment>タグを使ってレイアウトに宣言します。実行時には固定されます。 - 動的(コード) —
FragmentManagerとトランザクションを使用します。実行時に入れ替えられます。
<!-- Static: in activity_main.xml -->
<fragment
android:id="@+id/homeFragment"
android:name="com.example.HomeFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />動的なFragmentトランザクション
supportFragmentManagerを使って、実行時にFragmentを追加、置換、削除します。
// In Activity:
class MainActivity : AppCompatActivity(R.layout.activity_main) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.add(R.id.fragmentContainer, HomeFragment())
.commit()
}
}
fun showDetail(id: Int) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragmentContainer, DetailFragment.newInstance(id))
.addToBackStack(null) // allow back navigation
.commit()
}
}Fragmentに引数を渡す
companion objectのファクトリパターンを使い、Bundle経由でデータを渡します。パラメーター付きのFragmentコンストラクターは決して使用しないでください。構成変更後、Androidは引数なしのコンストラクターでFragmentを再作成するためです。
class DetailFragment : Fragment() {
companion object {
private const val ARG_ID = "item_id"
fun newInstance(itemId: Int): DetailFragment {
return DetailFragment().apply {
arguments = Bundle().apply {
putInt(ARG_ID, itemId)
}
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val itemId = requireArguments().getInt(ARG_ID)
// use itemId to load data
}
}FragmentからActivityへの通信
Fragmentで定義したinterfaceをActivityで実装します。FragmentはonAttachで参照を取得します。
class ListFragment : Fragment() {
interface OnItemSelected {
fun onItemSelected(id: Int)
}
private var listener: OnItemSelected? = null
override fun onAttach(context: Context) {
super.onAttach(context)
listener = context as? OnItemSelected
}
private fun handleClick(id: Int) {
listener?.onItemSelected(id)
}
override fun onDetach() {
super.onDetach()
listener = null
}
}バックスタック
トランザクションでaddToBackStack(null)を呼び出すと、Backを押したときにスタックからFragmentが取り出されます。
addToBackStackなし — BackでActivityを終了しますaddToBackStackあり — 前のFragmentに戻りますpopBackStack()をプログラムから使用して戻ることもできます
コンテナ内のFragment
Activityのレイアウトには、通常はIDを持つFrameLayoutなどのコンテナViewが必要です。Fragmentがそのコンテナを埋めます。
<!-- activity_main.xml -->
<FrameLayout
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />クイックチェック
Fragmentにコンストラクター引数を渡さず、companion factory経由でBundleを使用すべきなのはなぜですか?
復習:Fragment
Fragmentは、現代的なAndroid UIを構築する基本要素です。
Fragmentを継承し、onCreateViewでレイアウトをinflateするonViewCreatedでUIを設定するonDestroyViewでViewBindingを解放するBundleとcompanion factory(newInstance)でデータを渡す- 戻るナビゲーションには
addToBackStackを使用する - interfaceを使ってActivityと通信する
次は、実行時に危険な権限をリクエストします。
よくある質問
「フラグメント」レッスンは無料ですか?
はい。「フラグメント」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Android Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Android Academyコースには全7レッスンが含まれています。
「フラグメント」で何を学びますか?
Fragmentでモジュール化されたUIを構築します。フラグメントのライフサイクル、フラグメントでのViewBinding、引数の受け渡し、バックスタック管理、フラグメントとアクティビティ間の通信を学びます。 ブラウザで直接実行するハンズオンコードでAndroid Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Android Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAndroid Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン6/7です。
「フラグメント」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAndroid Academyレッスンでコードを書いて実行できますか?
はい。すべてのAndroid Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。