Kotlin Android commence une nouvelle activité


103

Je souhaite démarrer une autre activité sur Android mais j'obtiens cette erreur:

Veuillez spécifier l'invocation du constructeur; le classificateur 'Page2' n'a pas d'objet compagnon

après avoir instancié la Intentclasse. Que dois-je faire pour corriger l'erreur? Mon code:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun buTestUpdateText2 (view: View) {
        val changePage = Intent(this, Page2) 
        // Error: "Please specify constructor invocation; 
        // classifier 'Page2' does not have a companion object"

        startActivity(changePage)
    }

}

@BakaWaii cette page n'existe plus.
Scre

Réponses:


178

Pour démarrer un Activityen java que nous avons écrit Intent(this, Page2.class), vous devez essentiellement définir Contextdans le premier paramètre et la classe de destination dans le deuxième paramètre. Selon la Intentméthode dans le code source -

 public Intent(Context packageContext, Class<?> cls)

Comme vous pouvez le voir, nous devons passer le Class<?>type dans le deuxième paramètre.

En écrivant, Intent(this, Page2)nous ne spécifions jamais que nous allons passer la classe, nous essayons de passer le classtype qui n'est pas acceptable.

Utilisez ::class.javaqui est une alternative à .classdans kotlin. Utilisez le code ci-dessous pour démarrer votreActivity

Intent(this, Page2::class.java)

Exemple -

val intent = Intent(this, NextActivity::class.java)
// To pass any data to next activity
intent.putExtra("keyIdentifier", value)
// start your next activity
startActivity(intent)

4
Une idée pourquoi ils l'ont changé au ::class.javalieu de .class? L'approche Kotlin est inhabituellement compliquée par rapport à Java.
Mr-IDE

2
@ Mr-IDE classrenvoie un Kotlin KClass, mais Android attend un Java Class<...>, d'où la .javapropriété.
kirbyfan64sos le

34

Vous pouvez simplement démarrer un Activityin KOTLINen utilisant cette méthode simple,

val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("key", value)
startActivity(intent)

1
Vous n'avez pas besoin d'utiliser la méthode putExtra pour démarrer une nouvelle activité.
ShadeToD

@ShadeToD Ouais! Pas besoin d'utiliser la putExtraméthode. Je viens de l'ajouter pour passer des valeurs lors du démarrage de nouveauActivity
Gowtham Subramaniam

31

Pour démarrer une nouvelle activité,

startActivity(Intent(this@CurrentClassName,RequiredClassName::class.java)

Alors changez votre code en:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun buTestUpdateText2 (view: View) {
        startActivity(Intent(this@MainActivity,ClassName::class.java))

        // Also like this 

        val intent = Intent(this@MainActivity,ClassName::class.java)
        startActivity(intent)
    }

2
this @ Activity est égal à Java's Activity.this :)
leoelstin

12

Vous pouvez généralement simplifier la spécification du paramètre BlahActivity::class.javaen définissant une fonction générique réifiée en ligne.

inline fun <reified T: Activity> Context.createIntent() =
    Intent(this, T::class.java)

Parce que ça te laisse faire

startActivity(createIntent<Page2>()) 

Ou encore plus simple

inline fun <reified T: Activity> Activity.startActivity() {
    startActivity(createIntent<T>()) 
} 

Alors c'est maintenant

startActivity<Page2>() 

En tant que débutant en kotlin, comment planteriez-vous un nombre variable (ou aucun) de putExtra () avec cela?
Scre

1
Vous pouvez configurer au inline fun <reified T: Activity> Context.createIntent(vararg extras: Pair<String, Any?>) = Intent(this, T::class.java).apply { putExtras(bundleOf(*extras)) }lieu de ce que j'ai dit et cela fonctionnera (en supposant que vous ayez bundleOfd'Android-ktx ou d'anko)
EpicPandaForce

10

Vous devez donner le deuxième argument de type classe. Vous pouvez également l'avoir un peu plus rangé comme ci-dessous.

startActivity(Intent(this, Page2::class.java).apply {
    putExtra("extra_1", value1)
    putExtra("extra_2", value2)
    putExtra("extra_3", value3)
})

7

Essaye ça

val intent = Intent(this, Page2::class.java)
startActivity(intent)

6

C'est mon activité principale où je prends le nom d'utilisateur et le mot de passe de modifier le texte et le paramètre à l'intention

class MainActivity : AppCompatActivity() {
val userName = null
val password = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
    val intent = Intent(this@MainActivity,SecondActivity::class.java);
    var userName = username.text.toString()
    var password = password_field.text.toString()
    intent.putExtra("Username", userName)
    intent.putExtra("Password", password)
    startActivity(intent);
 }
}

C'est ma deuxième activité où je dois recevoir des valeurs de l'activité principale

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
var strUser: String = intent.getStringExtra("Username")
var strPassword: String = intent.getStringExtra("Password")
user_name.setText("Seelan")
passwor_print.setText("Seelan")
}

4

Cela est dû au fait que votre Page2classe n'a pas d'objet compagnon similaire à celui staticde Java afin d'utiliser votre classe. Pour passer votre classe en argument Intent, vous devrez faire quelque chose comme ça

val changePage = Intent(this, Page2::class.java)

4

De l'activité à l'activité

val intent = Intent(this, YourActivity::class.java)
startActivity(intent)

Du fragment à l'activité

val intent = Intent(activity, YourActivity::class.java)
startActivity(intent)

4

Eh bien, j'ai trouvé que ces 2 façons sont les plus simples de tous les résultats:

Voie n ° 1:

accoun_btn.setOnClickListener {
            startActivity(Intent(this@MainActivity, SecondActivity::class.java))
        }

Voie n ° 2: (de manière générique)

    accoun_btn.setOnClickListener {
        startActivity<SecondActivity>(this)
    }

    private inline fun <reified T> startActivity(context: Context) {
            startActivity(Intent(context, T::class.java))
        }

échantillon


1
val intentAct: Intent = Intent(this@YourCurrentActivity, TagentActivity::class.java)
startActivity(intentAct)

1

J'ai eu un problème similaire, j'ai commencé à écrire mon application dans Kotlin, après avoir réécrit l'une de mes activités, je voulais voir s'il y avait des problèmes, le problème était que je ne savais pas comment envoyer une intention du fichier java à kotlin fichier.

Dans ce cas, j'ai créé une fonction statique dans kotlin (objet compagnon), cette fonction obtient un contexte (à partir de l'activité actuelle) et renvoie la nouvelle intention tout en utilisant le contexte actuel (contexte "java") tout en utilisant la classe kotlin (" :: class.java ").

Voici mon code:

 //this code will be in the kotlin activity - SearchActivity
 companion object {

    fun newIntent(context: Context): Intent {
        return Intent(context, SearchActivity::class.java)
    }
}

    //this is how you call SearchActivity from MainActivity.java
Intent searchIntent = SearchActivity.Companion.newIntent(this);
startActivity(searchIntent);

Si vous ajoutez @JvmStaticà votre newIntentméthode, vous pouvez l'appeler depuis java sans la Companionpartie.
Wirling

0

Détails

  • Android Studio 3.1.4
  • Version Kotlin: 1.2.60

Étape 1. Application ()

Obtenez un lien vers le contexte de votre application

class MY_APPLICATION_NAME: Application() {

    companion object {
        private lateinit var instance: MY_APPLICATION_NAME
        fun getAppContext(): Context = instance.applicationContext
    }

    override fun onCreate() {
        instance = this
        super.onCreate()
    }

}

Étape 2. Ajouter un objet Routeur

object Router {
    inline fun <reified T: Activity> start() {
         val context =  MY_APPLICATION_NAME.getAppContext()
         val intent = Intent(context, T::class.java)
         context.startActivity(intent)
    }
}

Usage

// You can start activity from any class: form Application, from any activity, from any fragment and other  
Router.start<ANY_ACTIVITY_CLASS>()

0

N'oubliez pas d'ajouter l'activité que vous souhaitez présenter, à la vôtre AndroidManifest.xmlaussi :-) C'était le problème pour moi.


0

Pourquoi ne pas envisager l'encapsulation?

Par exemple:


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_contents)

        val title = intent.getStringExtra(EXTRA_TITLE) ?: EXTRA_TITLE_DEFAULT

        supportFragmentManager.beginTransaction()
            .add(R.id.frame_layout_fragment, ContentsFragment.newInstance())
            .commit()
    }

    // Omit...

    companion object {

        private const val EXTRA_TITLE = "extra_title"
        private const val EXTRA_TITLE_DEFAULT = "No title"

        fun newIntent(context: Context, title: String): Intent {
            val intent = Intent(context, ContentsActivity::class.java)
            intent.putExtra(EXTRA_TITLE, title)
            return intent
        }
    }

0

Vous pouvez utiliser à la fois des fichiers Kotlin et Java dans votre application.

Pour basculer entre les deux fichiers, assurez-vous de leur donner une <action android: name = "" unique dans AndroidManifest.xml, comme ceci:

            <activity android:name=".MainActivityKotlin">
                <intent-filter>
                    <action android:name="com.genechuang.basicfirebaseproject.KotlinActivity"/>
                    <category android:name="android.intent.category.DEFAULT" />
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity
                android:name="com.genechuang.basicfirebaseproject.MainActivityJava"
                android:label="MainActivityJava" >
                <intent-filter>
                    <action android:name="com.genechuang.basicfirebaseproject.JavaActivity" />
                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </activity>

Ensuite, dans votre MainActivity.kt (fichier Kotlin), pour démarrer une activité écrite en Java, procédez comme suit:

       val intent = Intent("com.genechuang.basicfirebaseproject.JavaActivity")
        startActivity(intent)

Dans votre MainActivityJava.java (fichier Java), pour démarrer une activité écrite en Kotlin, procédez comme suit:

       Intent mIntent = new Intent("com.genechuang.basicfirebaseproject.KotlinActivity");
        startActivity(mIntent);

0

un autre moyen simple de naviguer vers une autre activité est

Intent(this, CodeActivity::class.java).apply {
                    startActivity(this)
                }

1
Veuillez envisager d'expliquer votre code et comment cela aiderait, afin que d'autres puissent en profiter.
Amit Verma le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.