简体   繁体   中英

Kotlin Android Jetpack Navigation between Fragments in backstack

I have a small app. 1 Activity (MainActivity.kt) and two Fragments (MainFragment & CreateNewJobFragment).

Mainfragment has a Recyclerview. CreateNewJobFragment contains a 6 spinners and an edittext. I'm attempting to have the selections from the spinners and edittext to populate the RecyclerView when the user makes their choices and clicks a "create job" button.

The issue is, when this button is clicked, the app will go back up the backstack to the MainFragment, but instead of populating the recyclerview with a new item, it runs through onCreate again and nothing happens.

MainFragment.kt

class MainFragment : Fragment() ,ItemClickedCustomListener{
override fun onCustomSpinnerItemSelected(selectedItems: JobData) {

    Log.v("MainFragment","onCustomSpinnerItemSelected")
    Log.v("MainFragment","selectedItems --> "
            + selectedItems.companyName + " "
            + selectedItems.location + " "
            + selectedItems.pumpTruck + " "
            + selectedItems.smartPiggers)
    jobs.add(selectedItems)
    adapter = recyclerView.adapter as JobAdapter
    adapter.data(jobs)
}

var jobs = ArrayList<JobData>()
lateinit var  adapter : JobAdapter

private lateinit var binding: FragmentMainBinding
lateinit var recyclerView : RecyclerView

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        if (savedInstanceState == null) {
            binding = FragmentMainBinding.inflate(inflater)
            //getting recyclerview from xml and binding it
            recyclerView = binding.jobRecyclerView

            //adding a layoutmanager
            recyclerView.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)

            //Arraylist to store jobs using the data class JobData.
            // TODO: Change this to a user created list from CreateNewJobFragment.kt
            jobs = ArrayList()

            Log.v("MainFragment", "onCreateView --> ")

            //creating adapter
            adapter = JobAdapter(jobs)

            //add adapter to recyclerView
            recyclerView.adapter = adapter

            //Setting onClickListener for FAB(floating action button) using Navigation
            binding.createNewJobFAB.setOnClickListener { v: View ->
                v.findNavController().navigate(R.id.action_mainFragment_to_createNewJobFragment)
            }
        }
    return binding.root
}

}

CreateNewJobFragment.kt

class CreateNewJobFragment : Fragment() {

private lateinit var binding: FragmentCreateNewJobBinding

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    binding = FragmentCreateNewJobBinding.inflate(inflater)
    return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    var addJobToRecyclerview = JobData("","","","")


    //String array.
    //TODO: Move this to res/strings
    val companyNames = arrayOf("Company A", "Company B", "Company C", "Company D", "Company E")

    var nameSpinner = binding.spinnerCustomerName

    //Adapter for spinner
    nameSpinner.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, companyNames)

    //item selected listener for spinner
    nameSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
        override fun onNothingSelected(p0: AdapterView<*>?) {
            TODO("not implemented yet")
        }

        override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
            //user selected spinner choice added
            addJobToRecyclerview.companyName = companyNames[p2]
        }
    }

    //String array.
    //TODO: Move this to res/strings
    val refineryTown = arrayOf("Long Beach", "Houston", "Cherry Point", "Wood River", "Bismark")

    var townSpinner = binding.spinnerLocation

    //Adapter for spinner
    townSpinner.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_dropdown_item, refineryTown)

    //item selected listener for spinner
    townSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
        override fun onNothingSelected(p0: AdapterView<*>?) {
            TODO("not implemented yet")
        }

        override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
            addJobToRecyclerview.location = refineryTown[p2]
        }
    }

    <SNIP>Cutting out 5 repeated spinners and editText to save some space</SNIP>


    //Setting onClickListener for 'Create Job' button using Navigation
    binding.buttonCreateJob.setOnClickListener { v: View ->
        (activity as MainActivity).itemClickedCustomListener.onCustomSpinnerItemSelected(addJobToRecyclerview)
        Log.v("CreateNewJobFragment", "Job data added -->$addJobToRecyclerview")
        Log.v("CreateNewJobFragment", "Create job button --> clicked")

        v.findNavController().navigate(R.id.action_createNewJobFragment_to_mainFragment)

    }

}

}

I'm using the following Android documentation as a guide: Implementing Navigation

And this part in particular for the navigation back to MainFragment: Tie destinations to UI widgets

After clicking the "Create Job" button. App does go back to MainFragment. But as mentioned, nothing shows in Recyclerview.

I've some some logging in place. This is from the logs:

Log sample

2018-12-07 22:03:17.959 5806-5806/com.palarran.pigtimer V/MainActivity: onCustomSpinnerItemSelected

2018-12-07 22:03:17.959 5806-5806/com.palarran.pigtimer V/MainActivity: selectedItems --> Company A Long Beach Company 1 Company 4

2018-12-07 22:03:17.960 5806-5806/com.palarran.pigtimer V/CreateNewJobFragment: Job data added -->JobData(companyName=Company A, location=Long Beach, pumpTruck=Company 1, smartPiggers=Company 4)

2018-12-07 22:03:17.960 5806-5806/com.palarran.pigtimer V/CreateNewJobFragment: Create job button --> clicked

2018-12-07 22:03:18.026 5806-5806/com.palarran.pigtimer V/MainFragment: onCreateView -->

2018-12-07 22:03:18.146 5806-5806/com.palarran.pigtimer V/JobAdapter: getItemCount 0

2018-12-07 22:03:18.146 5806-5806/com.palarran.pigtimer V/JobAdapter: getItemCount 0

As you can see, after the log entry for "Create job button --> clicked", it jumps to "onCreateView" in the MainFragment and the item count in my custom adapter(JobAdapter.kt) does not increase.

JobAdapter.kt

class JobAdapter(private var jobList: ArrayList<JobData>) : RecyclerView.Adapter<JobAdapter.ViewHolder>() {

//Returning view for each item in the list
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): JobAdapter.ViewHolder {
    val v = LayoutInflater.from(parent.context).inflate(R.layout.job_list_item, parent, false)
    Log.v("JobAdapter","onCreateViewHolder")
    return ViewHolder(v)
}

//Binding the data on the list
override fun onBindViewHolder(holder: JobAdapter.ViewHolder, position: Int) {
    Log.v("JobAdapter","onBindViewHolder")
    holder.bindItems(jobList[position])
}

override fun getItemCount(): Int {
    Log.v("JobAdapter","getItemCount " + jobList.size)
    return jobList.size
}

fun data(jobs: ArrayList<JobData>) {
    Log.v("JobAdapter","DataSetChanged")
    jobList = jobs
    notifyDataSetChanged()
}

//Class holds the job list view
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    fun bindItems(job: JobData) {
        val textViewCompanyName = itemView.findViewById(R.id.tv_companyName) as TextView
        val textViewLocation  = itemView.findViewById(R.id.tv_job_location) as TextView

        textViewCompanyName.text = job.companyName
        Log.v("JobAdapter", "bindItems" + textViewCompanyName.text)
        textViewLocation.text = job.location
        Log.v("JobAdapter", "bindItems" + textViewLocation.text)
    }
}

}

Am I missing something in the documents or reading them incorrectly? I'm definitely misunderstanding something.

Late responding to this.

I was able to get this figured out. By using Sugar ORM database. Calling it in onResume() in my MainFragment.

It was a dumb question that I should have researched more before posting.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM