Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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)
@emoonadev

This comment has been minimized.

Copy link

emoonadev commented Mar 16, 2018

this work: startActivity(Intent(this, AddUserActivity::class.java))
this no work: launchActivity<AddUserActivity> { }

Why not work:

android.content.ActivityNotFoundException: Unable to find explicit activity class {com.emoonadev.gestionclientkotlin/int}; have you declared this activity in your AndroidManifest.xml?
                                                                                       at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1932)
                                                                                       at android.app.Instrumentation.execStartActivity(Instrumentation.java:1615)
                                                                                       at android.app.Activity.startActivityForResult(Activity.java:4472)
                                                                                       at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
                                                                                       at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:67)
                                                                                       at com.emoonadev.gestionclientkotlin.Activities.MainActivity.onOptionsItemSelected(MainActivity.kt:45)
                                                                                       at android.app.Activity.onMenuItemSelected(Activity.java:3435)
                                                                                       at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:368)
                                                                                       at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:195)
                                                                                       at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108)
                                                                                       at com.android.tools.profiler.support.event.WindowProfilerCallback.onMenuItemSelected(WindowProfilerCallback.java:133)
                                                                                       at android.support.v7.app.AppCompatDelegateImplV9.onMenuItemSelected(AppCompatDelegateImplV9.java:674)
                                                                                       at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
                                                                                       at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)
                                                                                       at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973)
                                                                                       at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:963)
                                                                                       at android.support.v7.widget.ActionMenuView.invokeItem(ActionMenuView.java:624)
                                                                                       at android.support.v7.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:150)
                                                                                       at android.view.View.performClick(View.java:6256)
                                                                                       at android.view.View$PerformClick.run(View.java:24701)
                                                                                       at android.os.Handler.handleCallback(Handler.java:789)
                                                                                       at android.os.Handler.dispatchMessage(Handler.java:98)
                                                                                       at android.os.Looper.loop(Looper.java:164)
                                                                                       at android.app.ActivityThread.main(ActivityThread.java:6541)
                                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                                       at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

My manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.emoonadev.gestionclientkotlin">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".Activities.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".Activities.AddUserActivity"
            android:parentActivityName=".Activities.MainActivity" />
        <activity android:name=".Activities.ProductsActivity"></activity>
    </application>

</manifest>
@emoonadev

This comment has been minimized.

Copy link

emoonadev commented Mar 16, 2018

can you send me an example of a project that will use it that I can see why it does not work?
My mail: emoonadev@gmail.com

@samrahimi

This comment has been minimized.

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

This comment has been minimized.

Copy link

hendrawd commented Aug 8, 2018

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

@ghost

This comment has been minimized.

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
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.