🦔
【Android】setFragmentResult の結果を Fragment で受け取る
setFragmentResult / setFragmentResultListener を使用する
setFragmentResult
、setFragmentResultListener
を使って結果の受け渡しを行うのですが、これらを使えるようにするために、app/build.gradle
に依存関係を追加します。
app/build.gradle
dependencies {
// 追加
implementation "androidx.fragment:fragment-ktx:1.3.6"
}
結果の受け渡し
setFragmentResultListener
- 第1引数 : 結果を渡す際に使用する
requestKey
を設定 - 第2引数 : ライフサイクルを指定
このライフサイクルがLifecycle.State.STARTED
の状態になると、setFragmentResult
で設定した結果が配信されます。
childFragmentManager.setFragmentResultListener(
"request_key",
viewLifecycleOwner
) { requestKey: String, result: Bundle ->
val text = result.getString("key_text", "")
...
}
setFragmentResult
- 第1引数 : 結果を渡す際に使用する
requestKey
を設定 - 第2引数 : 渡したい結果をセットした
Bundle
を指定
val bundle = bundleOf("key_text" to "sample")
setFragmentResult("request_key", bundle)
FragmentManager について
Activity
とFragment
間で結果をやりとりする場合はsupportFragmentManager
、Fragment
とFragment
間の場合はchildFragmentManager
を使います。
Activity と Fragment 間で結果を渡す場合
親Fragment と 子Fragment 間で結果を渡す場合
DialogFragment(子Fragment)
の結果を親Fragment で受け取る
実装例 : MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportFragmentManager.beginTransaction()
.replace(R.id.content_layout, MainFragment.newInstance())
.commitNow()
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" />
MainFragment.kt
class MainFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_main, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
childFragmentManager.setFragmentResultListener(
REQUEST_KEY,
viewLifecycleOwner
) { _, result: Bundle ->
val text = result.getString(MyDialog.KEY_CLICK, "unknown")
Toast.makeText(requireActivity(), text, Toast.LENGTH_SHORT).show()
}
requireActivity().findViewById<Button>(R.id.show_dialog_button).setOnClickListener {
MyDialog.newInstance(
requestKey = REQUEST_KEY
).show(childFragmentManager, this::class.java.simpleName)
}
}
companion object {
fun newInstance() = MainFragment()
private const val REQUEST_KEY = "request_key"
}
}
fragment_main.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/show_dialog_button"
style="@style/Widget.MaterialComponents.Button"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:text="ダイアログを表示する"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MyDialog.kt
class MyDialog : DialogFragment() {
private val _requestKey: String
get() = requireArguments().getString(KEY_REQUEST, "")
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return AlertDialog.Builder(requireActivity()).apply {
setTitle("タイトル")
setMessage("クリックイベントを伝えるよ")
setPositiveButton("ok") { _, _ ->
val bundle = bundleOf(KEY_CLICK to "okをクリック")
setFragmentResult(_requestKey, bundle)
}
setNegativeButton("cancel") { _, _ ->
val bundle = bundleOf(KEY_CLICK to "cancelをクリック")
setFragmentResult(_requestKey, bundle)
}
}.create()
}
companion object {
fun newInstance(
requestKey: String
) = MyDialog().apply {
arguments = bundleOf(KEY_REQUEST to requestKey)
}
const val KEY_CLICK = "click"
private const val KEY_REQUEST = "key_request"
}
}
Discussion