Androidプログラミング

【Android】FragmentとMainActivityで値を受け渡しする方法【Kotlin】

フラグメント内変数受け取り記事のアイキャッチ画像 Android

AndroidのFragment内の変数をメインのアクティビティで受け取る方法を紹介します。メインアクティビティとフラグメント間でデータのやり取りができるようになるとUIの表現の幅が広がるのでとても有効です。

スポンサーリンク

Fragmentファイルの作成・ボタン設置する方法

前回記事でフラグメントのファイル生成方法とボタンの設置方法を紹介しています。今回の内容は前回記事の続編になります。

フラグメントを使ったことがない方は以下記事を読むことをおススメします。

上記内容を踏まえて、以下で本題に入ります。

スポンサーリンク

サンプルコード(Fragment内変数をMainActivityで表示)

以下のような動作をするアプリを作成しました。

Fragment内変数受け取りサンプルアプリ

Fragment内のボタンを押すと、MainActivity内のtextViewを更新します。

値の受け渡しにはインターフェースを利用しています。

XML(Main,Fragment)

メインのXMLは以下の通り。
Fragmentと結果表示用のTextViewのみ。

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical">

        <!-- Fragment -->
        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/fgmtTouch"
            android:name="com.example.fragmentsample00.Fragment"
            android:layout_width="300dp"
            android:layout_height="200dp"
            android:layout_margin="20dp"/>

        <!-- Fragmentからのテキスト表示用 -->
        <TextView
            android:id="@+id/tvGetfromFragment"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Default Text"/>

    </LinearLayout>

フラグメントのXMLは以下の通り。
ボタンのみ配置。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:background="#0ff">

    <Button
        android:id="@+id/btnFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment Button" />

</LinearLayout>

Kotlin(Main,Fragment)

メインのKotlinは以下の通り。
Fragment側のファイルで定義されるインターフェースを実装

class MainActivity : AppCompatActivity(), Fragment.FragmentInterface {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)
    }

    // インターフェースの関数オーバーライド
    override fun onSetText(text: String) {
        binding.tvGetfromFragment.text = text
    }
}

フラグメントのKotlinは以下の通り。

class Fragment : Fragment() {

    private var _binding: FragmentBinding? = null
    private val binding get() = _binding!!

    // Activityに値返すようインターフェース
    internal var frgInterface:FragmentInterface? = null
    interface FragmentInterface {
        //val text_frg: String
        fun onSetText(text:String)
    }

    //インターフェースで値渡すのに必要(onCreateより先に呼ばれる)
    override fun onAttach(context: Context) {
        super.onAttach(context)
        if(context is FragmentInterface){
            frgInterface = context
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentBinding.inflate(layoutInflater, container, false)
        val view = binding.root

        // ボタンクラスのインスタンス作成
        val btnListener = BtnListener()
        // リスナを設定
        binding.btnFragment.setOnClickListener(btnListener)

        return  view
    }

    //binding 解放
    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    // クリックリスナ
    private inner class BtnListener: View.OnClickListener{
        override fun onClick(v: View) {
            when(v.id){
                binding.btnFragment.id -> {
                    // MainActivityへテキスト送信
                    frgInterface!!.onSetText("Text from Fragment")
                }
            }
        }
    }

}

スポンサーリンク

さいごに

画面遷移とFragmentを使いこなせればイメージするUIがどんどん作れるようになります。つかいこなしたいですね。

コメント

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