Kotlin Android iniciar nova atividade


103

Quero iniciar outra atividade no Android, mas recebo este erro:

Especifique a invocação do construtor; classificador 'Page2' não tem um objeto complementar

após instanciar a Intentclasse. O que devo fazer para corrigir o erro? Meu 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 essa página não existe mais.
Tela de

Respostas:


178

Para iniciar um Activityem java que escrevemos Intent(this, Page2.class), basicamente você tem que definir Contextno primeiro parâmetro e a classe de destino no segundo parâmetro. De acordo com o Intentmétodo no código-fonte -

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

Como você pode ver, temos que passar o Class<?>tipo no segundo parâmetro.

Ao escrever Intent(this, Page2), nunca especificamos que passaremos de classe, estamos tentando passar um classtipo que não é aceitável.

Use o ::class.javaque é alternativo .classno kotlin. Use o código abaixo para iniciar o seuActivity

Intent(this, Page2::class.java)

Exemplo -

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
Alguma ideia de por que eles mudaram para em ::class.javavez de .class? A abordagem Kotlin é incomumente complicada, em comparação com Java.
Mr-IDE

2
@ Mr-IDE classretorna um Kotlin KClass, mas o Android espera um Java Class<...>, daí a .javapropriedade.
kirbyfan64sos

34

Simplesmente você pode começar um Activityem KOTLINusando este método simples,

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

1
Você não precisa usar o método putExtra para iniciar uma nova atividade.
ShadeToD

@ShadeToD Sim! Não há necessidade de usar o putExtramétodo. Acabei de adicioná-lo para passar valores ao começar de novoActivity
Gowtham Subramaniam

31

Para iniciar uma nova atividade,

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

Portanto, altere seu código para:

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
esta @ Activity é igual a Activity.this :) do Java
leoelstin

12

Geralmente, você pode simplificar a especificação do parâmetro BlahActivity::class.javadefinindo uma função genérica reificada embutida.

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

Porque isso permite que você faça

startActivity(createIntent<Page2>()) 

Ou ainda mais simples

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

Então é agora

startActivity<Page2>() 

Como novato no kotlin, como você plantaria um número variável (ou nenhum) de putExtra () com isso?
Tela de

1
Você pode configurar em inline fun <reified T: Activity> Context.createIntent(vararg extras: Pair<String, Any?>) = Intent(this, T::class.java).apply { putExtras(bundleOf(*extras)) }vez do que eu disse e vai funcionar (supondo que você tenha bundleOfdo android-ktx ou anko)
EpicPandaForce

10

Você tem que dar o segundo argumento do tipo de classe. Você também pode deixá-lo um pouco mais arrumado como abaixo.

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

7

Tente isto

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

6

Esta é a minha atividade principal, onde pego o nome de usuário e a senha da edição de texto e configuração para a intenção

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 é a minha segunda atividade onde eu tenho que receber os valores da atividade 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

Isso ocorre porque sua Page2classe não tem um objeto companheiro que seja semelhante ao staticJava para usar sua classe. Para passar sua classe como um argumento para Intent, você terá que fazer algo assim

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

4

De atividade para atividade

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

Do fragmento à atividade

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

4

Bem, descobri que essas 2 maneiras são as mais simples de todos os resultados:

Caminho # 1:

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

Forma # 2: (de uma forma genérica)

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

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

amostra


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

1

Eu tive um problema semelhante, comecei a escrever meu aplicativo em Kotlin, depois de reescrever uma de minhas atividades, eu queria ver se havia algum problema, o problema era que eu não tinha certeza de como enviar um intent do arquivo java para kotlin Arquivo.

Neste caso, criei uma função estática em kotlin (objeto companheiro), esta função está obtendo um contexto (da atividade atual) e retornando a nova intenção ao usar o contexto atual (contexto "java") ao usar a classe kotlin (" :: class.java ").

Aqui está o meu 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);

Se você adicionar @JvmStaticao seu newIntentmétodo, poderá chamá-lo de java sem a Companionparte.
Wirling

0

Detalhes

  • Android Studio 3.1.4
  • Versão Kotlin: 1.2.60

Etapa 1. Aplicativo ()

Obtenha um link para o contexto de seu aplicativo

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

}

Etapa 2. Adicionar objeto Roteador

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

Lembre-se de adicionar a atividade que deseja apresentar ao seu AndroidManifest.xmltambém :-) Esse era o problema para mim.


0

Que tal considerar o encapsulamento?

Por exemplo:


    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

Você pode usar arquivos Kotlin e Java em seu aplicativo.

Para alternar entre os dois arquivos, certifique-se de fornecer a eles <action android: name = "" em AndroidManifest.xml, como:

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

Em seguida, em seu MainActivity.kt (arquivo Kotlin), para iniciar uma atividade escrita em Java, faça o seguinte:

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

Em seu MainActivityJava.java (arquivo Java), para iniciar uma Activity escrita em Kotlin, faça o seguinte:

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

0

outra maneira simples de navegar para outra atividade é

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

1
Por favor, considere explicar seu código e como ele ajudaria, para que outros possam se beneficiar disso.
Amit Verma
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.