Не удается получить доступ к методу фрагмента из действия - UninitializedPropertyAccessException - PullRequest
0 голосов
/ 05 мая 2018

У меня есть ViewPager. Я хочу изменить страницу, когда фрагмент позволяет это сделать.

Это onClick, когда я хочу проверить.

when (currentPage) {
   0 -> {
      if ((mAdapter.getItem(currentPage) as NameFragment).canGo()) {
         mViewPager.setCurrentItem(currentPage + 1, true)
      }
   }
   1 -> ...
}

Мой фрагмент:

private lateinit var fName: EditText
private lateinit var lName: EditText

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View = UI {
    verticalLayout {
       fName = editText {
          hint = "FIRST NAME"
          textSize = 20f
       }
       lName = editText {
          hint = "LAST NAME"
          textSize = 20f
       }
    }
}    

fun canGo(): Boolean {
   val firstName = fName.text.toString()
   val lastName = lName.text.toString()

   if (firstName.isEmpty() || firstName.isBlank() || lastName.isBlank() || lastName.isEmpty()) {
       toast("First name or Last name cannot be empty")
       return false
   }
   return true
}

Я инициализирую fName и lName в методе onCreateView, и это ошибка, которую я получаю. Полное исключение - здесь .

kotlin.UninitializedPropertyAccessException: lateinit property fName has not been initialized

Ответы [ 2 ]

0 голосов
/ 06 мая 2018

Я нашел ответ на этой статье. Сначала я отредактировал Adapter:

private class Adapter(fm: FragmentManager, private val fragments: ArrayList<Fragment>) : FragmentStatePagerAdapter(fm) {
   private val instantiatedFragments = SparseArray<WeakReference<Fragment>>()

   override fun getItem(position: Int): Fragment = fragments[position]

   override fun getCount() = fragments.size

   override fun instantiateItem(container: ViewGroup, position: Int): Any  {
     val fragment = super.instantiateItem(container, position) as Fragment
     instantiatedFragments.put(position, WeakReference(fragment))
     return fragment
   }

   @Nullable
   fun getFragment(position: Int) = instantiatedFragments.get(position)?.get()
}

А также мой onClick метод

when (currentPage) {
  0 -> {
     if ((mAdapter.getFragment(currentPage) as NameFragment).canGo()) {
        mViewPager.setCurrentItem(currentPage + 1, true)
     }
  }
  1 -> ...
}

Я изменил getItem(currentPage) на getFragment(currentPage).

0 голосов
/ 06 мая 2018

Эти свойства нужно инициализировать в методе onViewCreated, а не onCreateView.

onCreateView отвечает только за создание представления, как следует из названия, тогда как onViewCreated отвечает за обработку событий после правильного создания фрагмента.

И если вам нужно, вы можете создать обратный вызов, который будет запускаться при создании представления фрагмента, а затем реализовать этот обратный вызов в упражнении, так что вы получите доступ к этому методу canGo только после создания фрагмента. Опять же, только если вам действительно нужно.

interface OnFragmentInflatedListener {
    fun onFragmentInflated(fragment: Fragment)
}

// Fragment
private var onFragmentInflatedListener: OnFragmentInflatedListener? = null

fun setOnFragmentInflatedListener(onFragmentInflatedListener: OnFragmentInflatedListener?) {
    this.onFragmentInflatedListener = onFragmentInflatedListener
}

// Fragment's onViewCreated
// initialise your properties here
onFragmentInflatedListener?.onFragmentInflated(this)

// Activity
class MyActivity : AppCompatActivity(), OnFragmentInflatedListener {

    @Override
    fun onCreate(savedInstanceState: Bundle) {
        // do your stuff
        myFragment.setOnFragmentInflatedListener(this)
    }

    @Override
    fun onFragmentInflated(fragment: Fragment) {
        // do what you wanted to do
    }

}
...