Передача данных с Jetpack - PullRequest
       71

Передача данных с Jetpack

0 голосов
/ 09 октября 2019

В поисках более элегантного способа передачи данных с помощью Jetpack

Теперь я передаю данные следующим образом:

override fun onListItemClick(itemIndex: Int, itemCode: String) {
        val bundle = Bundle()
        bundle.putString(KEY_TARGET_GUID, (adapter.getItem(itemIndex) as Target).guid)
        findNavController().navigate(R.id.target_edit, bundle)
    }

И получаю их в другом фрагменте, например:

private val targetGuid: String
        get() = arguments?.getString(KEY_TARGET_GUID, "") ?: ""

Я видел, как парни из Google делали это в codelab , но в его примере они создали класс FlowStepFragmentArgs, и он объемный

data class FlowStepFragmentArgs(val flowStepNumber: Int = 2) : NavArgs {
    fun toBundle(): Bundle {
        val result = Bundle()
        result.putInt("flowStepNumber", this.flowStepNumber)
        return result
    }

    companion object {
        @JvmStatic
        fun fromBundle(bundle: Bundle): FlowStepFragmentArgs {
            bundle.setClassLoader(FlowStepFragmentArgs::class.java.classLoader)
            val __flowStepNumber : Int
            if (bundle.containsKey("flowStepNumber")) {
                __flowStepNumber = bundle.getInt("flowStepNumber")
            } else {
                __flowStepNumber = 2
            }
            return FlowStepFragmentArgs(__flowStepNumber)
        }
    }
}

Q : Как мне красиво передать данные в моем случае

Ответы [ 2 ]

2 голосов
/ 09 октября 2019

Используя навигационную архитектуру, вы можете сделать это следующим образом: - Пусть вы объявили фрагменты в вашем файле navigation.xml как: -

 <fragment
    android:id="@+id/fragment_a"
    android:name="com.example.FragmentA">
    <action android:id="@+id/action_item_click"
        app:destination="@id/fragment_b" />
</fragment>

<fragment
    android:id="@+id/fragment_b"
    android:name="com.example.fragmentB">
    <argument android:name="id" app:argType="string" android:defaultValue="sample data" />
</fragment>

Примечание: -

  1. Класс создается для каждого пункта назначения, где начинается действие. Имя этого класса - это имя источника назначения, к которому добавлено слово " Направления ".
  2. В этом классе есть метод для каждого действия, определенного в исходном месте назначения.

Так что для FragmentA класса он будет сгенерирован как FragmentADirections например. -

override fun onListItemClick(itemIndex: Int, itemCode: String) {
    findNavController().navigate(FragmentADirections.actionItemClick("Pass YOUR_STRING"))
}

Примечание: -

  1. Создан класс для получателя . Имя этого класса - это имя пункта назначения, к которому добавлено слово " Args ".

А для FragmentB класса он будет сгенерирован, поскольку вы можете получать данные как FragmentBArgs Например: -

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    // do what you want with this id
    arguments?.let {bundle->
       val id = FragmentBArgs.fromBundle(bundle).id
    }
              // OR you can do also as
    // val id = arguments?.getString("id").orEmpty()
}

Для болеедетали, пожалуйста, используйте ссылку https://developer.android.com/guide/navigation/navigation-pass-data

0 голосов
/ 09 октября 2019

Насколько я знаю, на самом деле есть только 2 варианта передачи данных с помощью Jetpack Navigation.

1) Использование Bundle. Здесь я нахожу budnleOf(x to y) функцию очень удобной

    val targetGuid = adapter.getItem(itemIndex) as Target).guid)
    val bundle = bundleOf(KEY_TARGET_GUID, targetGuid)
    findNavController().navigate(R.id.target_edit, bundle)

2) Определяя аргументы вашего пункта назначения внутри вашего навигационного графика. Который будет генерировать код. Предполагая, что вы R.id.target_edit это фрагмент:

<fragment
    android:id="@+id/target_edit"
    android:name="com.example.TargetEditFragment"
    tools:layout="@layout/fragment_target_edit">
    <argument
        android:name="targetGuid"
        android:defaultValue="@null"
        app:argType="com.example.Target"
        app:nullable="true"/>
 </fragment>

Тогда в вашем TargetEditFragment

override fun onCreate(savedInstanceState: Bundle?) {
  val targetGuid =
    arguments?.let { TargetEditFragmentArgs.fromBundle(it).targetGuid }
}
...