概要
2つのFragmentで間で遷移するアプリの雛形をまとめる。
仕様
- 2つのFragmentは、それぞれ、MainFragmentとSecondFragmentとする。
- MainFragment上にボタンがあり、それを押すと SecondFragmentに遷移する。
- SecondFragmentは何も表示しない。
- SecondFragmentで戻るボタンを押すと、MainFragment に遷移する。
- MainFragmentで戻るボタンを押しても、なにも遷移しない。
ファイル生成
プロジェクト生成
Android Studioで以下の必要なファイルを生成する。 Projectの雛形で、Fragment+ViewModelを使ふが、ViewModeならではのことは、ここでは何もしない。生成されるViewModelのファイルも無視する。
Prjoject雛形 Fragment + ViewModel
Name: InterFragmentTransition
Language: Kotlin
Use androidx.* artifacts: チェック
必要なファイル
| ファイル | 説明 |
|---|---|
| main_activity.xml | 自動生成される。編集不要。Fragmentの入れ物となる id=@+id/containerを定義し提供。 |
| MainActivity.kt | 自動生成される。編集必要。containerにFragmentを吹き込み(inflate)し、その後、Fragmentをreplaceする。 |
| main_fragment.xml | 自動生成される。編集必要。遷移用のボタンを配置する。 |
| MainFragment.kt | 自動生成される。編集必要。ボタン押下のイベントリスナーと、ボタン押下イベント処理の interfaceを追加する。 |
| second_fragment.xml | SecondFragmentを新規作成すると一緒に作成される。編集不要。 |
| SecondFragment.kt | 自分で生成する。編集不要。 |
Fragment ファイル生成
- Android ⇢ app ⇢ java ⇢ com.example.xxxxx で右クリック
- New ⇢ Fragment ⇢ Fragment(BLANK)を選択
- ダイアローグで以下を設定
- Fragment Name: SecondFragment
- Create lyaout XML? : チェックつける
- Fragment Layout Name: fragment_second
- include fragment factory methods? : チェックはずす
- include interface callback? : チェックはずす
- 言語はKotlin
以上までで必要なファイルはすべてそろふ。
ファイル編集
レイアウトファイル main_fragment.xml
Designモードでボタンを配置するのみ。layoutのidはmain、ボタンのidはここではbuttonMainとする。
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.MainFragment">
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="MainFragment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/buttonMain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="To Second Fragment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/message"
app:layout_constraintVertical_bias="0.483" />
</androidx.constraintlayout.widget.ConstraintLayout>
コード ファイル MainFragment.kt
追加コードは、ボタン押下のイベントリスナーと、ボタン押下の interfaceの定義だけ。
class MainFragment : Fragment() {
companion object {
fun newInstance() = MainFragment()
}
private lateinit var viewModel: MainViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val view = inflater.inflate(R.layout.main_fragment, container, false)
val button = view.findViewById<Button>(R.id.buttonMain)
button.setOnClickListener {
val listener = context as? OnButtonClickListener
listener?.onButtonClicked()
}
return view
}
interface OnButtonClickListener {
fun onButtonClicked()
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
// TODO: Use the ViewModel
}
}
- 13行目〜19行目:編集部分。イベントリスナーの設定。
- 22行目〜24行目:追加部分。イベント用 interface の定義。
コードファイル MainActivity.kt
MainActivity.ktは以下のやうになる。
class MainActivity : AppCompatActivity(), MainFragment.OnButtonClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance(), "tagMain")
.commitNow()
}
}
override fun onButtonClicked() {
val secondFragment = SecondFragment()
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.container, secondFragment, "tagSecond")
transaction.addToBackStack(null)
transaction.commit()
}
override fun onBackPressed() {
val fragment = supportFragmentManager.findFragmentByTag("tagMain")
if (fragment != null && fragment.isVisible()) {
// just ignore the Back Button Press
} else {
super.onBackPressed()
}
}
}
- 1行目:MainFragmentの中の interfaceを派生。
- 8行目:replaceの引数として MainFragmentのタグ名を設定
- 13〜19行目:interfaceの実装。ボタン押下のイベント処理本体。MainからSecondへの遷移をBackStackへ追加。
- 21〜28行目:MainFragmentの場合は戻るボタンを無視する、の処理を追加。
(了)
0 件のコメント:
コメントを投稿