Kotlin Android开始新活动


102

我想在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

Answers:


177

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

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

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

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

使用::class.java这是另类的.class在科特林。使用以下代码启动您的Activity

Intent(this, Page2::class.java)

范例-

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
知道为什么他们将其::class.java改为.class吗?与Java相比,Kotlin方法异常复杂。
Mr-IDE

2
@ Mr-IDE class返回Kotlin KClass,但是Android需要Java Class<...>,因此是.java属性。
kirbyfan64sos

34

只要你可以启动一个ActivityKOTLIN使用这种简单的方法,

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

1
您不需要使用putExtra方法来启动新活动。
ShadeToD

@ShadeToD是的!无需使用putExtra方法。我刚刚添加了它,以便在开始新的Activity
创建

31

要开始新的活动,

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

12

通常,您可以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)) }而不是我所说的那样,它将起作用(假设您bundleOf来自android-ktx或anko)
EpicPandaForce 18/09/26

10

您必须给出类类型的第二个参数。您也可以像下面这样使它更加整洁。

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

7

试试这个

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

6

这是我的主要活动,我从编辑文本和设置意图中获取用户名和密码

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

4

这是因为您的Page2类没有与staticJava中类似的伴随对象,因此可以使用您的类。要将您的课程作为参数传递给Intent,您必须执行以下操作

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

4

从活动到活动

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

从片段到活动

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

4

好吧,我发现以下两种方法是所有结果中最简单的:

方式1:

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

方式2 :(以通用方式)

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

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

样品


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

1

我遇到了类似的问题,我开始用Kotlin编写应用程序,重写了我的一项活动后,我想看看是否有任何问题,问题是我不确定如何将Java文件中的意图发送到Kotlin。文件。

在这种情况下,我在kotlin(伴侣对象)中创建了一个静态函数,该函数在从当前活动中获取上下文(并从当前活动中获取)并在使用kotlin类(“ java”上下文)时返回新的意图。 :: class.java”)。

这是我的代码:

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

如果您将方法添加@JvmStaticnewIntent方法中,则可以无需任何Companion部分就从Java调用它。
威灵

0

细节

  • Android Studio 3.1.4
  • Kotlin版本:1.2.60

步骤1. Application()

获取链接到您的应用程序的上下文

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

}

步骤2.添加路由器对象

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

用法

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


0

考虑封装如何?

例如:


    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

您可以在应用程序中使用Kotlin和Java文件。

要在两个文件之间切换,请确保在AndroidManifest.xml中为它们提供唯一的<action android:name =“”,如下所示:

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

然后在您的MainActivity.kt(科特林文件)中,启动用Java编写的Activity,请执行以下操作:

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

在您的MainActivityJava.java(Java文件)中,要启动用Kotlin编写的Activity,请执行以下操作:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.