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

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

Tente isto

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

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

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

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

outra maneira simples de navegar para outra atividade é

Intent(this, CodeActivity::class.java).apply {
                    startActivity(this)
                }
Mohamed AbdelraZek
fonte
1
Por favor, considere explicar seu código e como ele ajudaria, para que outros possam se beneficiar disso.
Amit Verma