Kotlin Android avvia una nuova attività


103

Voglio iniziare un'altra attività su Android ma ricevo questo errore:

Si prega di specificare la chiamata del costruttore; il classificatore "Pagina2" non ha un oggetto associato

dopo aver istanziato la Intentclasse. Cosa devo fare per correggere l'errore? Il mio codice:

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 quella pagina non esiste più.
Scre il

Risposte:


178

Per avviare un Activityjava che abbiamo scritto Intent(this, Page2.class), in pratica devi definire Contextnel primo parametro e la classe di destinazione nel secondo parametro. Secondo il Intentmetodo nel codice sorgente -

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

Come puoi vedere dobbiamo passare il Class<?>tipo nel secondo parametro.

Scrivendo Intent(this, Page2)non specifichiamo mai che passeremo la classe, stiamo cercando di passare un classtipo che non è accettabile.

Usa ::class.javaun'alternativa a .classin kotlin. Usa il codice sottostante per avviare il tuoActivity

Intent(this, Page2::class.java)

Esempio -

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
Qualche idea sul perché l'hanno cambiato in ::class.javainvece di .class? L'approccio Kotlin è insolitamente complicato, rispetto a Java.
Mr-IDE

2
@ Mr-IDE classrestituisce un Kotlin KClass, ma Android si aspetta un Java Class<...>, da cui la .javaproprietà.
kirbyfan64sos

34

Semplicemente è possibile avviare un Activityin KOTLINutilizzando questo metodo semplice,

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

1
Non è necessario utilizzare il metodo putExtra per iniziare una nuova attività.
ShadeToD

@ShadeToD Yeah! Non c'è bisogno di usare il putExtrametodo. L'ho appena aggiunto per il passaggio di valori quando si inizia un nuovoActivity
Gowtham Subramaniam

31

Per iniziare una nuova attività,

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

Quindi cambia il tuo codice in:

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 è uguale a Java's Activity.this :)
leoelstin

12

In genere è possibile semplificare la specifica del parametro BlahActivity::class.javadefinendo una funzione generica reificata in linea.

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

Perché questo ti permette di farlo

startActivity(createIntent<Page2>()) 

O anche più semplice

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

Quindi è adesso

startActivity<Page2>() 

Come principiante di kotlin, come pianteresti un numero variabile (o nessuno) di putExtra () con quello?
Scre il

1
Potresti impostare inline fun <reified T: Activity> Context.createIntent(vararg extras: Pair<String, Any?>) = Intent(this, T::class.java).apply { putExtras(bundleOf(*extras)) }invece di quello che ho detto e funzionerà (supponendo che tu abbia bundleOfda android-ktx o anko)
EpicPandaForce

10

Devi fornire il secondo argomento di tipo classe. Puoi anche averlo un po 'più ordinato come sotto.

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

7

Prova questo

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

6

Questa è la mia attività principale in cui prendo il nome utente e la password dal testo di modifica e l'impostazione all'intento

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);
 }
}

Questa è la mia seconda attività in cui devo ricevere valori dall'attività 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

Questo perché la tua Page2classe non ha un oggetto compagno simile a staticJava, quindi per usare la tua classe. Per passare la lezione come argomento a Intent, dovrai fare qualcosa del genere

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

4

Dall'attività all'attività

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

Dal frammento all'attività

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

4

Bene, ho trovato questi 2 modi per essere il più semplice di tutti i risultati:

Modo # 1:

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

Modo # 2: (in modo generico)

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

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

campione


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

1

Ho avuto un problema simile, ho iniziato a scrivere la mia applicazione in Kotlin, dopo aver riscritto una delle mie attività volevo vedere se ci sono problemi, il problema era che non ero sicuro di come inviare un intento dal file java a kotlin file.

In questo caso ho creato una funzione statica in kotlin (oggetto compagno), questa funzione sta ottenendo un contesto (dall'attività corrente) e restituisce il nuovo intento mentre si utilizza il contesto corrente (contesto "java") mentre si utilizza la classe kotlin (" :: class.java ").

Ecco il mio codice:

 //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);

Se aggiungi @JvmStatical tuo newIntentmetodo puoi chiamarlo da java senza la Companionparte.
Wirling

0

Dettagli

  • Android Studio 3.1.4
  • Versione Kotlin: 1.2.60

Passaggio 1. Applicazione ()

Ottieni il collegamento al contesto della tua applicazione

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()
    }

}

Passaggio 2. Aggiungi oggetto Router

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

Utilizzo

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

0

Ricordati di aggiungere l'attività che vuoi presentare anche alla tua AndroidManifest.xml:-) Questo era il problema per me.


0

Che ne dici di considerare l'incapsulamento?

Per esempio:


    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

Puoi utilizzare sia Kotlin che file Java nella tua applicazione.

Per passare da un file all'altro, assicurati di fornire loro <action android: name = "" in AndroidManifest.xml, in questo modo:

            <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>

Quindi nel tuo MainActivity.kt (file Kotlin), per avviare un'attività scritta in Java, fai questo:

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

Nel tuo MainActivityJava.java (file Java), per avviare un'attività scritta in Kotlin, fai questo:

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

0

un altro modo semplice per passare a un'altra attività è

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

1
Pls considera di spiegare il tuo codice e come potrebbe aiutare, in modo che altri possano trarne beneficio.
Amit Verma
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.