In a Fragment, Kotlins synthetic import for layouts provided by Anko isn't working. I am trying to set the visibility of the views but it says the view is null. I have the following code.
class HistoryFragment : Fragment(), HistoryContract.view, LoaderManager.LoaderCallbacks<List<SongEntity>>{
private lateinit var mPresenter : HistoryContract.Presenter
private lateinit var adapter: HistoryAdapte
private val loaderId : Int = 101
override fun onLoadFinished(loader: Loader<List<SongEntity>>?, data: List<SongEntity>?) {
hideLoadingIndicator()
if (data == null) {
showErrorView()
} else {
//update the adapter
adapter.updateDataset(data)
}
}
override fun onLoaderReset(loader: Loader<List<SongEntity>>?) {
}
override fun onCreateLoader(id: Int, args: Bundle?): Loader<List<SongEntity>> {
showLoadingIndicator()
return object : AsyncTaskLoader<List<SongEntity>>(activity!!.baseContext){
override fun loadInBackground(): List<SongEntity>? {
return mPresenter.fetchSongs()
}
}
}
override fun showLoadingIndicator() {
song_history_pv.visibility = View.VISIBLE
}
override fun hideLoadingIndicator() {
song_history_pv.visibility = View.INVISIBLE
}
override fun showErrorView() {
song_history_error_tv.visibility = View.VISIBLE
}
override fun hideErrorView() {
song_history_error_tv.visibility = View.INVISIBLE
}
override fun setPresenter(presenter: HistoryContract.Presenter) {
mPresenter = presenter
}
override fun showDiscoveredSongs(songs: List<SongEntity>) {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val rootView = inflater.inflate(R.layout.fragment_song_history, container, false)
loaderManager.initLoader(loaderId, null , this)
songHistoryRv.layoutManager = LinearLayoutManager(context)
songHistoryRv.adapter = HistoryAdapter {
Toast.makeText(activity!!.baseContext, "${it.name}", Toast.LENGTH_SHORT).show()
}
return rootView
}
}
Now when I am setting the visibility of the progress view in the showLoadingIndicator function i am getting the error that the view is null.

Below is the layout file that I am using for the fragment
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/songHistoryRv"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<ProgressBar
android:id="@+id/song_history_pv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/song_history_error_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/song_history_error"
android:visibility="invisible"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
import kotlinx.android.synthetic.main.fragment_song_history.* is the synthetic import that I am using.
Please help me out on this. Am I missing something? I am new to kotlin.
Your issue is that you are trying to access the view too early. In #onCreateView you are inflating your view but Fragment#getView() will still return null as long as you do not return the inflated view. Internally the Kotlin Android Extensions use getView().findViewById(int) method to bind the views the first time you are trying to access it.
tl;dr
To fix your issue simply return the inflated view in #onCreateView and move your operations regarding the LoaderManager to #onViewCreated:
class HistoryFragment : Fragment(), HistoryContract.view, LoaderManager.LoaderCallbacks<List<SongEntity>>{
// ...
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.fragment_song_history, container, false)
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
loaderManager.initLoader(loaderId, null , this)
songHistoryRv.layoutManager = LinearLayoutManager(context)
songHistoryRv.adapter = HistoryAdapter {
Toast.makeText(activity!!.baseContext, "${it.name}", Toast.LENGTH_SHORT).show()
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With