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

}
J Adonai Dagdag
fuente
@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)
Rahul
fuente
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)
Gowtham Subramaniam
fuente
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)
    }
leoelstin
fuente
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>() 
EpicPandaForce
fuente
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)
})
Adib Faramarzi
fuente
7

Prueba esto

val intent = Intent(this, Page2::class.java)
startActivity(intent)
Boris
fuente
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")
}
Bharat Vasoya
fuente
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)
Alf Moh
fuente
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)
Masum
fuente
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

Saadat Sayem
fuente
1
val intentAct: Intent = Intent(this@YourCurrentActivity, TagentActivity::class.java)
startActivity(intentAct)
Ashish Patel
fuente
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);
Anton Makov
fuente
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>()
Vasily Bodnarchuk
fuente
0

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

Nicolai Harbo
fuente
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
        }
    }
libliboom
fuente
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);
Gene
fuente
0

otra forma sencilla de navegar a otra actividad es

Intent(this, CodeActivity::class.java).apply {
                    startActivity(this)
                }
Mohamed AbdelraZek
fuente
1
Por favor, considere explicar su código y cómo ayudaría, para que otros puedan beneficiarse de esto.
Amit Verma