Kotlin Android memulai Aktivitas baru

104

Saya ingin memulai aktivitas lain di Android tetapi saya mendapatkan kesalahan ini:

Harap tentukan permintaan konstruktor; classifier 'Page2' tidak memiliki objek pendamping

setelah membuat instance Intentkelas. Apa yang harus saya lakukan untuk memperbaiki kesalahan tersebut? Kode saya:

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
sumber
@BakaWaii halaman itu tidak ada lagi.
Scre

Jawaban:

179

Untuk memulai Activitydi java yang kami tulis Intent(this, Page2.class), pada dasarnya Anda harus mendefinisikan Contextdi parameter pertama dan kelas tujuan di parameter kedua. Menurut Intentmetode dalam kode sumber -

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

Seperti yang Anda lihat, kita harus memasukkan Class<?>tipe dalam parameter kedua.

Dengan menulis Intent(this, Page2)kami tidak pernah menentukan kami akan lulus kelas, kami mencoba untuk mengirimkan classjenis yang tidak dapat diterima.

Gunakan ::class.javayang merupakan alternatif .classdi kotlin. Gunakan kode di bawah ini untuk memulaiActivity

Intent(this, Page2::class.java)

Contoh -

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
sumber
4
Tahu mengapa mereka mengubahnya menjadi ::class.javabukan .class? Pendekatan Kotlin sangat rumit, dibandingkan dengan Java.
Mr-IDE
3
@ Mr-IDE classmengembalikan Kotlin KClass, tetapi Android mengharapkan Java Class<...>, karena itulah .javapropertinya.
kirbyfan64sos
34

Cukup Anda dapat memulai Activitydi KOTLINdengan menggunakan metode sederhana ini,

val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("key", value)
startActivity(intent)
Gowtham Subramaniam
sumber
1
Anda tidak perlu menggunakan metode putExtra untuk memulai aktivitas baru.
ShadeToD
@ShadeToD Ya! Tidak perlu menggunakan putExtrametode. Saya baru saja menambahkannya untuk nilai kelulusan saat memulai yang baruActivity
Gowtham Subramaniam
31

Untuk memulai Aktivitas baru,

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

Jadi ubah kode Anda menjadi:

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
sumber
2
ini @ Aktivitas sama dengan Java's Activity.this :)
leoelstin
12

Anda biasanya dapat menyederhanakan spesifikasi parameter BlahActivity::class.javadengan menentukan fungsi generik yang direifikasi sebaris.

inline fun <reified T: Activity> Context.createIntent() =
    Intent(this, T::class.java)

Karena itu memungkinkan Anda melakukannya

startActivity(createIntent<Page2>()) 

Atau bahkan lebih sederhana

inline fun <reified T: Activity> Activity.startActivity() {
    startActivity(createIntent<T>()) 
} 

Jadi sekarang

startActivity<Page2>() 
EpicPandaForce
sumber
Sebagai pemula di kotlin, bagaimana Anda akan menanam nomor variabel (atau tidak ada) dari putExtra () dengan itu?
Scre
1
Anda dapat mengatur inline fun <reified T: Activity> Context.createIntent(vararg extras: Pair<String, Any?>) = Intent(this, T::class.java).apply { putExtras(bundleOf(*extras)) }alih - alih apa yang saya katakan dan itu akan berfungsi (dengan asumsi Anda memiliki bundleOfdari android-ktx atau anko)
EpicPandaForce
10

Anda harus memberikan argumen kedua untuk tipe kelas. Anda juga bisa membuatnya sedikit lebih rapi seperti di bawah ini.

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

Coba ini

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

Ini adalah aktivitas utama saya di mana saya mengambil nama pengguna dan kata sandi dari edit teks dan pengaturan ke maksud

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

Ini adalah aktivitas kedua saya di mana saya harus menerima nilai dari aktivitas utama

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

Ini karena Page2kelas Anda tidak memiliki objek pendamping yang mirip dengan staticdi Java sehingga untuk menggunakan kelas Anda. Untuk melewatkan kelas Anda sebagai argumen Intent, Anda harus melakukan sesuatu seperti ini

val changePage = Intent(this, Page2::class.java)
Alf Moh
sumber
4

Dari aktivitas ke aktivitas

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

Dari fragmen ke aktivitas

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

Nah, menurut saya 2 cara ini menjadi yang paling sederhana dari semua hasil:

Cara # 1:

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

Cara # 2: (Dengan cara yang umum)

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

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

Sampel

Saadat Sayem
sumber
1
val intentAct: Intent = Intent(this@YourCurrentActivity, TagentActivity::class.java)
startActivity(intentAct)
Ashish Patel
sumber
1

Saya memiliki masalah serupa, saya mulai menulis aplikasi saya di Kotlin, setelah saya menulis ulang salah satu aktivitas saya, saya ingin melihat apakah ada masalah, masalahnya adalah saya tidak yakin bagaimana cara mengirim maksud dari file java ke kotlin mengajukan.

Dalam hal ini saya membuat fungsi statis di kotlin (objek pendamping), fungsi ini mendapatkan konteks (dari aktivitas saat ini) dan mengembalikan maksud baru saat menggunakan konteks saat ini (konteks "java") saat menggunakan kelas kotlin (" :: class.java ").

Ini kode saya:

 //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
sumber
Jika Anda menambahkan @JvmStaticke newIntentmetode Anda, Anda dapat memanggilnya dari java tanpa Companionbagian.
Wirling
0

Detail

  • Android Studio 3.1.4
  • Versi Kotlin: 1.2.60

Langkah 1. Aplikasi ()

Dapatkan tautan ke konteks aplikasi Anda

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

}

Langkah 2. Tambahkan objek 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)
    }
}

Pemakaian

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

Ingatlah untuk menambahkan aktivitas yang ingin Anda tampilkan, ke Anda AndroidManifest.xmljuga :-) Itu adalah masalah saya.

Nicolai Harbo
sumber
0

Bagaimana dengan ini untuk mempertimbangkan enkapsulasi?

Sebagai contoh:


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

Anda dapat menggunakan file Kotlin dan Java dalam aplikasi Anda.

Untuk beralih di antara dua file, pastikan Anda memberinya <action android: name = "" yang unik di AndroidManifest.xml, seperti ini:

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

Kemudian di MainActivity.kt (file Kotlin) Anda, untuk memulai Aktivitas yang ditulis di Java, lakukan ini:

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

Di MainActivityJava.java (file Java) Anda, untuk memulai Aktivitas yang ditulis di Kotlin, lakukan ini:

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

cara sederhana lain untuk menavigasi ke aktivitas lain adalah

Intent(this, CodeActivity::class.java).apply {
                    startActivity(this)
                }
Mohamed AbdelraZek
sumber
1
Mohon pertimbangkan untuk menjelaskan kode Anda dan bagaimana itu akan membantu, sehingga orang lain dapat memperoleh manfaat dari ini.
Amit Verma