Я расширил класс диалога и настройку макета, которую я хотел.
Проблема, которую я столкнулся, заключается в том, что мне нужен способ получить данные с ввода, если пользователь попадает в сохранение. < /p>
Первая попытка: Retrive via On Aattachment < /code> < /b /> hits> < /p>
. Интерфейс с одной функцией, которая возвращает это значение, сделал мой фрагмент (тот, который собирается вызвать пользовательский диалог). Их, я перевернул onattachfragment в моем пользовательском диалоге, как это:
Код: Выделить всё
class CustomDialogFragment private constructor() : DialogFragment() {
companion object {
fun getInstance(callback: Callback): CustomDialogFragment {
return Bundle().apply {
putSerializable("callback", callback)
}.let {
CustomDialogFragment().apply { arguments = it }
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
saveCallback = it.getSerializable("callback")!! as Callback
}
}
private lateinit var saveCallback: Callback
interface Callback : Serializable {
fun setText(text: String)
}
private var _binding: FragmentCustomDialogBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentCustomDialogBinding.inflate(inflater, container, false)
return binding.root
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState)
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
return dialog
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupViews()
}
private fun setupViews() = binding.run {
closeIcon.setOnClickListener { closeDialog() }
cancelButton.setOnClickListener { closeDialog() }
saveButton.setOnClickListener { onSaveClicked() }
}
private fun onSaveClicked() = binding.run {
val strMaxPrice = maxPriceInput.text.toString()
saveCallback.setText(strMaxPrice)
closeDialog()
}
override fun onAttachFragment(childFragment: Fragment) {
super.onAttachFragment(childFragment)
saveCallback = childFragment as Callback
}
private fun closeDialog() {
requireDialog().hide()
}
}
< /code>
и на фрагменте, который отображает этот диалог: < /p>
class FirstFragment : Fragment(), Callback {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.buttonFirst.setOnClickListener {
val fragmentManager = requireActivity().supportFragmentManager
val newFragment = CustomDialogFragment.getInstance(callback)
newFragment.show(fragmentManager, "dialog")
}
}
override fun setText(text: String) {
Toast.makeText(requireContext(), text, Toast.LENGTH_LONG).show()
}
...
}
Кроме того, этот метод устарел, так что ... давайте попробуем другой способ. Это значение в пакете диалога, поэтому, когда произойдут такие вещи, как изменения конфигурации, ваше значение не будет потеряно. Тем не менее, интерфейс не может быть сохранен на пакете, но сериализуемое значение может. Итак, давайте создадим интерфейс, который реализует этот метод: < /p>
Код: Выделить всё
companion object {
fun getInstance(callback: Callback): CustomDialogFragment {
return Bundle().apply {
putSerializable("callback", callback)
}.let {
CustomDialogFragment().apply { arguments = it }
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
saveCallback = it.getSerializable("callback")!! as Callback
}
}
private lateinit var saveCallback: Callback
interface Callback : Serializable {
fun setText(text: String)
}
< /code>
и на фрагменте, который будет показывать этот диалог: < /p>
class FirstFragment : Fragment(), CustomDialogFragment.Callback {
override fun setText(text: String) {
Toast.makeText(requireContext(), text, Toast.LENGTH_LONG).show()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.buttonFirst.setOnClickListener {
val fragmentManager = requireActivity().supportFragmentManager
val newFragment = CustomDialogFragment.getInstance(this)
newFragment.show(fragmentManager, "dialog")
}
}
...
}
< /code>
Однако это звучало многообещающе и сработало (я мог бы вызвать диалог, отобразить его и получить значение), если я минимизирую свое приложение после отображения диалога (до или после закрытия диалога), мое приложение сбоя с BadparcelableException: < /p>
Fatal Exception: android.os.BadParcelableException
Parcelable encountered IOException writing serializable object (name = com.package.app.MyFragment)
< /code>
Итак, это тоже не сработало ... < /p>
третья попытка: использование навигации и Safeargs < /h3>
Я помню, что у нас теперь есть навигация, так что давайте попробуем с этим: < /p>
graph: < /p>
my customfragment: < /p>
class CustomDialogFragment : DialogFragment() {
private val args: CustomDialogFragmentArgs by navArgs()
private val block = args.block
< /code>
Моя активность: < /p>
findNavController().navigate(MyFragmentDirections.toCustomDialogFragment(object : Callback {
override fun setText(text: String) {
Toast.makeText(requireContext(), text, Toast.LENGTH_LONG).show()
}
}))
< /code>
обратный вызов: < /p>
interface Callback : java.io.Serializable {
fun setText(text: Int)
}
< /code>
, который также не работал, отображая эту ошибку: < /p>
Caused by: java.lang.IllegalStateException: Fragment CustomDialogFragment{7fd896f} (a78e55c0-62f1-48c2-bc19-3f9d6f85adb2) has null arguments
>
Подробнее здесь: https://stackoverflow.com/questions/757 ... ogfragment
Мобильная версия