Search code examples
androidkotlinandroid-fragmentsandroid-intentonactivityresult

trying to send data from a Fragment to an Activity with Kotlin and onActivityResult


When the 'Add Customer' Button is pressed in MainActivity.kt a new Activity is started for Result, CustomerActivity.kt. CustomerActivity opens up Fragment (ListFragment.kt) which contains a list of all the Customers in the Room Database.

When a Customer is clicked on, another Fragment is opened. In UpdateFragment.kt, all the customers information is displayed and a button "Choose Customer". Once clicked, an Intent is created and the Customers information is added to the Intent. The Main Activity is opened again and with it the selected customer information passed in the intent.

How can I open the Intent for its information from UpdateFragment.kt in MainActivity.kt? And gain access to the customer information that was passed with the intent? Currently I am able to create an intent with the customer information in UpdateFragment.kt and open MainActivity.kt but I do not know how to access the intent in MainActivity.

MainActivity.kt

package com.example.app

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.multiplerecyclerview.CustomerAdapter
import kotlinx.android.synthetic.main.activity_customer.*

const val INDEX = 0

class MainActivity : AppCompatActivity() {

    val list = ArrayList<DataModel>() /*ArrayList that is type Data Model. */

    /* Adapter class is initialized and list is passed in the param. */
    val customerAdapter = CustomerAdapter(this, getItemsList())

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)

        customerButton.setOnClickListener { /* Customer onclick button: Gets taken to the customer screen. */
            val intent = Intent(this@MainActivity, CustomerActivity::class.java)  /* Creating an Intent to go to Customer Activity so a customer can be selected. */
            startActivityForResult(intent,1) /* Starting Activity for result. */
        }

        /* Set the LayoutManager that this RecyclerView will use. */
        customerRecyclerView.layoutManager = LinearLayoutManager(this)

        /* Adapter instance is set to the recyclerview to inflate the items. */
        customerRecyclerView.adapter = customerAdapter

    }

    /* This function is invoked once we return from Activity. */
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (resultCode == 1) {
            val name: String = data?.getStringExtra("customerName").toString() /* storing the values from arguments returned. */
            val number: String = data?.getStringExtra("customerNumber").toString()
            val postalCode: String = data?.getStringExtra("postalCode").toString()
            val address: String = data?.getStringExtra("address").toString()

        }

    }

    private fun getItemsList(): ArrayList<DataModel> {

        list.add(DataModel("Todd Philips","123 Fake Street","012801212", OrderAdapter.CUSTOMER_ADD))

        return list
    }

}

CustomerActivity.kt

package com.example.app

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class CustomerActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_customer)
    }

}

activity_customer.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CustomerActivity">

    <fragment
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/app_nav" />

</androidx.constraintlayout.widget.ConstraintLayout>

ListFragment.kt

package com.example.app

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.app.viewmodel.AppViewModel
import com.example.app.fragments.list.ListAdapter
import kotlinx.android.synthetic.main.fragment_list.view.*

class listFragment : Fragment() {

    private lateinit var appViewModel: appViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_list, container, false)
        //val search = findViewById<>

        // RecyclerView
        val adapter = ListAdapter()
        val recyclerView = view.recyclerview
        recyclerView.adapter = adapter
        recyclerView.layoutManager = LinearLayoutManager(requireContext())

        //CustomerViewModel
        appViewModel = ViewModelProvider(this).get(AppViewModel::class.java)
        appViewModel.readAllData.observe(viewLifecycleOwner, Observer {customer ->
            adapter.setData(customer)
        })


        view.floatingActionButton.setOnClickListener {
            findNavController().navigate(R.id.action_listFragment_to_addFragment)
        }
        return view
    }
}

UpdateFragment.kt

package com.example.app.fragments.update

import android.content.Intent
import androidx.appcompat.app.AlertDialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.widget.AlertDialogLayout
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.example.app.*
import com.example.app.model.Customer
import com.example.app.viewmodel.APPViewModel
import kotlinx.android.synthetic.main.fragment_update.*
import kotlinx.android.synthetic.main.fragment_update.view.*

class UpdateFragment : Fragment() {

    private val args by navArgs<UpdateFragmentArgs>()
    private lateinit var appViewModel: APPViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_update, container, false)

        appViewModel = ViewModelProvider(this).get(APPViewModel::class.java)

        view.updateTextName.setText(args.currentCustomer.name)
        view.updateTextNumber.setText(args.currentCustomer.mobile)
        view.updatePostalAddress.setText(args.currentCustomer.eircode)
        view.updateTextAddress.setText(args.currentCustomer.address)

        view.updateBtn.setOnClickListener {
            updateItem()
        }

        view.deleteBtn.setOnClickListener {
            deleteItem()
        }

        view.pickBtn.setOnClickListener {
            val name = updateTextName.text.toString()
            val number = updateTextNumber.text.toString()
            val postalCode = updatePostalAddress.text.toString()
            val address = updateTextAddress.text.toString()

            Toast.makeText(requireContext(), "Pick Button Clicked!", Toast.LENGTH_SHORT).show()
           //val intent = Intent(getActivity(), OrderActivity::class.java)
           
            //Creating the intent to return to MainActivity with customer information
            val intent = Intent(activity, MainActivity::class.java)
            activity?.startActivity(intent)

            intent.putExtra("customerName", name)
            intent.putExtra("customerNumber", number)
            intent.putExtra("postalCode", postalCode)
            intent.putExtra("address", address)

            activity?.startActivity(intent)


           // setResult(RESULT_CODE_2, intent) // Tried using this code to finish the activity and return to main
           // finish() /* Ending the  Activity. */
        }

        return view
    }

    private fun updateItem() {
        val name = updateTextName.text.toString()
        val number = updateTextNumber.text.toString()
        val postalCode = updatePostalAddress.text.toString()
        val address = updateTextAddress.text.toString()

        val customer = Customer(args.currentCustomer.id, name,address,postalCode,number)

        posViewModel.updateCustomer(customer)
        Toast.makeText(requireContext(), "Successfully updated!", Toast.LENGTH_LONG).show()
        // Returning to the List Fragment
        findNavController().navigate(R.id.action_updateFragment_to_listFragment)

    }

    private fun deleteItem() {
       
    }

}


This Button Clicked in MainActivity

This Button Clicked in MainActivity

enter image description here

enter image description here

Update

I am in UpdateFragment.kt and I want to create an intent and extras about a customer and send the extra information to MainActivity.kt.

The problem is about recieving the information sent to MainActivity. I am using onActivityResult in MainActivity to recieve the intent from UpdateFragment. However the function is not being called. UpdateFragment.kt

    view.pickBtn.setOnClickListener {
            val name = updateTextName.text.toString()
            val number = updateTextNumber.text.toString()
            val postalCode = updatePostalAddress.text.toString()
            val address = updateTextAddress.text.toString()

            Toast.makeText(requireContext(), "Pick Button Clicked!", Toast.LENGTH_SHORT).show()
           //val intent = Intent(getActivity(), MainActivity::class.java)
       /*
            val intent = Intent(activity, MainActivity::class.java)

            intent.putExtra("customerName", name)
            intent.putExtra("customerNumber", number)
            intent.putExtra("postalCode", postalCode)
            intent.putExtra("address", address)

            activity?.startActivity(intent)
*/
            startActivityForResult(Intent(context, OrderActivity::class.java), 141)

           // setResult(RESULT_CODE_2, intent)
           // finish() /* Ending the  Activity. */
        }

        return view
    }

    override fun startActivityForResult(intent: Intent?, requestCode: Int) {

        if (requestCode == 141) {
            intent!!.putExtra("customerName", "John")
            intent.putExtra("customerNumber", "087212")
            intent.putExtra("postalCode", "V1H7")
            intent.putExtra("address", "123 Fake Street")

            onActivityResult(1, 2, intent)
        }

    }

MainActivity.kt


/* This function is invoked once we return from Activity. */
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

       
            val name: String = data?.getStringExtra("customerName").toString() /* storing the values from arguments returned. */
            val number: String = data?.getStringExtra("customerNumber").toString()
            val postalCode: String = data?.getStringExtra("postalCode").toString()
            val address: String = data?.getStringExtra("address").toString()

    }


Solution

  • I did not read everything you wrote but in your Activity class, you are checking the result code which is wrong. Change it to request code

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
    
        if (resultCode == RESULT_OK) {
            if (requestCode== 1) {
               val name: String = data?.getStringExtra("customerName").toString() /* storing the values from arguments returned. */
               val number: String = data?.getStringExtra("customerNumber").toString()
               val postalCode: String = data?.getStringExtra("postalCode").toString()
               val address: String = data?.getStringExtra("address").toString()
            }
        }
    }