1

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()

    }

love2code
  • 55
  • 5
  • You should not start your MainActivity, but finish the current one and set result as in the commented code and check for requestCode. – hardartcore Mar 09 '21 at 09:47
  • Hi hardatcore, I get the error Unresolved reference: setResult in UpdateFragment.kt. And also the same for finish(). If this code worked it would bring the results back to the fragment ListFragment and then another finish() would be needed to send results back to MainActivity. – love2code Mar 09 '21 at 09:57
  • You should use `activity.setResult() / activity.finish()`. But I see in your code that you are using `Navigation` lib, if your whole navigation is based on that I think you should continue using the library for getting `onActivityResult`. – hardartcore Mar 09 '21 at 10:11
  • How can I use onActivityResult, I left an Update at the bottom of the question simplyfying my request. – love2code Mar 09 '21 at 10:46
  • Do you want to use Navigation library or to do it without it? – hardartcore Mar 09 '21 at 11:06
  • I want to use Navigation Library as it is essential to the RecyclerView and Update as well as List Fragments that I am using – love2code Mar 09 '21 at 11:43

2 Answers2

1

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()
        }
    }
}
Kunu
  • 5,078
  • 6
  • 33
  • 61
  • I changed the code but I think the onActivityResult in Main is not being opened because of how I am setting up the intent in UpdateFragment (is there a way of adding a request code and getting onActivityResult to be invoked from Update Fragment?): val intent = Intent(activity, OrderActivity::class.java) activity?.startActivity(intent) intent.putExtra("customerName", name) activity?.startActivity(intent) – love2code Mar 09 '21 at 09:22
0

Sorry didn't check the code entirely, but for your expected result you can try this:

Opening MainActivity from your UpdateFragment ->

You need to perform startActivityForResult from the fragment itself. Don't use activity?.startActivity(). By using startActivityForResult from UpdateFragment, you can implement onActivityResult() in the UpdateFragment itself and get the result from MainActivity when setResult() and finish() are called.

Edit: What I meant was to start the activity from the fragment and implement the onActivityResult in the fragment itself. This way your activity will start from fragment and once completed, will give the result to the fragment.

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, 141)

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

    return view
}

/* 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()
}
}

And in your main activity, override the onActivityResult and just call super().

MainActivity.kt:

/* This function is invoked once we return from Activity. */
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
//The activity gets the first shot at onActivityResult. 
//If we don't want to do any process here, then we need to call super.onActivityResult() 
//which will then allow the fragment's onActivityResult to be called. 
//This ONLY works when we start the activity from the fragment.
        super.onActivityResult(requestCode, resultCode, data)
    }

If you want, you can refer to this answer here to get onActivityResult Callback in the fragment.

  • Hi Rishabh, could you look at the Update at the bottom of the question. I tried implementing this but can't get the code working. – love2code Mar 09 '21 at 10:45
  • Hey please check my edited answer. Let me know how things work out! Sorry for the serious late reply... – Rishabh Kamdar Mar 15 '21 at 05:31