Kotlin Android запустить нову активність


103

Я хочу запустити ще одну діяльність на 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

Відповіді:


178

Щоб запустити Activityin java, про яку ми писали Intent(this, Page2.class), в основному вам потрібно визначити Contextперший параметр і клас призначення в другому параметрі. Відповідно до Intentметоду у вихідному коді -

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

Як бачите, нам потрібно передати Class<?>тип у другому параметрі.

Пишучи, Intent(this, Page2)ми ніколи не вказуємо, що ми збираємось пройти клас, ми намагаємось передати classтип, який не є прийнятним.

Використання, ::class.javaяке є альтернативою .classв kotlin. Використовуйте код нижче, щоб розпочати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.
Mr-IDE

2
@ Mr-IDE classповертає Kotlin KClass, але Android очікує Java Class<...>, отже, .javaвластивість.
kirbyfan64sos

34

Просто ви можете почати Activityв KOTLINза допомогою цього методу простий,

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

1
Вам не потрібно використовувати метод putExtra, щоб розпочати нову діяльність.
ShadeToD

@ShadeToD Так! Не потрібно використовувати putExtraметод. Я щойно додав його для передачі значень при запуску новогоActivity
Gowtham Subramaniam

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
це @ Activity дорівнює Activity
Java.this

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

10

Ви повинні дати другий аргумент класу типу. Ви також можете зробити це трохи більш охайним, як показано нижче.

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


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

Ну, я знайшов ці 2 способи бути найпростішими з усіх результатів:

Шлях №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

У мене була подібна проблема, я почав писати свою заявку в Котліні, після того, як переписав одне зі своїх занять, я хотів перевірити, чи є якісь проблеми, проблема полягала в тому, що я не був впевнений, як надіслати намір з файлу Java на Kotlin файл.

У цьому випадку я створив статичну функцію в kotlin (об'єкт-супутник), ця функція отримує контекст (з поточної активності) і повертає новий намір під час використання поточного контексту ("java" контекст) під час використання класу kotlin (" :: 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);

Якщо ви додасте @JvmStaticдо свого newIntentметоду, ви можете викликати його з Java без Companionчастини.
Wirling

0

Деталі

  • Android Studio 3.1.4
  • Версія Котліна: 1.2.60

Крок 1. Застосування ()

Отримайте посилання на контекст вашої програми

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

Не забудьте додати діяльність, яку ви хочете презентувати, до своєї AndroidManifest.xmlтеж :-) Це було проблемою для мене.


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 у своїй програмі.

Щоб переключатися між двома файлами, обов’язково надайте їм унікальний <action android: name = "" в AndroidManifest.xml, наприклад:

            <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 (файл Kotlin), щоб запустити Діяльність, написану на Java, зробіть наступне:

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

У вашому MainActivityJava.java (файл Java), щоб запустити Діяльність, написану на Kotlin, виконайте наступне:

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

0

ще одним простим способом переходу до іншої діяльності є

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

1
Будь ласка, розгляньте пояснення вашого коду та як це допомогло б, щоб інші могли отримати від цього користь.
Amit Verma
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.