Teox76
Teox76

Reputation: 11

Launch Activity from onClick method of Listview (Fragment)

I recently started learning Android development in Kotlin. I did follow this guide and everything went good.

Now I'm trying to merge the content of those two guides:
https://developer.android.com/training/contacts-provider/retrieve-details.html#kotlin
and
https://developer.android.com/guide/components/fragments#Example

in order to display the details of a Contact using Fragments. I'm having trouble to launch an activity in the onItemClick method (the guide uses a ListView):

 override fun onItemClick(parent: AdapterView<*>, view: View?, position: Int, id: Long) {
    // Get the Cursor
    val cursor: Cursor? = (parent.adapter as? CursorAdapter)?.cursor?.apply {
        // Move to the selected contact
        moveToPosition(position)
        // Get the _ID value
        contactId = getLong(Companion.CONTACT_ID_INDEX)
        // Get the selected LOOKUP KEY
        //contactKey = getString(CONTACT_KEY_INDEX)
        mContactKey = getString(Companion.CONTACT_KEY_INDEX)
        // Create the contact's content Uri
        contactUri = ContactsContract.Contacts.getLookupUri(contactId, mContactKey)
        /*
         * You can use contactUri as the content URI for retrieving
         * the details for a contact.
         */
    }
    val intent = Intent().apply{
        setClass(activity,DetailsActivity::class.java)
        putExtra("contactID",contactId)
        putExtra("mContackKey",mContactKey)
        putExtra("contactUri",contactUri)
    }
    startActivity(intent)
}

If I create the Intent to start the activity as displayed in the guide, I get the compiler error "Inferred type is FragmentActivity?, but context was expected".

I changed then the Intent to either one of the following:

val intent = Intent().apply{
        setClass(requireContext(),DetailsActivity::class.java)
        putExtra("contactID",contactId)
        putExtra("mContackKey",mContactKey)
        putExtra("contactUri",contactUri)
    }
    startActivity(intent)

or

 val intent = Intent().apply{
        context?.let { setClass(it,DetailsActivity::class.java) }
        putExtra("contactID",contactId)
        putExtra("mContackKey",mContactKey)
        putExtra("contactUri",contactUri)
    }
    startActivity(intent)

whit this, I do not get the compiler error, but in the Logcat I see the notice "W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@9dc9013"

Can you please point me to the correct way to instantiate an activity from the onClick method of a ListView inside a Fragment ? Thank you!

On a related note: do you recommend those guides or is their content obsolete ?

Edit: the full fragment class is here

Upvotes: 1

Views: 251

Answers (2)

Tenfour04
Tenfour04

Reputation: 93629

startActivity() is a function in the Context class (of which Activity is a subclass), not of the Fragment class.

So you can make a direct bare call to startActivity() from within the code of a subclass of Context (as any Activity implementation is), but when you are calling it from a Fragment, you have to call it on a context: context.startActivity().

The Fragment.context property is nullable, so you can use requireContext().startActivity(). It won't be null when responding to clicks, so this is safe.

Upvotes: 0

Rizwan
Rizwan

Reputation: 1664

Try below code for opening new activity from fragment :

activity?.let{
    val intent = Intent (it, DetailsActivity::class.java)
    intent.putExtra("contactID",contactId);
    intent.putExtra("mContackKey",mContactKey);
    intent.putExtra("contactUri",contactUri);
    it.startActivity(intent)
}

Upvotes: 1

Related Questions