Kotlin Android启动新的Activity。

144

我想在Android上启动另一个活动,但是我遇到了这个错误:

请指定构造函数调用;分类器“Page2”没有伴生对象

在实例化Intent类之后。我该怎么做才能纠正这个错误?我的代码:

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,该页面已经不存在了。 - Scre
在将Java应用程序转换为Kotlin时遇到了相同的错误。 必须添加依赖项。 IDE实际上正在警告我。 但我也在这里找到了答案 https://dev59.com/XlsX5IYBdhLWcg3wLM7K - JonR85
19个回答

240

为了在Java中启动一个Activity,我们会编写Intent(this, Page2.class),基本上你需要在第一个参数中定义Context,在第二个参数中定义目标类。根据源代码中的Intent方法 -

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

正如您所看到的,我们必须在第二个参数中传递Class<?>类型。

通过编写Intent(this, Page2),我们从未指定我们将要传递的是类,而是试图传递不可接受的class类型。

在kotlin中,使用::class.java作为.class的替代方法。使用以下代码启动您的Activity

Intent(this, Page2::class.java)

示例 -

// start your activity by passing the intent
startActivity(Intent(this, Page2::class.java).apply {
    // you can add values(if any) to pass to the next class or avoid using `.apply`
    putExtra("keyIdentifier", value)
})

8
为什么他们将其更改为::class.java而不是.class?与Java相比,Kotlin的方法异常复杂。 - Mr-IDE
8
@Mr-IDE class 返回 Kotlin 的 KClass,但 Android 需要一个 Java 的 Class<...>,因此需要使用 .java 属性。 - kirbyfan64sos

58

您可以使用这个简单的方法在KOTLIN中启动一个Activity

只需使用此简单方法即可:

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

3
启动新活动时不需要使用putExtra方法。 - ShadeToD
1
@ShadeToD 是的!不需要使用 putExtra 方法。我只是在启动新的 Activity 时添加了它来传递值。 - Gowtham Subramaniam

37

要开始一个新的活动,

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

所以请将您的代码更改为:

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 等同于 Java 的 Activity.this :) - leoelstin
你忘记在startActivity(Intent(this@CurrentClassName,RequiredClassName::class.java)中添加一个结尾的')'了。 - coderGtm
为什么要使用 this@MainActivity 而不是只用 this?我以为 this 总是指当前活动!! - C.F.G

16
通常可以通过定义一个内联的具体化泛型函数来简化参数BlahActivity::class.java的规范。
inline fun <reified T: Activity> Context.createIntent() =
    Intent(this, T::class.java)

因为这样可以让您实现
startActivity(createIntent<Page2>()) 

甚至更简单
inline fun <reified T: Activity> Activity.startActivity() {
    startActivity(createIntent<T>()) 
} 

所以现在它是

startActivity<Page2>() 

作为Kotlin的新手,您将如何使用putExtra()种植变量数量(或没有)? - Scre
1
你可以使用 inline fun <reified T: Activity> Context.createIntent(vararg extras: Pair<String, Any?>) = Intent(this, T::class.java).apply { putExtras(bundleOf(*extras)) } 来代替我之前说的方法,这样就能正常工作了(假设你已经导入了 android-ktx 或 anko 中的 bundleOf)。 - EpicPandaForce

16

你必须提供第二个参数的类类型。你也可以像以下这样稍微整理一下。

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

非常干净,我现在正在修改所有意图以匹配这个格式 - JamTheMan

11

试一下这个

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

10

我发现以下两种方法是最简单的:

方法1:

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

第二种方式:(通用方法)

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

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

sample


8
这是我的主要活动,我从编辑文本中获取用户名和密码,并将它们设置到意图中。
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);
 }
}

这是我的第二个活动,我需要从主活动接收值。
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")
}

7
这是因为您的Page2类没有一个伴生对象,类似于Java中的static,所以要使用您的类。如果要将您的类作为参数传递给Intent,您需要这样做。
val changePage = Intent(this, Page2::class.java)

5

从一个活动到另一个活动

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

从片段到活动

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接