Kotlin Android เริ่มกิจกรรมใหม่


106

ฉันต้องการเริ่มกิจกรรมอื่นบน 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

คำตอบ:


186

ในการเริ่มต้นActivityใน 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? แนวทาง 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
กิจกรรม @ นี้เท่ากับกิจกรรมของ Java นี่ :)
leoelstin

12

โดยทั่วไปคุณสามารถลดความซับซ้อนของข้อกำหนดของพารามิเตอร์ได้BlahActivity::class.javaโดยการกำหนดฟังก์ชัน reified generic แบบอินไลน์

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

11

คุณต้องให้อาร์กิวเมนต์ที่สองของประเภทคลาส นอกจากนี้คุณยังสามารถจัดให้เป็นระเบียบเรียบร้อยมากขึ้นเช่นด้านล่าง

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คลาสของคุณไม่มีอ็อบเจ็กต์ร่วมซึ่งคล้ายกับstaticใน Java เพื่อใช้คลาสของคุณ ในการผ่านชั้นเรียนของคุณเป็นข้อโต้แย้ง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 หลังจากที่ฉันเขียนกิจกรรมของฉันใหม่ฉันต้องการดูว่ามีปัญหาหรือไม่ปัญหาคือฉันไม่แน่ใจว่าจะส่ง Intent จากไฟล์ 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.2

ขั้นตอนที่ 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.