Home > Enterprise >  How do I start activity B from fragment A in Kotlin?
How do I start activity B from fragment A in Kotlin?

Time:10-05

com.udacity.shoestore:

MainActivity ShoeListActivity2 ShoeListFragment2 WelcomeFragment InstructionsFragment

Layout:

activity_main activity_shoe_list2 fragment_instructions fragment_login fragment_shoe_list2 fragment_welcome

manifest file:

    <activity
        android:name=".ShoeListActivity2"
        android:exported="false"
        android:label="@string/title_activity_shoe_list2"
        android:theme="@style/AppTheme.NoActionBar.NoActionBar" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
        </intent-filter>
    </activity>
    ...
    <activity
        android:name=".MainActivity"
        android:exported="true"
        android:screenOrientation="unspecified">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

From the instructions fragment, I am trying to start the ShoeListActivity fragment but it crashes. While trying to debug, it tries to load up the MainActivity.

First I tried

    binding.listShoesButton.setOnClickListener {
        val intent=Intent(this@InstructionsFragment, this@ShoeListActivity2)
        startActivity(intent)    
    } 

but the IDE wouldn't accept it as an intent.

Then I found out that it would like Intent to be something like

    val intent = Intent(ACTION_MAIN)
    startActivity(intent, ShoeListActivity2::class.java)

but it didn't like that either. So I tried

    binding.listShoesButton.setOnClickListener {
        val intent = Intent(context, ShoeListActivity2::class.java)
        startActivity(intent)
    }

But that just ended up trying to go to the main activity before crashing.

What is the right way to start the ShoeListActivity2 from the InstructionsFragment?

Thanks. PS: I also tried

    binding.listShoesButton.setOnClickListener {
        val intent = Intent(this@InstructionsFragment, ShoeListActivity2::class.java)
        startActivity(intent)
    }

but the editor flagged this as an error as "Intent" was underlined in red.

CodePudding user response:

You will need to get Context of the parent Activity, Because Fragment doesn't have its own Context

You can do something like this:

val intent = Intent (getActivity(), ShoeListActivity2::class.java)
getActivity().startActivity(intent)

CodePudding user response:

your trying for following code is almost correct

binding.listShoesButton.setOnClickListener {
    val intent = Intent(context, ShoeListActivity2::class.java)
    startActivity(intent)
}

but here "context" is nullable object which IDE would be giving error as Intent's constructor params requires Context to be not Null. So ideally we need to pass context with null safety. We can do it in following 2 ways:

1: Using null safety using let scope

binding.listShoesButton.setOnClickListener {
    context?.let{
       val intent = Intent(it, ShoeListActivity2::class.java)
       startActivity(intent)
    }        
}

2: Using in-built requiredContext or requireActivity function with try-catch

binding.listShoesButton.setOnClickListener {
    try {
        val intent = Intent(requireActivity(), ShoeListActivity2::class.java)
        startActivity(intent)
    } catch(e : IllegalStateException){
    }
}
  • Related