Skip to content

Instantly share code, notes, and snippets.

@passsy
Last active March 28, 2023 06:51
Show Gist options
  • Star 39 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save passsy/3e6a12150af02120f8c6c156100277cc to your computer and use it in GitHub Desktop.
Save passsy/3e6a12150af02120f8c6c156100277cc to your computer and use it in GitHub Desktop.
Kotlin extension functions to start a generic Activity
package com.pascalwelsch.extensions
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
/**
* Extensions for simpler launching of Activities
*/
inline fun <reified T : Any> Activity.launchActivity(
requestCode: Int = -1,
options: Bundle? = null,
noinline init: Intent.() -> Unit = {}) {
val intent = newIntent<T>(this)
intent.init()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
startActivityForResult(intent, requestCode, options)
} else {
startActivityForResult(intent, requestCode)
}
}
inline fun <reified T : Any> Context.launchActivity(
options: Bundle? = null,
noinline init: Intent.() -> Unit = {}) {
val intent = newIntent<T>(this)
intent.init()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
startActivity(intent, options)
} else {
startActivity(intent)
}
}
inline fun <reified T : Any> newIntent(context: Context): Intent =
Intent(context, T::class.java)
@samrahimi
Copy link

samrahimi commented Mar 21, 2018

@emoonadev You have to call the extensions from a Context. Here's a simple example of launching an activity when a button is clicked (using Anko layout and helpers). Assumes there is an Activity class called MapActivity in the project and that you've added the extensions Kotlin to your project (get rid of the top line in the gist with the package name and replace with the package name of your app)

Examples:

class AnkoActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        AnkoActivityUI().setContentView(this)
    }

   fun launchOtherActivity() {
       this.launchActivity<OtherActivity>() 
   }
}

class OtherClass {
    fun launchOtherActivity(ctx: Context) {
       ctx.launchActivity<OtherActivity>() 
   }
}

@hendrawd
Copy link

hendrawd commented Aug 8, 2018

you can combine with anko's intentFor also, it will be simpler

Copy link

ghost commented Mar 15, 2019

How about fragments? I suggest slightly improve this functions:

inline fun <reified T : Any> Activity.launchActivity(
    requestCode: Int = -1,
    options: Bundle? = null,
    noinline init: Intent.() -> Unit = {}) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
          startActivityForResult(newIntent<T>(this, init), requestCode, options)
    else
         startActivityForResult(newIntent<T>(this, init), requestCode)
}

inline fun <reified T : Any> Context.launchActivity(
    options: Bundle? = null,
    noinline init: Intent.() -> Unit = {}) {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
          startActivity(newIntent<T>(this, init), options)
    else
         startActivity(newIntent<T>(this, init))
}

@RequiresApi(Build.VERSION_CODES.HONEYCOMB)
inline fun <reified T : Any> Fragment.launchActivity(
    requestCode: Int = -1,
    options: Bundle? = null,
    noinline init: Intent.() -> Unit = {}) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
          startActivityForResult(newIntent<T>(requireContext(), init), requestCode, options)
    else
         startActivityForResult(newIntent<T>(requireContext(), init), requestCode)
}

inline fun <reified T : Any> newIntent(context: Context, noinline init: Intent.() -> Unit = {}): Intent {
    val intent = Intent(context, T::class.java)
    intent.init()
    return  intent
}

@denebchorny
Copy link

Why do you use startActivityForResult instead of startActivity?

IDK, but would it be good to be able to choose which one to use?

For example, one fun launchActivity and another one fun launchActivityForResult.

What do you think? Or is it right to use alwaysstartActivityForResult?

@passsy
Copy link
Author

passsy commented Jul 20, 2020

I use both. If you provide a requestCode it calls startActivityForResult otherwise startActivity

@denebchorny
Copy link

Yep, I did research, and it's funny what I found. StartActivity calls startActivityForResult internally; then, it means that we would say its the same.

public void startActivity(Intent intent, @nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}

@passsy
Copy link
Author

passsy commented Jul 20, 2020

It's important to call the correct method though. startActivity might be overridden or - unlikely - the internal implementation might change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment