问题
I have a problem, I added three textView (textView, textView2, textView3) and imageView to fragment_home.xml and when I try to run the application on the emulator in Android Studio I get the error lateinit property homeViewModel has not been initialized.
homeFragment.kt
class homeFragment : Fragment() {
private lateinit var homeViewModel: homeViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
homeViewModel =
ViewModelProviders.of(this).get(homeViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_home, container, false)
val textView: TextView = root.findViewById(R.id.text_home)
homeViewModel.text.observe(this, Observer {
textView.text = it
})
return root
}
}
error log
6728-6728/com.radex.mysummercarmanual E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.radex.mysummercarmanual, PID: 6728
kotlin.UninitializedPropertyAccessException: lateinit property homeViewModel has not been initialized
at com.radex.mysummercarmanual.ui.home.homeFragment.onCreateView(homeFragment.kt:23)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2439)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2646)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2416)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2372)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3273)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2466)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1483)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3269)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:620)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1391)
at android.app.Activity.performStart(Activity.java:7157)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2937)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
回答1:
- Try initialise your viewModel inside
onActivityCreated()
- Don't observe or initiate you ViewModel inside
onCreateView()
- Rename your class name from
homeFragment
toHomeFragment
andhomeViewModel
toHomeViewModel
- You don't need to do findViewMyId in Kotlin. you can access view directly ID.
The change Idea is bellow
class HomeFragment : Fragment() { private lateinit var homeViewModel: HomeViewModel override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val root = inflater.inflate(R.layout.fragment_home, container, false) return root } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) homeViewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java) homeViewModel.text.observe(this, Observer { text_home.text = it }) } }
回答2:
When you initialize homeViewModel
, you reference an uninitialized one so it gives you the error.
ViewModelProviders.of(this).get(***homeViewModel***::class.java)
I think the class name of your ViewModel should be HomeViewModel
, so try this one:
private lateinit var homeViewModel: HomeViewModel
...
homeViewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)
回答3:
According to your code
, as you're inside fragment do not initialize
ViewModel inside onCreateView()
, simply means let the view create first then initilalize viewModel
.
To initialize viewModel
you have to override onActivityCreated() method and initialize viewModel inside it. Your code will be like this:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
homeViewModel = ViewModelProviders.of(activity!!)[HomeViewModel::class.java]
homeViewModel.text.observe(this, Observer {
text_home.text = it
})
}
And notice here i pass activity!!
rather than this
, cause you just can't get the activity context or getActivity() directly whenever you're inside the fragment just by calling this
. You have to tell manually. So your viewModel
instantiation will be like this:
homeViewModel = ViewModelProviders.of(activity!!)[HomeViewModel::class.java]
Or You could use if
block, like this:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
if(!::homeViewModel.isInitialized){
homeViewModel = ViewModelProviders.of(activity!!)[HomeViewModel::class.java]
homeViewModel.text.observe(this, Observer {
text_home.text = it
})
}
}
来源:https://stackoverflow.com/questions/58964019/lateinit-property-homeviewmodel-has-not-been-initialized