I have created RecyclerView
in fragment
inside activity
, all are working good but when i do notifyDataSetChanged()
to adapter
from activity
through interface
,I got an error "lateinit property adapter
has not been initialized" but I have already initialized adapter
class BuildingListFragment : Fragment(), MainActivity.EditInterface {
lateinit var adapter: BuildingListAdapter
private var mListener: OnFragmentInteractionListener? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater!!.inflate(R.layout.fragment_building_list, container, false)
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val buildingList = ArrayList<BuildingDetailModel>()
val alphaList = arrayOf("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
"L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "z")
for (i in alphaList.indices) {
val building = BuildingDetailModel()
building.buildingName = alphaList[i] + " Building"
buildingList.add(building)
}
//initialize adapter
adapter = BuildingListAdapter(buildingList)
// RV_Building_List.layoutManager = LinearLayoutManager(context, LinearLayout.VERTICAL, false)
RV_Building_List.adapter = adapter
RV_Building_List.layoutManager = object : LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false) {
override fun onLayoutChildren(recycler: RecyclerView.Recycler?, state: RecyclerView.State) {
super.onLayoutChildren(recycler, state)
//TODO if the items are filtered, considered hiding the fast scroller here
val firstVisibleItemPosition = findFirstVisibleItemPosition()
if (firstVisibleItemPosition != 0) {
// this avoids trying to handle un-needed calls
if (firstVisibleItemPosition == -1)
//not initialized, or no items shown, so hide fast-scroller
{
fastscroller.visibility = View.GONE
}
return
}
val lastVisibleItemPosition = findLastVisibleItemPosition()
val itemsShown = lastVisibleItemPosition - firstVisibleItemPosition + 1
//if all items are shown, hide the fast-scroller
fastscroller.visibility = if (adapter.itemCount > itemsShown) View.VISIBLE else View.GONE
}
}
fastscroller.setRecyclerView(RV_Building_List)
fastscroller.setViewsToUse(R.layout.recycler_view_fast_scroller__fast_scroller, R.id.fastscroller_bubble, R.id.fastscroller_handle)
}
override fun editClickFromMainActivity() {
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
//at this line error is lateinit property adapter has not been initialized
if (adapter.getIsSelected()) adapter.setIsSelected(false) else adapter.setIsSelected(true)
}
override fun onDetach() {
super.onDetach()
mListener = null
}
override fun onResume() {
super.onResume()
}
interface OnFragmentInteractionListener {
// TODO: Update argument type and name
fun onFragmentInteraction(uri: Uri)
}
companion object {
// TODO: Rename and change types and number of parameters
fun newInstance(): BuildingListFragment {
val fragment = BuildingListFragment()
return fragment
}
}
}
My mainActivity
class MainActivity : AppCompatActivity() {
private val mOnNavigationItemSelectedListener =
BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_list -> {
val fragment = BuildingListFragment.Companion.newInstance();
addFragment(fragment, R.anim.slide_re_in, R.anim.slide_re_out)
return@OnNavigationItemSelectedListener true
}
R.id.navigation_map -> {
val fragment = BuildingMapFragment.Companion.newInstance();
addFragment(fragment, R.anim.slide_in, R.anim.slide_out)
return@OnNavigationItemSelectedListener true
}
}
false
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
val fragment = BuildingListFragment.Companion.newInstance()
addFragment(fragment, R.anim.slide_re_in, R.anim.slide_re_out)
iv_Add.setOnClickListener {
var intent = Intent(this, AddBuildingMapsActivity::class.java)
startActivity(intent)
}
iv_edit.setOnClickListener {
(BuildingListFragment.newInstance() as EditInterface).editClickFromMainActivity()
}
}
/**
* add/replace fragment in container [framelayout]
*/
private fun addFragment(fragment: Fragment, slide_re_in: Int, slide_re_out: Int) {
supportFragmentManager
.beginTransaction()
.setCustomAnimations(slide_re_in, slide_re_out)
.replace(R.id.fragmentContainer, fragment, null)//fragment.javaClass.getSimpleName()
.addToBackStack(null)//fragment.javaClass.getSimpleName()
.commit()
}
override fun onBackPressed() {
super.onBackPressed()
Log.e("TAG", "TAG")
}
interface EditInterface {
fun editClickFromMainActivity()
}
}
please help me to solve this issue thanks..
Your problem is that you're creating a new instance of the fragment when the click handler is being called in the main activity line
(BuildingListFragment.newInstance() as EditInterface).editClickFromMainActivity()
You will need to call the method on the actual fragment instance that's currently on screen. There's various ways of getting around this but I think the safest path for now is doing something like
iv_edit.setOnClickListener {
val fragment = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as? BuildingListFragment
fragment?.editClickFromMainActivity()
}
though this will mean that you must also use the same FRAGMENT_TAG
in addFragment
on the .replace(R.id.fragmentContainer, fragment, null)
line (FRAGMENT_TAG
instead of null
)
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