AndroidのFragment内の変数をメインのアクティビティで受け取る方法を紹介します。メインアクティビティとフラグメント間でデータのやり取りができるようになるとUIの表現の幅が広がるのでとても有効です。
Fragmentファイルの作成・ボタン設置する方法
前回記事でフラグメントのファイル生成方法とボタンの設置方法を紹介しています。今回の内容は前回記事の続編になります。
フラグメントを使ったことがない方は以下記事を読むことをおススメします。
上記内容を踏まえて、以下で本題に入ります。
サンプルコード(Fragment内変数をMainActivityで表示)
以下のような動作をするアプリを作成しました。
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がどんどん作れるようになります。つかいこなしたいですね。
コメント