Kotlin Android начинает новую деятельность


104

Я хочу начать другое действие на 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

Ответы:


179

Чтобы запустить 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? Подход Kotlin необычайно сложен по сравнению с Java.
Mr-IDE

3
@ 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
this @ Activity совпадает с Java Activity.
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)) }вместо того, что я сказал, и это будет работать (при условии, что у вас есть bundleOfandroid-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

У меня была аналогичная проблема, я начал писать свое приложение на Kotlin, после того, как я переписал одно из своих действий, я хотел увидеть, есть ли какие-либо проблемы, проблема заключалась в том, что я не был уверен, как отправить намерение из 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
  • Версия Kotlin: 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. Добавьте объект Router

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
Пожалуйста, рассмотрите возможность объяснения вашего кода и того, как он может помочь, чтобы другие могли извлечь из этого пользу.
Амит Верма,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.