无法从活动访问片段的方法 - UninitializedPropertyAccessException

时间:2018-05-05 20:57:04

标签: android kotlin android-viewpager anko

我有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方法上初始化lNameonCreateView,这是我得到的错误。完全例外是here

kotlin.UninitializedPropertyAccessException: lateinit property fName has not been initialized

2 个答案:

答案 0 :(得分:0)

这些属性需要在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
    }

}

答案 1 :(得分:0)

我在this文章中找到了答案。首先,我编辑了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)