Kotlin Android inicia una nueva actividad


103

Quiero iniciar otra actividad en Android pero aparece este error:

Especifique la invocación del constructor; el clasificador 'Page2' no tiene un objeto complementario

después de crear una instancia de la Intentclase. ¿Qué debo hacer para corregir el error? Mi código:

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 esa página ya no existe.
Scre

Respuestas:


178

Para iniciar un Activityen Java que escribimos Intent(this, Page2.class), básicamente tienes que definir Contexten el primer parámetro y la clase de destino en el segundo parámetro. Según el Intentmétodo en el código fuente -

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

Como puede ver, tenemos que pasar el Class<?>tipo en el segundo parámetro.

Al escribir Intent(this, Page2), nunca especificamos que vamos a aprobar la clase, estamos tratando de pasar un classtipo que no es aceptable.

Uso ::class.javaalternativo de .classen kotlin. Utilice el siguiente código para iniciar suActivity

Intent(this, Page2::class.java)

Ejemplo -

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
¿Alguna idea de por qué lo cambiaron a en ::class.javalugar de .class? El enfoque de Kotlin es inusualmente complicado, en comparación con Java.
Mr-IDE

2
@ Mr-IDE classdevuelve un Kotlin KClass, pero Android espera un Java Class<...>, de ahí la .javapropiedad.
kirbyfan64sos

34

Simplemente puede iniciar una Activityen KOTLINel uso de este método simple,

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

1
No es necesario utilizar el método putExtra para iniciar una nueva actividad.
ShadeToD

@ShadeToD ¡Sí! No es necesario utilizar el putExtramétodo. Lo acabo de agregar para pasar valores al comenzar de nuevoActivity
Gowtham Subramaniam

31

Para iniciar una nueva actividad,

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

Así que cambia tu código a:

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 es igual a la Activity de
Java.this

12

En general, puede simplificar la especificación del parámetro BlahActivity::class.javadefiniendo una función genérica reificada en línea.

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

Porque eso te deja hacer

startActivity(createIntent<Page2>()) 

O incluso más simple

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

Entonces es ahora

startActivity<Page2>() 

Como novato en kotlin, ¿cómo plantarías un número variable (o ninguno) de putExtra () con eso?
Scre

1
Puede configurar en inline fun <reified T: Activity> Context.createIntent(vararg extras: Pair<String, Any?>) = Intent(this, T::class.java).apply { putExtras(bundleOf(*extras)) }lugar de lo que dije y funcionará (suponiendo que tenga bundleOfdesde android-ktx o anko)
EpicPandaForce

10

Tienes que dar el segundo argumento del tipo de clase. También puedes tenerlo un poco más ordenado como a continuación.

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

7

Prueba esto

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

6

Esta es mi actividad principal en la que tomo el nombre de usuario y la contraseña de editar texto y configurar la intención

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

Esta es mi segunda actividad donde tengo que recibir valores de la actividad principal.

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

Esto se debe a que su Page2clase no tiene un objeto complementario que sea similar al staticde Java, así que use su clase. Para pasar tu clase como argumento Intent, tendrás que hacer algo como esto

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

4

De actividad en actividad

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

Del fragmento a la actividad

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

4

Bueno, encontré estas 2 formas de ser el más simple de todos los resultados:

Camino # 1:

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

Camino # 2: (de manera genérica)

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

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

muestra


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

1

Tuve un problema similar, comencé a escribir mi aplicación en Kotlin, después de reescribir una de mis actividades quería ver si había algún problema, el problema era que no estaba seguro de cómo enviar una intención desde un archivo java a kotlin expediente.

En este caso, creé una función estática en kotlin (objeto complementario), esta función obtiene un contexto (de la actividad actual) y devuelve la nueva intención mientras usa el contexto actual (contexto "java") mientras usa la clase kotlin (" :: class.java ").

Aquí está mi código:

 //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 agrega @JvmStatica su newIntentmétodo, puede llamarlo desde java sin la Companionparte.
Gira el

0

Detalles

  • Android Studio 3.1.4
  • Versión de Kotlin: 1.2.60

Paso 1. Aplicación ()

Obtenga un enlace al contexto de su aplicación

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

}

Paso 2. Agregar objeto de enrutador

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

Uso

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

0

Recuerde agregar la actividad que desea presentar a su AndroidManifest.xmltambién :-) Ese fue el problema para mí.


0

¿Qué tal esto para considerar la encapsulación?

Por ejemplo:


    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

Puede utilizar archivos Kotlin y Java en su aplicación.

Para cambiar entre los dos archivos, asegúrese de darles una <action android: name = "" única en AndroidManifest.xml, así:

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

Luego, en su MainActivity.kt (archivo Kotlin), para iniciar una actividad escrita en Java, haga esto:

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

En su MainActivityJava.java (archivo Java), para iniciar una actividad escrita en Kotlin, haga esto:

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

0

otra forma sencilla de navegar a otra actividad es

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

1
Por favor, considere explicar su código y cómo ayudaría, para que otros puedan beneficiarse de esto.
Amit Verma
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.