Fragmentでやりたいことを整理して実験してみます。まず、やりたいことは
画面の遷移はメニューと画面に配置したボタンで行います。
環境はAndroidStudio4.1.1、Kotlinv1.4.21です。
<activity_main.xml>はcontainerのLinearLayoutを置いただけです。
<?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">
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:layout_editor_absoluteX="162dp"
tools:layout_editor_absoluteY="101dp"></LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<fragment_a.xml>はTextViewを一つ置いただけです。FragmetntのレイアウトファイルはFramelayoutで作られますが、constraint Layoutに変換しています。idはさぼって変更していないのでframelayoutのままです。layout_heightは”match_parent”だとFragmetntBが表示できないので”wrap_content”にしています。
<?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/frameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".FragmentA">
<TextView
android:id="@+id/textViewA"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/fragmentA_Text"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<fragment_b.xml>はTextViewとbuttonを置いてます。あとは<fragment_a.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:id="@+id/frameLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".FragmentB">
<TextView
android:id="@+id/textViewB"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/fragmentB_Text"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/buttonB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button_B"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewB" />
</androidx.constraintlayout.widget.ConstraintLayout>
<fragment_c.xml>はTextViewとbuttonを置いてます。<fragment_c.xml>を表示しているときは一つのFragmetntだけなのでlayout_heightは”match_parent”にしています。
<?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/frameLayout3"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmentC">
<TextView
android:id="@+id/textViewC"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/fragmentC_Text"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/buttonC"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button_C"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewC" />
</androidx.constraintlayout.widget.ConstraintLayout>
<fragment_d.xml>はTextViewのtextの内容が違うだけで、ほぼ<fragment_a.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:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".FragmentA">
<TextView
android:id="@+id/textViewA"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/fragmentA_Text"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<MainActivity.kt>は最初の画面のFragmetntの表示とメニューです。
package com.example.myfragmentposex
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val fragmentA = FragmentA()
val fragmentB = FragmentB()
if(savedInstanceState == null) {
val transaction = supportFragmentManager.beginTransaction()
transaction.add(R.id.container, fragmentA)
transaction.add(R.id.container, fragmentB)
transaction.commit()
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val fragmentA = FragmentA()
val fragmentB = FragmentB()
val fragmentC = FragmentC()
val fragmentD = FragmentD()
val transaction = supportFragmentManager.beginTransaction()
when(item?.itemId){
R.id.A_Select -> {
transaction.replace(R.id.container, fragmentA)
transaction.add(R.id.container, fragmentB)
transaction.commit()
}
R.id.C_Select -> {
transaction?.replace(R.id.container, fragmentC)
transaction.addToBackStack(null)
transaction?.commit()
}
R.id.D_Select -> {
transaction?.replace(R.id.container, fragmentD)
transaction.add(R.id.container, fragmentB)
transaction.addToBackStack(null)
transaction?.commit()
}
}
return super.onOptionsItemSelected(item)
}
}
<FragmentA.kt>と<FragmentD.kt>は自動でできるコードから使わないコードを消しただけです。
package com.example.myfragmentposex
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
class FragmentA : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_a, container, false)
}
}
package com.example.myfragmentposex
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
class FragmentD : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_d, container, false)
}
}
<FragmentB.kt>にはWidgetsのインスタンスの取得とボタンをクリックしたときの処理を書いています。
”textViewA”は”別のFragmetntのWidgetなので
getActivity()?.findViewById<View>(R.id.textViewA) as TextView?
で取得しています。
package com.example.myfragmentposex
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
class FragmentB : Fragment() {
private var textViewA: TextView? = null
private var button: Button? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_b, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
textViewA = getActivity()?.findViewById<View>(R.id.textViewA) as TextView?
button = view?.findViewById<View>(R.id.buttonB) as Button?
button?.setOnClickListener(){
textViewA?.append("ボタンクリックで追加。")
}
}
}
<FragmentC.kt>はボタンをクリックすると画面3に遷移するようにしています。
package com.example.myfragmentposex
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
class FragmentC : Fragment() {
private var buttonC: Button? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_c, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val fragmentD = FragmentD()
val fragmentB = FragmentB()
buttonC = view?.findViewById<View>(R.id.buttonC) as Button?
buttonC?.setOnClickListener(){
val transaction = getActivity()?.supportFragmentManager?.beginTransaction()
//transaction.add(R.id.container1, allViewFragment)
transaction?.replace(R.id.container, fragmentD)
transaction?.add(R.id.container, fragmentB)
transaction?.commit()
}
}
}
実行すると画面1が表示されます。配置はちゃんと設定していないので上に詰まって表示されています。ここでBUTTON_BをクリックするとFragmetntAのTextViewに”ボタンクリックで追加されました”の文字が追加されます。
次にメニューから”C”を選択すると画面2に遷移します。続いて画面2のBUTTON_Cをクリックすると画面3に遷移します。
画面3でもBUTTON_BをクリックするとFragmetntDのTextViewに”ボタンクリックで追加されました”の文字が追加されます。
とりあえず、やりたかったことは実現できました。
コメント