Fragment を使ってみる(その4)やりたいことの整理

Android Studio

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に”ボタンクリックで追加されました”の文字が追加されます。

とりあえず、やりたかったことは実現できました。

コメント

タイトルとURLをコピーしました