#android #kotlin #android-fragments #android-architecture-navigation
Вопрос:
Я перехожу от фрагмента A к фрагменту B , во Фрагменте B мне нужно вызвать обратный вызов , созданный во фрагменте A, я не хочу использовать для этого общую модель представления, вместо этого я просто хочу подключить своего слушателя из фрагмента A
В настоящее время это мой подход
class FragmentA: MyListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
FragmentB().apply {
this.myListener = this@FragmentA
}
myButton.setOnClickListener { findNavController().navigate(R.id.fragmentB) }
}
override fun launchFunction() { ... }
Теперь из моего фрагмента B я хочу запустить этот прослушиватель в другом методе, который у меня есть, но интерфейс имеет значение null
class FragmentB {
val myListener: MyListener? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
myListener.launchFunction()
}
Но это не работает, я подозреваю, что из FragmentA я правильно применяю прослушиватель к экземпляру FragmentB, который отличается от того, который использует NavController для навигации
Как я могу подойти к этому ?
Спасибо
Комментарии:
1. Небезопасно вызывать любого слушателя для фрагмента в заднем стеке. Есть ли причина, по которой вы не используете API для возврата результата ?
2. Я не возвращаю результат, но вместо этого мне нужно запустить операцию из фрагмента A @ianhanniballake
3. Я думаю, что я пойду с этим developer.android.com/guide/navigation/… и просто вставьте фрагмент b, чтобы выполнить метод фрагмента A @ianhanniballake
Ответ №1:
Попробуйте использовать следующий код, он будет работать.
//Receiver class
class CustomResultReceiver(handler: Handler?, receiver:
ResultReceiverCallBack) :
ResultReceiver(handler), Serializable {
private var mReceiver: ResultReceiverCallBack = receiver
override fun onReceiveResult(resultCode: Int, resultData: Bundle) {
mReceiver?.onLaunch(true, resultCode, resultData)
}
interface ResultReceiverCallBack {
fun onLaunch(action: Boolean, resultCode: Int, resultData: Bundle)
}
}
//Fragment A
Class FragmentA:Fragment(),CustomResultReceiver.ResultReceiverCallBack {
private lateinit var binding: FragmentABinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentABinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.dialogButton.setOnClickListener{
findNavController().navigate(
R.id.action_FragmentA_to_FragmentB,
Bundle().apply { putSerializable("key",
CustomResultReceiver(Handler(requireContext().mainLooper),
this@FragmentA))})
}
}
override fun onLaunch(action: Boolean, resultCode: Int, resultData:
Bundle) {
toast(“Fragment B launch“)
}
}
//Fragment B
Class FragmentB:Fragment(){
private lateinit var binding: FragmentBBinding
private var resultReceiver: ResultReceiver? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentBBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
arguments.let {
resultReceiver = arguments?.getSerializable("key") as
CustomResultReceiver
}
resultReceiver?.send(1,Bundle())
}
}