Very new to coding ~1 month. Apologies if this is answered elsewhere, but spent hours looking through other similar questions but cant get it quite right. What: Trying to pass the position click data from fragment 1 (MainFragment) to fragment 2 (MapsFragment) to load the corresponding map. Goes through the adapter onclick method because I want to use RecyclerView on MainFragment. Project is buildable but crashes when I click an item on recyclerview (cant open map). Whats wrong????
Thanks ahead of time!!
EDIT: ANSWERED Thank you everyone for comments. Was able to solve this by 1) changing lateinit var on mapsfragment to a regular var + nullable, and 2) changing my bundle line in the main fragment to
val bundle = bundleOf(EXTRA_USER_MAP to sports[position])
view.findNavController(.navigate(R.id.action_mainFragment_to_mapsFragment, bundle)
woohoo Kotlin!
Main Fragment:
const val EXTRA_USER_MAP = "EXTRA_USER_MAP"
private const val TAG = "MainFragment"
class MainFragment : Fragment() {
override fun onCreateView ... // code to inflate my fragment view
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val sports = generateData()
myMaps.layoutManager = LinearLayoutManager(activity)
myMaps.adapter = this.context?.let {
MapsAdapter(it, sports, object: MapsAdapter.OnClickListener {
override fun onItemClick(position: Int) {
Log.i(TAG, "onItemClick $position")
// When user taps on view in recyclerview, navigate to new fragment and opens corresponding map
val bundle = Bundle()
bundle.putSerializable(EXTRA_USER_MAP, sports[position])
view.findNavController().navigate(R.id.action_mainFragment_to_mapsFragment)
}
})
}
}
private fun generateData(): List<Sport> { ... // code for my data set
Maps Fragment
private const val TAG = "MapsFragment"
class MapsFragment : Fragment(), OnMapReadyCallback {
private lateinit var map: GoogleMap
private lateinit var sport: Sport
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_maps, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val bundle = arguments
if (bundle !=null) {
sport = bundle.getSerializable(EXTRA_USER_MAP) as Sport
}
val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
mapFragment?.getMapAsync(this)
}
// Actions for map
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
Log.i(TAG, "Map rendered: ${sport.title}") // Logcat check once working
...
Related Adapter code
class MapsAdapter(
val context: Context,
val sports: List<Sport>,
val onClickListener: OnClickListener)
: RecyclerView.Adapter<MapsAdapter.ViewHolder>() {
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
interface OnClickListener {
fun onItemClick(position: Int)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val sport = sports[position]
holder.itemView.setOnClickListener {
Log.i(TAG, "Tapped on position $position")
onClickListener.onItemClick(position)
}
...