This question already has answers here:
findViewByID returns null
(33 answers)
NullPointerException when trying to access views in a Kotlin fragment
(9 answers)
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
I am new to android development. I have only been doing it for about a month now so I apologize if this is a simple question.
I am keep getting the following error when trying to run my app
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.swiperefreshlayout.widget.SwipeRefreshLayout.setOnRefreshListener(androidx.swiperefreshlayout.widget.SwipeRefreshLayout$OnRefreshListener)' on a null object reference
at edu.cogswell.tn.prism.MainActivity.onCreate(MainActivity.kt:54)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
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)
Here is my code
package (package name)
import android.app.AlertDialog
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.gson.Gson
import edu.cogswell.tn.prism.`interface`.NewsService
import edu.cogswell.tn.prism.adapter.viewHolder.ListSourceAdapter
import edu.cogswell.tn.prism.common.Common
import edu.cogswell.tn.prism.modle.WebSite
import io.paperdb.Paper
import kotlinx.android.synthetic.main.fragment_central.*
import retrofit2.Call
import retrofit2.Response
import javax.security.auth.callback.Callback
class MainActivity : AppCompatActivity() {
lateinit var layoutManager: LinearLayoutManager
lateinit var myService: NewsService
lateinit var adapter: ListSourceAdapter
lateinit var dialog: AlertDialog
var mSwipeRefreshLayout: SwipeRefreshLayout? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNaigationView)
val navController = findNavController(R.id.fragment)
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.central,
R.id.leftWing,
R.id.rightWing
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
bottomNavigationView.setupWithNavController(navController)
Paper.init(this)
myService = Common.newsService
swipe_to_refresh_centreal.setOnRefreshListener {
loadWebSiteSource(true)
}
recycler_view_source_news_central.setHasFixedSize(true)
layoutManager = LinearLayoutManager(this)
recycler_view_source_news_central.layoutManager = layoutManager
//dialog = SpotsDialog.Builder().setContext(this).build()
loadWebSiteSource(false)
}
private fun loadWebSiteSource(isRefresh: Boolean) {
if(!isRefresh){
val cache = Paper.book().read<String>("cache")
if(cache != null && !cache.isBlank() && cache != "null"){
val website = Gson().fromJson<WebSite>(cache, WebSite::class.java)
adapter = ListSourceAdapter(baseContext, website)
adapter.notifyDataSetChanged()
recycler_view_source_news_central.adapter = adapter
}
else{
dialog.show()
myService.sources.enqueue(object:retrofit2.Callback<WebSite>{
override fun onResponse(call: Call<WebSite>, response: Response<WebSite>) {
adapter = ListSourceAdapter(baseContext,response!!.body()!!)
adapter.notifyDataSetChanged()
recycler_view_source_news_central.adapter = adapter
Paper.book().write("cache", Gson().toJson(response!!.body()!!))
dialog.dismiss()
}
override fun onFailure(call: Call<WebSite>, t: Throwable) {
Toast.makeText(baseContext,"Failed",Toast.LENGTH_SHORT).show()
}
})
}
}
else{
swipe_to_refresh_centreal.isRefreshing = true
myService.sources.enqueue(object:retrofit2.Callback<WebSite>{
override fun onResponse(call: Call<WebSite>, response: Response<WebSite>) {
adapter = ListSourceAdapter(baseContext,response!!.body()!!)
adapter.notifyDataSetChanged()
recycler_view_source_news_central.adapter = adapter
Paper.book().write("cache", Gson().toJson(response!!.body()!!))
swipe_to_refresh_centreal.isRefreshing=false
}
override fun onFailure(call: Call<WebSite>, t: Throwable) {
Toast.makeText(baseContext,"Failed",Toast.LENGTH_SHORT).show()
}
})
}
}
}
Here is the xml code
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/swipe_to_refresh_centreal"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Central">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_source_news_central"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp" />
</RelativeLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
Not too sure why I keep getting this error. I am using this tutorial https://www.youtube.com/watch?v=mvVcqzJYAbY
For reference.
Thank you in advance.
I see that you use kotlin synthetic properties here. It's deprecated. So I recommend using any other instrument instead. Even findViewById is better in my opinion.
So what's wrong here. It's an often issue related to kotlin synthetic properties - wrong imports.
Look, you do all actions in an activity, but imported
import kotlinx.android.synthetic.main.fragment_central.*
So this line import view from layout named fragment_central. But you inflated activity_main instead. So this view simply does not exist here.
You are importing wrong layout. Can you try this. Pass your main activity layout in import section and remove the swiperefresh layout from import as well as from variable declaratiion.
import kotlinx.android.synthetic.main.your_layout.*
Related
I'm trying develope single-activity application using the navigation to corresponding fragment from my home fragment under certain conditions (see my code fragment below). But when I start application with the condition isLoggedIn == true, an exception appears:
2022-05-01 17:42:22.888 14974-14974/com.example.shercofaqapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.shercofaqapp, PID: 14974
java.lang.IllegalStateException: Fragment LoginFragment{d69320f} (2bebfc01-ce4e-435e-be4f-821b5d142eb8 id=0x7f0a0096) did not return a View from onCreateView() or this was called before onCreateView().
at androidx.fragment.app.Fragment.requireView(Fragment.java:2008)
at com.example.shercofaqapp.view.LoginFragment.onCreateView(LoginFragment.kt:47)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2995)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:523)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841)
at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:2777)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3020)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2784)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:262)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:478)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1425)
at android.app.Activity.performStart(Activity.java:7825)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3294)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
This is a fragment of my code:
package com.example.shercofaqapp.view
import android.content.Context
import android.os.Bundle
import android.text.TextUtils
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.databinding.DataBindingUtil
import androidx.navigation.Navigation
import com.example.shercofaqapp.R
import com.example.shercofaqapp.databinding.FragmentLoginBinding
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import kotlin.properties.Delegates
class LoginFragment : Fragment() {
lateinit var binding: FragmentLoginBinding
private var isLoggedIn by Delegates.notNull<Boolean>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val sharedPref = requireActivity()
.getSharedPreferences("MyPreferences", Context.MODE_PRIVATE)
val editor = sharedPref.edit()
var isLoggingIn = false
binding = DataBindingUtil.inflate(
inflater, R.layout.fragment_login, container, false)
binding.apply {
//Log in / sign up logic
isLoggedIn = sharedPref.getBoolean("isLoggedIn", false)
if (isLoggedIn) {
Navigation.findNavController(requireView())
.navigate(R.id.action_loginFragment_to_garageFragment)
}
}
return binding.root
}
}
The question is: how can I get view for Navigation before onCreateView() return it?
I tried to use this solution, but I don't understand what argument I should pass to .findNavController(...) in my case.
P.S. NavHostFragment is in MainActivity:
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/containerView"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph" />
</layout>
As per the Navigate to a destination documentation, you should use the findNavController() Kotlin extension on Fragment, which is a convenience wrapper around calling NavHostFragment.findNavController(this):
binding.apply {
//Log in / sign up logic
isLoggedIn = sharedPref.getBoolean("isLoggedIn", false)
if (isLoggedIn) {
// Make sure to:
// 1. Add a dependency on navigation-fragment-ktx in your build.gradle
// 2. import androidx.navigation.fragment.findNavController
findNavController()
.navigate(R.id.action_loginFragment_to_garageFragment)
}
}
findNavController(requireActivity())
.navigate(R.id.action_loginFragment_to_garageFragment)
use this code of line, I think it is helpful for you
Edit : If you are using it in fragment then,
Navigation.findNavController(getView()).navigate(R.id.action_loginFragment_to_garageFragment)
I initialized viewModel with this line viewModel = (activity as NewsActivity).viewModel in BreakingNewsFragment but, recived below error.
How i can fix this problem?! thanks for your help
BreakingNewsFragment
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.View
import com.example.simplenewsapp.R
import com.example.simplenewsapp.main.MainViewModel
import com.example.simplenewsapp.NewsActivity
import com.example.simplenewsapp.adapter.NewsRecyclerViewAdapter
import kotlinx.android.synthetic.main.fragment_breaking_news.*
class BreakingNewsFragment : Fragment(R.layout.fragment_breaking_news) {
lateinit var viewModel: MainViewModel
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = (activity as NewsActivity).viewModel
....
NewsActivity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.setupWithNavController
import com.example.simplenewsapp.data.local.ArticleDatabase
import com.example.simplenewsapp.main.MainRepository
import com.example.simplenewsapp.main.MainViewModel
import com.example.simplenewsapp.main.MainViewModelProviderFactory
import kotlinx.android.synthetic.main.activity_news.*
class NewsActivity : AppCompatActivity() {
lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_news)
val newsRepository = MainRepository(ArticleDatabase(this))
val mainViewModelProviderFactory = MainViewModelProviderFactory(newsRepository)
viewModel =
ViewModelProvider(this, mainViewModelProviderFactory).get(MainViewModel::class.java)
bottomNavigationView.setupWithNavController(newsNavHostFragment.findNavController())
}
}
MainViewModelProviderFactory
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
class MainViewModelProviderFactory(val mainRepository:MainRepository): ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return MainViewModel(mainRepository) as T
}
}
MainViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.simplenewsapp.data.local.models.NewsResponse
import com.example.simplenewsapp.util.Resource
import kotlinx.coroutines.launch
import retrofit2.Response
class MainViewModel(
val newsRepository: MainRepository
) : ViewModel() {
val breakingNews: MutableLiveData<Resource<NewsResponse>> = MutableLiveData()
var breakingNewsPage = 1
init {
getBreakingNews("us")
}
fun getBreakingNews(countyCode: String) = viewModelScope.launch {
breakingNews.postValue(Resource.Loading())
val response = newsRepository.getBreakingNews(countyCode, breakingNewsPage)
breakingNews.postValue(handleBreakingNewsResponse(response))
}
private fun handleBreakingNewsResponse(response: Response<NewsResponse>): Resource<NewsResponse> {
if (response.isSuccessful) {
response.body()?.let { resultResponse ->
return Resource.Success(resultResponse)
}
}
return Resource.Error(response.message())
}
}
Error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.simplenewsapp, PID: 4455
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.simplenewsapp/com.example.simplenewsapp.NewsActivity}: android.view.InflateException: Binary XML file line #17: Binary XML file line #17: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
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)
Caused by: android.view.InflateException: Binary XML file line #17: Binary XML file line #17: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #17: Error inflating class fragment
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property viewModel has not been initialized
at com.example.simplenewsapp.NewsActivity.getViewModel(NewsActivity.kt:16)
at com.example.simplenewsapp.ui.fragments.BreakingNewsFragment.onViewCreated(BreakingNewsFragment.kt:29)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2974)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:543)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1636)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3112)
at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3049)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2975)
at androidx.fragment.app.FragmentStateManager.ensureInflatedView(FragmentStateManager.java:389)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:281)
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:141)
at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:313)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:292)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:780)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:866)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:696)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:170)
at com.example.simplenewsapp.NewsActivity.onCreate(NewsActivity.kt:20)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
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)
I/Process: Sending signal. PID: 4455 SIG: 9
Firstly why you are using same View Model for fragment and activity ?
This approach is incorrect and may lead to inconsistent data and memory leaks.
Ideally fragment and activity should have their own independent View Model.
For example:
a) NewsActivity and NewsViewModel
b) BreakingNewsFragment and BreakingNewsViewModel
This separates the code by following the Separation of concerns principle and you will get benefit from this as your application logic grows.
And If you are looking for shared behavior/data, please used Shared View Model.
Secondly, instead of using the View Model from NewsActivity
you should initialize it completely in BreakingNewsFragment, the way you did in NewsActivity.
// Add below code either in your fragment or activity.
val newsRepository = MainRepository(ArticleDatabase(this))
val mainViewModelProviderFactory = MainViewModelProviderFactory(newsRepository)
viewModel = ViewModelProvider(this, mainViewModelProviderFactory).get(MainViewModel::class.java)
I know it's late but I'm happy to find the solution:
The problem was fragment tag of xml.
I changed the fragment tag to androidx.fragment.app.FragmentContainerView.
and initializing the fragmentcontentview and setting up nav controller:
val navHostFragment= supportFragmentManager.findFragmentById(R.id.newsNavHostFrag) as NavHostFragment
val navController= navHostFragment.navController
bottomNavigationView.setupWithNavController(navController)
Use this dependency instead:
implementation 'androidx.appcompat:appcompat:1.2.0'
and use this version only.
I used to use implementation 'androidx.appcompat:appcompat:1.3.1', and that creates the same error as you are facing.
Try once and use implementation 'androidx.appcompat:appcompat:1.2.0' dependency and exact the same version - that's what worked for me.
If you are using fragment like this:-
<FrameLayout
android:id="#+id/flFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/bottomNavigationView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<fragment
android:id="#+id/newsNavHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/news_nav_graph" />
</FrameLayout>
then you have to change your appcompat dependency version 1.3.1 to 1.2.0 like this
implementation 'androidx.appcompat:appcompat:1.2.0'
but if you are using latest dependency version i.e 1.3.1 then you have to use
<androidx.fragment.app.FragmentContainerView
android:id="#+id/newsNavHostFrag"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/news_nav_graph"/>
and in MainActivity.kt
change this :-
bottomNavigationView.setupWithNavController(newsNavHostFragment.findNavController())
to this:-
val navHostFragment= supportFragmentManager.findFragmentById(R.id.newsNavHostFrag) as NavHostFragment
val navController= navHostFragment.navController
bottomNavigationView.setupWithNavController(navController)
Use below line instead of lateinit var viewModel: MainViewModel
private val viewModel:MainViewModel by activityViewModels()
Also , if you can't import it check for this dependency in app level build.gradle
implementation 'androidx.fragment:fragment-ktx:1.1.0'
and remove this line : viewModel = (activity as NewsActivity).viewModel
For solving this error, you have to put this code in your activity as well as in your fragment both
in Newsactivity:-
val newsResporiaty = NewsResporiaty(ArticleDatabase(requireContext()))
val viewModelFactory = NewsViewModelProviderFactory(newsResporiaty)
viewModel = ViewModelProvider(this,viewModelFactory).get(NewsViewModel::class.java)
And also your in fragmets:-
val newsResporiaty = NewsResporiaty(ArticleDatabase(requireContext()))
val viewModelFactory = NewsViewModelProviderFactory(newsResporiaty)
viewModel = ViewModelProvider(this,viewModelFactory).get(NewsViewModel::class.java)
This worked for me.
Process: com.bignerdranch.android.on_callbabysitting, PID: 19624
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bignerdranch.android.on_callbabysitting/com.bignerdranch.android.on_callbabysitting.Home}: java.lang.IllegalStateException: recyclerv_view must not be null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.IllegalStateException: recyclerv_view must not be null
at com.bignerdranch.android.on_callbabysitting.Home.onCreate(Home.kt:42)
at android.app.Activity.performCreate(Activity.java:6975)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
tools:context=".Home">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerv_view"
android:layout_width="match_parent"
android:layout_height ="match_parent">
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
package com.bignerdranch.android.on_callbabysitting
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.inflate
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.recycv1.*
import kotlinx.android.synthetic.main.sidebar.*
import java.lang.IllegalStateException
class Home : AppCompatActivity() {
var names = ArrayList<String>()
var imgUrls = ArrayList<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.homepage)
lateinit var context: Context
var helper = MyDBHelper(applicationContext)
var db = helper.readableDatabase
var rs = db.rawQuery("SELECT * FROM USERS", null)
rs.moveToFirst()
while(rs.isAfterLast == false)
{
names.add(rs.getString(rs.getColumnIndex("EMAIL")))
rs.moveToNext()
names.add(rs.getString(rs.getColumnIndex("FIRST_NAME")))
rs.moveToNext()
//names.add(rs.getString(rs.getColumnIndex("LAST_NAME")))
//rs.moveToNext()
}
recyclerv_view.layoutManager = LinearLayoutManager(this)
recyclerv_view.adapter = RecyclerViewAdapter(imgUrls, names, this)
/*names.add(editTextTextEmailAddress3.getText().toString())
names.add(editTextTextPassword.getText().toString())
//names.add(editTextTextEmailAddress3.getText().toString())
//names.add(editTextTextPassword.getText().toString())*/
//try {
// recyclerv_view.adapter = RecyclerViewAdapter.First(this, imgUrls, names)
//recyclerv_view.layoutManager = LinearLayoutManager(this)
// }catch (ignored: IllegalStateException)
//{
//}
//val recyclerView : RecyclerView = findViewById(R.id.recyclerv_view)
//val recyclerView = findViewById<RecyclerView>(R.id.recyclerv_view)
//recyclerView.setAdapter(first)
//recyclerView.setLayoutManager(LinearLayoutManager(this))
}
}
package com.bignerdranch.android.on_callbabysitting
import android.app.PendingIntent.getActivity
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.recyclerview.widget.RecyclerView
import de.hdodenhof.circleimageview.CircleImageView
import android.widget.TextView
import android.widget.LinearLayout
import com.bumptech.glide.Glide
import java.security.AccessController.getContext
open class RecyclerViewAdapter(val imgNames: ArrayList<String>, val imgPic: ArrayList<String>, val context: Context) : RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
//var Context = context
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
{
// lateinit var cimg:CircleImageView
//lateinit var img:TextView
//lateinit var parentLayout: LinearLayout
val CircleImageView = itemView.findViewById<CircleImageView>(R.id.profile_image)
val TextView = itemView.findViewById<TextView>(R.id.textView19)
val TextView1 = itemView.findViewById<TextView>(R.id.textView18)
val TextView2 = itemView.findViewById<TextView>(R.id.textView20)
val parentLayout = itemView.findViewById<LinearLayout>(R.id.parent_layout)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
//var View = LayoutInflater.from(parent.getContext()).inflate(R.layout.homepage, parent, false)
//var viewHolder = ViewHolder(View)
return ViewHolder(LayoutInflater.from(context).inflate(R.layout.homepage, parent, false))
}
override fun getItemCount(): Int {
return imgNames.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
/* Glide
.with(context)
.asBitmap()
.load(imgPic.get(position))
.into(holder.CircleImageView)
var First = First(context,imgNames, imgPic)
First.imgN.add(imgNames.get(position))
*/
holder?.TextView?.text = imgNames.get(position)
holder?.TextView1.text = imgNames.get(position)
holder?.TextView2.text = imgNames.get(position)
holder?.parentLayout.parent
}
}
I am trying to have my code display the user's name at login in the home page, I can successfully move in from one activity to the next with a click, but when I add the recycler view in my home activity, it doesn't work. Attached is the recycler view XML, adapter activity, and my home class activity along with the log.
In your imports there are multiple UI's imported. Just check once where the recyclerview lies actually.
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.recycv1.*
import kotlinx.android.synthetic.main.sidebar.*
you've not initialized the recyclerv_view in the activity class.
java.lang.IllegalStateException: ProfileFragmentBinding.bind(view) must not be null
at com.xx.profile.ProfileFragment.onViewCreated(ProfileFragment.kt:39)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:332)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1997)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:198)
at android.app.ActivityThread.main(ActivityThread.java:7055)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:523)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:836)
From the last few days i am getting a very weird exception and the crash is happening mainly because of DataBindingComponent, as it is returning null, with dataBinding
It's working good with ViewBinding but with databinding it's crashing
Note(Coincidently): I have 21 modules in my project including this, i got this exception at runtime for every databinding module, and if i remove any other module and make it to 20, the code excecute fine for both databinding as well as for viewbinding.
But i need this as Module, It will be great, if u guys could assist me. Thanks in advance.
I am using Navigation-Architecture component with BottomNavigationView.
My Code is as Follows,
package com.xx.profile
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.observe
import com.xx.core.dagger.ViewModelFactory
import com.xx.core.dagger.coreComponent
import com.xx.core.util.LogoutInterface
import com.xx.core.util.context.launchUrl
import com.xx.core.util.event.EventObserver
import com.xx.profile.databinding.ProfileFragmentBinding
import com.xx.profile.di.DaggerProfileComponent
import javax.inject.Inject
class ProfileFragment(private val logoutInterface: LogoutInterface) : Fragment(R.layout.profile_fragment) {
private lateinit var binding: ProfileFragmentBinding
#Inject
lateinit var viewModelFactory: ViewModelFactory
private val viewModel: ProfileViewModal by lazy {
ViewModelProvider(viewModelStore, viewModelFactory).get(ProfileViewModal::class.java)
}
override fun onAttach(context: Context) {
super.onAttach(context)
DaggerProfileComponent.factory().create(context.coreComponent()).inject(this)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = ProfileFragmentBinding.bind(view)
}
}
My xml is as follows,
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context=".ProfileFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:orientation="vertical"
android:padding="16dp"
tools:ignore="ExtraText">
</LinearLayout>
</ScrollView>
</layout>
I'm a beginner with Android Studio and Kotlin. I get the following error when trying to change the text of a TextView using Synthetic Binding from within my class.
Unable to start activity ComponentInfo{com.oppenheimer.myapplication/com.oppenheimer.myapplication.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
The code up to "Some other text" works but when I try with "Very new phrase" from within the class it crashes. It seems to be a common error but I'm not finding other posts that match my issue.
Here is my code
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/MyText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
package com.oppenheimer.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MyText.text = "Some other text"
val myClass = MyClass()
myClass.MyFunction()
}
}
MyClass.kt
package com.oppenheimer.myapplication
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MyClass : AppCompatActivity() {
fun MyFunction () {
MyText.text = "Very new phrase"
}
}
Full Error
2020-05-02 13:13:50.784 3632-3632/com.oppenheimer.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.oppenheimer.myapplication, PID: 3632
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.oppenheimer.myapplication/com.oppenheimer.myapplication.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:163)
at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:174)
at android.content.Context.obtainStyledAttributes(Context.java:738)
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:692)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:659)
at androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.java:479)
at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:214)
at com.oppenheimer.myapplication.MyClass._$_findCachedViewById(Unknown Source:25)
at com.oppenheimer.myapplication.MyClass.MyFunction(MyClass.kt:10)
at com.oppenheimer.myapplication.MainActivity.onCreate(MainActivity.kt:18)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
How do I change the layout from within a class? What is the "right" way to do this? Should I Pass the TextView into the class?
Thanks
Generally speaking, you should not be trying to access a layout item from within another class, which is why you get an error.
Move it to the MainActivty's onCreate() function:
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MyText.text = "Some other text"
val myClass = MyClass()
myClass.MyFunction()
MyText.text = "Very new phrase"
}
}
MyClass.kt
class MyClass : AppCompatActivity() {
fun MyFunction () {
}
}
If you really need to, you could access MyText and alter its value by passing a reference of it to MyClass and to MyFunction() as a parameter.
MainActivity.kt
package com.oppenheimer.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MyText.text = "Some other text"
val textView = findViewById<TextView>(R.id.MyText)
val myClass = MyClass(textView)
myClass.MyFunction(textView)
}
}
MyClass.kt
package com.oppenheimer.myapplication
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MyClass(textView: TextView) : AppCompatActivity() {
fun MyFunction (textView: TextView) {
textView.text = "Very new phrase"
}
}
Please note also that following naming conventions is good software practice and therefore all function names should start with a small letter, myFunction().