Возврат к фрагменту из Activity / RecyclerView.ViewHolder и передача данных

#kotlin #supportfragmentmanager

#kotlin #supportfragmentmanager

Вопрос:

У меня есть приложение, в котором я открываю activity из фрагмента, выбираю элемент из RecyclerView, а затем заполняю этот исходный фрагмент данными из выбранного элемента. Это работает в первый раз, но данные, похоже, не переносятся обратно во фрагмент, а затем, если я попробую это во второй раз, он скажет «Просмотр не найден для идентификатора 0x7f0a001a (com.tipsy.cardgenie:id / ScrollView01) для фрагмента AddCardFragment{dc1763f}». Я думаю, что я либо неправильно возвращаюсь к фрагменту, который создал activity, либо неправильно использую supportfragmentmanager.

 class QAViewHolder(view: View) : RecyclerView.ViewHolder(view) {

itemView.setOnClickListener { v: View ->
 val addCard = AddCardFragment()
                    val args = Bundle()
                    val activity = v.context as AppCompatActivity
                    args.putString("sport", cards.sport).toString()

                    activity.supportFragmentManager.beginTransaction()
                        .replace(R.id.content, addCard)
                        .addToBackStack(null)
                        .commit()
}
}
  

Во фрагменте onCreate, который у меня есть, который не видит данные, которые я установил в activity:

  val bundle = this.arguments
            if (bundle != null) {
                sport = bundle.getString("sport").toString()
            }
  

Представление содержимого находится в макете фрагмента, к которому я тоже возвращаюсь.

 <FrameLayout
        android:id="@ id/content"
        android:layout_height="match_parent"
        android:layout_width="match_parent">
</FrameLayout>
  

Заранее благодарим вас за любую помощь или предложения!!

Ответ №1:

Я могу предположить, что если нет необходимости открывать новое activity, тогда у вас может быть список или recyclerview во фрагменте, чтобы вы могли получать обновленные данные внутри фрагмента и выполнять все, что вы хотите. Но если вы хотите вернуть данные из определенного действия во фрагмент, вы можете открыть это действие из фрагмента, используя startActivityForResult(yourIntent,requestCode) этот метод, и после выбора элемента из recyclerview использования interface вы можете вернуть данные в действие и отправить обратно, используя этот фрагмент фрагменту

 val myIntent = Intent()
    myIntent.putExtra("data","your data")
    setResult(RESULT_OK,myIntent)
    finish()
  

Теперь вы можете объявить приведенный ниже метод в своем фрагменте и получить в нем свои данные

  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    // you can get your whatever data in @data object
}
  

а затем обновите свой код по мере необходимости … и нет необходимости заменять фрагмент из другого activity.

Комментарии:

1. Большое вам спасибо!!! Это сделало это — я слишком долго боролся с этим!

Ответ №2:

Рекомендуется обрабатывать события щелчка фрагментами и использовать методы обратного вызова. Вы можете добавить функцию ClickListener в конструктор вашего адаптера следующим образом

Adapter.kt

 Class Adapter(cards: List<Card>,val clickListener: (Card) -> Unit): RecyclerView.Adapter<MyAdapter.Holder>() {
}
  

В вашем методе onBindViewHolder вы устанавливаете ClickListener

 override fun onBindViewHolder(holder: Holder?, position: Int) {
    var card : Card = cards[position]

    // Calling the clickListener sent by the constructor
    holder?.itemView?.setOnClickListener { clickListener(card) }
}
  

Затем в вашей activity вы выполняете этот вызов при инициализации вашего адаптера

Activity.kt

 val adapter = Adapter(cards) {
  val addCard = AddCardFragment()
  val args = Bundle()
  args.putString("sport", cards.sport).toString()

  supportFragmentManager.beginTransaction()
      .replace(R.id.content, addCard)
      .addToBackStack(null)
      .commit()
}