i started learing Kotlin after using Java, curently trying to create recyclerview using Kotlin, but everytime reach this code:
recyclerview!!.layoutManager = LinearlayoutManager(context)
inside a fragment, it always returns null for me, and by converting existing Java Code using converter in android studio returns error.Can anyone help me why this is always happened? code below is my current fragment code:
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.fragment_notes.*
import java.sql.Timestamp
class NotesFragment : Fragment() {
companion object {
fun newInstance(): NotesFragment {
return NotesFragment()
}
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater?.inflate(R.layout.fragment_notes, container, false)
val messageList : MutableList<message> = prepareMessage()
recycler_view!!.layoutManager = LinearLayoutManager(context)
recycler_view!!.adapter = NotesAdapter(context)
(recycler_view!!.adapter as NotesAdapter).setMessage(messageList)
return view
}
private fun prepareMessage(): MutableList<message> {
var messageList : MutableList<message> = ArrayList()
for(i in 0..10){
val timestamp: Long = System.currentTimeMillis()/1000L
val message = message(0,
"Judul Catatan ke $i",
resources.getString(R.string.lipsum),
timestamp
)
messageList.add(message)
}
return messageList
}
}
Thats because the views are not created yet in onCreateView. Since you are using kotlinx.android.synthetic you need to access it inside onViewCreated.Like this
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater?.inflate(R.layout.fragment_notes, container, false)
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
recycler_view = view.findViewById(R.id.your_recycler_id)
recycler_view?.layoutManager = LinearLayoutManager(context)
recycler_view?.adapter = NotesAdapter(context)
val messageList : MutableList<message> = prepareMessage()
(recycler_view?.adapter as NotesAdapter).setMessage(messageList)
}
Try this...
You should declare your recyclerview object, before accessing their properties.
.....
private var recycler_view: RecyclerView? = null
.....
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater?.inflate(R.layout.fragment_notes, container, false)
recycler_view = view.findViewById(R.id.your_recycler_id)
recycler_view?.layoutManager = LinearLayoutManager(context)
recycler_view?.adapter = NotesAdapter(context)
val messageList : MutableList<message> = prepareMessage()
(recycler_view?.adapter as NotesAdapter).setMessage(messageList)
return view
}
have you declare your recylerview like this
polishrecyler = view .findViewById<View>(R.id.polish_recyler) as RecyclerView
I just now had a similar situation.
In my project, I have a RecyclerView working perfectly. In my case, it has five files involved: Foo.kt (the model), FooList.kt (the AppCompatActivity class), FooListAdapter.kt, foo_list.xml (the layout with the RecyclerView) and foo_list_row.xml (my custom row for the ReyclerView). Not sure if it's important or not, but the icon for Foo.kt is while the icon for the FooList.kt and FooListAdapter.kt is
I needed another RecyclerView, so I simply created five new files: Bar.kt, BarList.kit, BarListAdapter.kit, bar_list.xml and bar_list_row.xml. I copied/pasted the code from one to the other, and made the appropriate Foo->Bar changes in the code. This is when I got the same error as the OP. Looking in the import section, the import for RecyclerView was flagged as "superfluous". Odd.
Most of the suggested answers here is to declare the variable and use findViewById to reference it. But, my working RecyclerView doesn't do that, so why should it be necessary in the second RecyclerView? It doesn't make sense.
I continued to search and found this solution:
Save the code found in two files I had created manually (BarList.kit
(the AppCompatActivity file) and the 'corresponding' bar_list.xml)
Delete those files.
Right-click on the package name and select New > Activity > Empty Activity. This re-created the files I had just deleted with exactly the same names.
Restore the code saved from step 1 to the appropriate files.
Now both my RecyclerViews work correctly.
I guess when you use the New > Activity > Empty Activity, Android Studio does some work in the background which is not done if you just create the files manually.
Related
I'm trying to implement left and right buttons on the home Fragment of my app, which should scroll to the next card of my RecyclerView. To do this I need to determine the current position of the view so that I can smooth scroll to this position +-1. But helper.findSnapView(linearLayoutManager) always returns null. When this should be fetched there is a
I/ViewConfigCompat: Could not find method getScaledScrollFactor() on ViewConfiguration
in the logcat, which I think is causing the problem. But searching online doesn't yield anything. The code is below. Please try to help me to understand the issue.
package com.example.storybook
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSnapHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SnapHelper
import com.example.storybook.Model.Book
import com.example.storybook.Utils.MarginItemDecoration
import com.example.storybook.Utils.RecyclerViewAdapter
import kotlinx.android.synthetic.main.fragment.*
class Fragment : Fragment(), View.OnClickListener {
private var mBooks = mutableListOf<Book>()
private val helper: SnapHelper = LinearSnapHelper()
private val linearLayoutManager = LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val listOfBookFilenames: Array<String> = context?.assets?.list("PDFs")!!
for (filename in listOfBookFilenames) {
val tempBook = Book(filename)
mBooks.add(tempBook)
}
return inflater.inflate(R.layout.fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
books_recycler.apply {
layoutManager = linearLayoutManager
adapter = RecyclerViewAdapter(mBooks, context)
}
books_recycler.addItemDecoration(MarginItemDecoration(65))
helper.attachToRecyclerView(books_recycler)
left_button.setOnClickListener {onClick(left_button)}
right_button.setOnClickListener {onClick(right_button)}
}
override fun onClick(view: View) {
val snapView: View? = helper.findSnapView(linearLayoutManager)
var currentFocusPosition = RecyclerView.NO_POSITION
if (snapView == null) {
println("View is null")
} else {
currentFocusPosition = linearLayoutManager.getPosition(snapView)
}
when(view) {
right_button -> books_recycler.smoothScrollToPosition(currentFocusPosition + 1)
left_button -> books_recycler.smoothScrollToPosition(currentFocusPosition - 1)
}
}
}
I have already tried declaring the snapHelper and linearLayoutManagers locally, within the onViewCreated and onClick methods, and it seems to make no difference. This is my first ever app, so there might be a lot I don't understand.
Despite having tried every configuration several times, and rebuilding over an over again, I rebuilt just one more time with the above configuration and it just worked. Sometimes it works out that way.
If you're here from the future and you're having the same problem, try declaring your snapHelper and linearLayoutManager as private values outside the functions and try rebuilding again.
I'm creating a portfolio app that uses Android's new Jetpack Navigation NavController. I've created a fragment with a RecyclerView that will be populated with views that you can click on to navigate to various app demos (and maybe actual apps I've made if I can figure that out). I'm currently populating the list manually, but I'd like to automate that process.
class PortfolioFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_portfolio, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val navController = view.findNavController()
val currentDestination = navController.currentDestination
// How get list of actions?
val appActions = listOf(
R.id.action_portfolioFragment_to_testFragment
)
portfolio_app_list.layoutManager = LinearLayoutManager(context)
portfolio_app_list.adapter = PortfolioAdapter(appActions)
}
}
I couldn't find any methods on NavGraph, nor NavDestination to get the list of actions available for currentDestination. I know that my navigation_main.xml has them, and I could use XMLPullParser or something like that to get them, but I may start using the Safe Args plugin which we'll mean that getting the actual class from the XML would be a pain.
This might be considered a bit hacky.
NavDestination has a private property called mActions which contains the NavActions associated with the NavDestination.
I solved this by using reflection to get access to it.
val currentDestination = findNavController().currentDestination
val field = NavDestination::class.java.getDeclaredField("mActions")
field.isAccessible = true
val fieldValue = field.get(currentDestination) as SparseArrayCompat<*>
val appActions = arrayListOf<Any>()
fieldValue.forEach { key, any ->
appActions.add(any)
}
The NavActions are returned as a SparseArrayCompat which is then iterated to obtain the List
I'm trying to learn how to implement databinding in an Android app. I have a small app I'm working with to learn this. And while I have databinding working for part of the app. I have hit a hiccup when trying to implement a recyclerview. I just cannot seem to get it. Been banging away at it for two or three days, and getting frustrated. Thought I'd ask you guys.
The app is super simple at this point.
The part i'm stuck on is accessing my recyclerview from an .xml layout from my MainFragment.kt
At first I was trying to use binding, but got frustrated and went back to just trying to use findViewById, but that is giving me issue too. I am beginning to think, I don't have as firm a grasp on databinding as I thought I did.
This is from the fragment that holds the recyclerView:
fragment_main.xml
<androidx.recyclerview.widget.RecyclerView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
android:id="#+id/job_recyclerView"/>
I have another small layout file that is using Cardview to show each individual item in the recyclerview
A super simple Model:
JobData.kt
data class JobData(val companyName: String, val location: String)
An Adapter:
JobAdapter.kt
class CustomAdapter(val userList: ArrayList<JobData>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
//Returning view for each item in the list
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomAdapter.ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.job_item_layout, parent, false)
return ViewHolder(v)
}
//Binding the data on the list
override fun onBindViewHolder(holder: CustomAdapter.ViewHolder, position: Int) {
holder.bindItems(userList[position])
}
override fun getItemCount(): Int {
return userList.size
}
//Class holds the job list view
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(job: JobData) {
val textViewName = itemView.findViewById(R.id.tv_company_name) as TextView
val textViewAddress = itemView.findViewById(R.id.tv_Location) as TextView
textViewName.text = job.companyName
textViewAddress.text = job.location
}
}
}
And then the code in my MainFragment to handle it all, which it is not doing. I've tried everything, it was getting ugly. As you can see below. Binding is in place and working for my FloatingActionButton. But I for some reason cannot figure out how to access that recylerview. At the point the code is at below, I thought I'd just accessing using findViewById, but that is not working either.
MainFragment.kt
class MainFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding: FragmentMainBinding = DataBindingUtil.inflate(
inflater, R.layout.fragment_main, container, false)
//Setting onClickListener for FAB(floating action button) using Navigation
binding.createNewJobFAB.setOnClickListener { v: View ->
v.findNavController().navigate(R.id.action_mainFragment_to_createNewJobFragment)
}
//getting recyclerview from xml
val recyclerView = findViewById(R.id.job_recyclerView) as RecyclerView
//adding a layoutmanager
recyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
//Arraylist to store jobs using the data class JobData
val jobs = ArrayList<JobData>()
//add dummy data to list
jobs.add(JobData("A Company", "Town A"))
jobs.add(JobData("B Company", "Town B"))
jobs.add(JobData("C Company", "Town C"))
jobs.add(JobData("D Company", "Town D"))
//creating adapter
val adapter = CustomAdapter(jobs)
//add adapter to recyclerView
recyclerView.adapter = adapter
return binding.root
}
}
The above fails to compile for two reasons:
findViewById shows as an "Unresolved Reference".
When adding the layoutManager, "this" shows as a "Type Mismatch"
Which I believe is due to the fact that Fragments do not have a context. Or so, I think anyway. But I don't know to resolve that? Maybe override some other method, but I can't seem to figure out which or how?
Oh and MainActivity looks like:
MainActivity.kt
class MainActivity : AppCompatActivity() {
//private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
#Suppress("UNUSED_VARIABLE")
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
}
//Ensures back button works as it should
override fun onSupportNavigateUp() = findNavController(this, R.id.navHostFragment).navigateUp()
}
Which is pointing to Nav_Graph for Android Navigation (part of JetPack). This bit is fine and working.
Adding gradle files to show that my dependencies were set correctly as suggested below.
app/gradle
android {
compileSdkVersion 28
dataBinding {
enabled = true
}
...
}
kapt {
generateStubs = true
correctErrorTypes = true
}
dependencies {
...
kapt "com.android.databinding:compiler:$gradle_version"
...
}
Encase your xml in <layout>..<layout/>
private lateinit var binding: FragmentXXXBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = FragmentXXXBinding.inflate(inflater)
return binding.root
}
Then you can call recyclerview by binding.jobRecyclerview
try to set all the click listeners etc on onViewCreated rather than onCreateView of fragment
It is wrong way to findViewById from Fragment(it is good technique for Activity):
val recyclerView = findViewById(R.id.job_recyclerView) as RecyclerView
First, fragment's layout have to be return by onCreateView() method.
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_main, container, false)
}
I personally like do all fragment's business logic inside onViewCreated()
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//Now, we can use views by kotlinx
//val recyclerView = job_recyclerView
//Or old-fashioned way
val recyclerView = getView()!!.findViewById(R.id.job_recyclerView) as RecyclerView
}
RecylerView can be accessed from fragment's layout by having root view like: getView()!!.findViewById or by kotlinx inside onViewCreated(): job_recyclerView
Ok, so first of all you are getting error on findViewById because your fragment is unaware about the view that contains recyclerView
What you should do is, take an instance of view that you are inflating for this fragment (declare view as a global variable, replace your inflater line with this).
var rootView
// Inside onCreateView
var rootView = inflater?.inflate(R.layout.fragment, container, false)
Now replace, findViewById() with rootView.findViewById()
And the other error is because the fragment does not have any context of it's own so replace this with activity!!
By writing activity!! you are calling getActicity() method which returns context of parent activity.
I have the following ViewHolder class for my Recycler View,
inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val dateText = itemView.itemDateSummaryList
private val systolicVal = itemView.systolicValue
private val diastolicVal = itemView.diastolicValue
fun update(listItem: SummaryListItemModel) {
Log.i(TAG, "Update method called " + listItem.date)
dateText.text = listItem.date
systolicVal.text = listItem.sysVal.toInt().toString()
diastolicVal.text = listItem.diasVal.toInt().toString()
}
}
But when I run the app an error comes up at the dateText.text = listItem.date saying,
java.lang.IllegalStateException: dateText must not be null
at *****.******.*****.ui.detailview.bloodpressure.SummaryListAdapter$ItemViewHolder.update(SummaryListAdapter.kt:68)
But the listItem.date is not null I have check with the Log.
the error is not about listItem.date, the error says that the dateText textview to which you are trying to set text is null ,
double check you are using the correct textview
Possibilities :
1) you might be using wrong id of textview
2) you may have used wrong file while inflating view.
ctrl + click on itemDateSummaryList and see whether the textview is from he same layout file you have infate or otherwise
If you are using fragments: 1. Use a global variable that will hold your layout reference
private var root: View? = null // create a global variable which will hold your layout
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
root = inflater.inflate(R.layout.your_layout_file_name, container, false) // initialize it here
return root
}
To use any view of your layout which is inside your layout you can use it with (root.) like:
root?.textView.text="Hello"
It's saying your dateText view itself is null not the value listItem.date Verify whether you are rendering it correctly, the itemview has the TextView with the id you are trying to access
The same happened to me while using Fragment, I took my code from onCreateView and put it to onViewCreated method, the problem solved.
I get this error my fragment,
I solved this error,
Error's Code:
class MyFragment : Fragment(){
private var item: Item? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
item = arguments?.getParcelable(BUNLDE_ITEM)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
item?.let {
textViewTitle.text = "Text"
}
return inflater.inflate(R.layout.my_fragment, null, false)
}
companion object {
private const val BUNLDE_ITEM = "item"
fun newInstance(item: Item) = MyFragment().apply {
arguments = Bundle().apply {
putParcelable(BUNLDE_ITEM, item)
}
}
}
}
Working Code:
class MyFragment : Fragment() {
private var item: Item? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
item = arguments?.getParcelable(BUNLDE_ITEM)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val root: View = inflater.inflate(R.layout.my_fragment, container, false)
val textViewTitle = root.findViewById<View>(R.id.textViewTitle) as TextView
item?.let {
textViewTitle.text = "text"
}
return root
}
companion object {
private const val BUNLDE_ITEM = "item"
fun newInstance(item: Item) = MyFragment().apply {
arguments = Bundle().apply {
putParcelable(BUNLDE_ITEM, item)
}
}
}
}
It also might happen on wrong context reference in xml file, usually it appears on manualy moving Activity to another package, Android studio didn't make this change automatically:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:tools="http://schemas.android.com/tools"
....
tools:context=".view.ui.login.LoginActivity">
....
</androidx.constraintlayout.widget.ConstraintLayout>
I read all of these answers but none worked for me so here is my answer.
Find the line of code similar the this:
var view:View?=inflater.inflate(R.layout.fragment_profilefragement, container, false)
Place your cursor on fragement_ProfileFragement and click with CTRL. Check that you are in the right fragement XML file.
I just had the same issue with my RecyclerView. It had been working for months. After numerous unsuccessful troubleshooting steps, I did a Build > Clean Project and it fixed the issue.
You have look carefully because IN SOME PART OF YOUR CODE you are not referencing the view correctly. In other words, that specific view does not exist in your code.
Try to repeat the steps you did
Check in the class where the code fails your view is being inflated correctly.
This will save you hours of looking where is wrong.
I tried to this code which is mention below, but getting crash during run time. The error occurred is Android Run time:
FATAL EXCEPTION: main Process: com.root.specialbridge, PID: 17706 kotlin.KotlinNullPointerException at com.root.specialbridge.fragments.profile_fragment.WallFragments.initializeView(WallFragments.kt:49)
class WallFragments : Fragment(){
private var wallAdapter: WallAdapter? = null
private var wall_recycler: RecyclerView? = null
private val wallArrayList: ArrayList<Wall>? = null
private var mainlayout: LinearLayout? = null
private var no_result_found_layout: RelativeLayout? = null
private var userProfileWallInterface: UserProfileWallInterface? = null
internal var wallActivityBeanse: MutableList<WallActivityBeans> = ArrayList()
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater!!.inflate(R.layout.wall_fragments, container, false)
userProfileWallInterface = UserProfileWallPresentation(activity, this)
initializeView()
wallAdapter = WallAdapter(activity, wallActivityBeanse)
wall_recycler!!.adapter = wallAdapter
return view
}
fun initializeView() {
wall_recycler = view!!.findViewById(R.id.wall_recycler_id) as RecyclerView
mainlayout = view!!.findViewById(R.id.mainlayout) as LinearLayout
no_result_found_layout = view!!.findViewById(R.id.no_result_found_layout) as RelativeLayout
wall_recycler!!.layoutManager = LinearLayoutManager(activity)
wall_recycler!!.setHasFixedSize(true)
if (AuthPreference(activity).isGetMemberProfile) {
userProfileWallInterface!!.getMemberProfileWall(view!!)
} else {
userProfileWallInterface!!.getUserProfileWall(AuthPreference(activity).token, AuthPreference(activity).user.id, view!!)
}
}
companion object {
val instance: WallFragments
get() = WallFragments() }}
Add
apply plugin: 'kotlin-android-extensions'
in the app level gradle file and
import
import kotlinx.android.synthetic.main.fragment_your_fragment_name.view.*
in the onCreateView of your fragment (e.g. if the id of your textview is textView)
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
val view = inflater!!.inflate(R.layout.fragment_splashfragment, container, false)
view.textView.text = "hello" //add your view before id else getting nullpointer exception
return view
}
UPDATE:
declare viewOfLayout in your class instead of view.
class yourfragment:Fragment(){
private lateinit var viewOfLayout: View
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
viewOfLayout = inflater!!.inflate(R.layout.fragment_splashfragment, container, false)
viewOfLayout.textView.text = "hello" //add your view before id else will get nullpointer exception
return viewOfLayout
}
}
Introducing Kotlin Android Extensions.
You do not have to use findViewById anymore. Using this plugin you can use the UI component directly as a global field. Supported in Activities, fragments and views.
Example,
To refer text view from the layout below,
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/hello"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, MyActivity"/>
</android.support.constraint.ConstraintLayout>
in activity you can simply write,
// Using R.layout.activity_main from the main source set
import kotlinx.android.synthetic.main.activity_main.*
class MyActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Instead of findViewById(R.id.hello) as TextView
hello?.setText("Hello, world!")
}
}
in fragments,
// Using R.layout.fragment_content from the main source set
import kotlinx.android.synthetic.main.fragment_content.*
class ContentFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
inflater.inflate(R.layout.fragment_content, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Instead of view.findViewById(R.id.hello) as TextView
hello?.setText("Hello, world!")
}
}
and for views,
// Using R.layout.item_view_layout from the main source set
import kotlinx.android.synthetic.main.item_view_layout.*
class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) {
fun bindData(data: String) {
// Instead of itemView.findViewById(R.id.hello) as TextView
itemView.hello?.setText(data)
}
}
And, you should not use !! everywhere, unless you want NullPointerException explicitly.
Instead use anyone from the following:
Do null check with safe call - ?., Eg. nullableVariable?.method()
Use non-null object using ?.let{ }, Eg. nullableVariable?.let { it.method() }
Supplying a backup value for the nullable variable using elvis operator - ?:, Eg. nullableVariable ?: <backupValue>.
Read more about Null Safety in Kotlin.
Initialization of view in fragment :
wall_recycler=view.findViewById<RecyclerView>(R.id.wall_recycler_id)
mainlayout = view.findViewById<LinearLayout>(R.id.mainlayout)
The problem is that you are accessing it too soon. requireView() and view returns null in onCreateView.I have find all views in onViewCreated().
Try doing it in the onViewCreated method:
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
wall_recycler=requireView().findViewById<RecyclerView>(R.id.wall_recycler_id)
mainlayout = requireView().findViewById<LinearLayout>(R.id.mainlayout)
mainlayout.setOnClickListener { Log.d(TAG, "onViewCreated(): hello world");}
}