Kotlin Android bắt đầu Hoạt động mới


102

Tôi muốn bắt đầu một hoạt động khác trên Android nhưng gặp lỗi này:

Vui lòng chỉ định lệnh gọi hàm tạo; trình phân loại 'Trang2' không có đối tượng đồng hành

sau khi khởi tạo Intentlớp. Tôi phải làm gì để sửa lỗi? Mã của tôi:

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 trang đó không tồn tại nữa.
Scre

Câu trả lời:


177

Để bắt đầu một Activitytrong java mà chúng tôi đã viết Intent(this, Page2.class), về cơ bản bạn phải xác định Contexttrong tham số đầu tiên và lớp đích trong tham số thứ hai. Theo Intentphương pháp trong mã nguồn -

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

Như bạn có thể thấy, chúng ta phải truyền Class<?>loại tham số thứ hai.

Bằng cách viết, Intent(this, Page2)chúng tôi không bao giờ chỉ định chúng tôi sẽ vượt qua lớp, chúng tôi đang cố gắng chuyển classloại không được chấp nhận.

Sử dụng ::class.javathay thế .classtrong kotlin. Sử dụng mã dưới đây để bắt đầuActivity

Intent(this, Page2::class.java)

Thí dụ -

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
Bất kỳ ý tưởng tại sao họ thay đổi nó thành ::class.javathay vì .class? Phương pháp Kotlin phức tạp một cách bất thường, so với Java.
Mr-IDE

2
@ Mr-IDE classtrả về một Kotlin KClass, nhưng Android yêu cầu một Java Class<...>, do đó thuộc .javatính này.
kirbyfan64sos

34

Đơn giản chỉ cần bạn có thể bắt đầu một Activitytrong KOTLINbằng cách sử dụng phương pháp đơn giản này,

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

1
Bạn không cần sử dụng phương thức putExtra để bắt đầu hoạt động mới.
ShadeToD

@ShadeToD Vâng! Không cần sử dụng putExtraphương pháp. Tôi chỉ cần thêm nó cho đi giá trị khi bắt đầu mớiActivity
Gowtham Subramaniam

31

Để bắt đầu một Hoạt động mới,

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

Vì vậy, hãy thay đổi mã của bạn thành:

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
@ Hoạt động này tương đương với Activity.this Java :)
leoelstin

12

Nói chung, bạn có thể đơn giản hóa đặc điểm kỹ thuật của tham số BlahActivity::class.javabằng cách xác định một hàm chung được sửa đổi nội tuyến.

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

Bởi vì điều đó cho phép bạn làm

startActivity(createIntent<Page2>()) 

Hoặc thậm chí đơn giản hơn

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

Vì vậy, nó bây giờ

startActivity<Page2>() 

Là một người mới làm quen với kotlin, làm thế nào bạn sẽ đặt một số biến (hoặc không) của putExtra () với số đó?
Scre

1
Bạn có thể thiết lập inline fun <reified T: Activity> Context.createIntent(vararg extras: Pair<String, Any?>) = Intent(this, T::class.java).apply { putExtras(bundleOf(*extras)) }thay vì những gì tôi nói và nó sẽ làm việc (giả sử bạn có bundleOftừ android-ktx hoặc anko)
EpicPandaForce

10

Bạn phải đưa ra đối số thứ hai của loại lớp. Bạn cũng có thể để nó gọn gàng hơn một chút như dưới đây.

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

7

Thử cái này

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

6

Đây là hoạt động chính của tôi, nơi tôi lấy tên người dùng và mật khẩu từ việc chỉnh sửa văn bản và cài đặt cho mục đích

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

Đây là hoạt động thứ hai của tôi mà tôi phải nhận các giá trị từ hoạt động chính

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

Điều này là do Page2lớp của bạn không có đối tượng đồng hành tương tự như statictrong Java để sử dụng lớp của bạn. Để chuyển lớp của bạn làm đối số Intent, bạn sẽ phải làm điều gì đó như thế này

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

4

Từ hoạt động đến hoạt động

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

Từ phân mảnh đến hoạt động

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

4

Tôi thấy 2 cách này là đơn giản nhất trong tất cả các kết quả:

Cách # 1:

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

Cách 2: (Nói một cách chung chung)

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

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

mẫu vật


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

1

Tôi đã gặp sự cố tương tự, tôi bắt đầu viết ứng dụng của mình trong Kotlin, sau khi viết lại một trong các hoạt động của mình, tôi muốn xem có vấn đề gì không, vấn đề là tôi không chắc chắn cách gửi ý định từ tệp java tới kotlin tập tin.

Trong trường hợp này, tôi đã tạo một hàm tĩnh trong kotlin (đối tượng đồng hành), hàm này đang lấy một ngữ cảnh (từ hoạt động hiện tại) và trả về ý định mới trong khi sử dụng ngữ cảnh hiện tại (ngữ cảnh "java") trong khi sử dụng lớp kotlin (" :: class.java ").

Đây là mã của tôi:

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

Nếu bạn thêm @JvmStaticvào newIntentphương thức của mình, bạn có thể gọi nó từ java mà không cần Companionphần này.
Wirling

0

Chi tiết

  • Android Studio 3.1.4
  • Phiên bản Kotlin: 1.2.60

Bước 1. Ứng dụng ()

Nhận liên kết đến bối cảnh của ứng dụng của bạn

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

}

Bước 2. Thêm đối tượng 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)
    }
}

Sử dụng

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

0

Hãy nhớ thêm hoạt động bạn muốn trình bày, cho cả của bạn AndroidManifest.xml:-) Đó là vấn đề đối với tôi.


0

Làm thế nào về điều này để xem xét đóng gói?

Ví dụ:


    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

Bạn có thể sử dụng cả tệp Kotlin và Java trong ứng dụng của mình.

Để chuyển đổi giữa hai tệp, hãy đảm bảo bạn cung cấp cho chúng <action android: name = "" duy nhất trong AndroidManifest.xml, như sau:

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

Sau đó, trong MainActivity.kt (tệp Kotlin) của bạn, để bắt đầu Hoạt động được viết bằng Java, hãy làm như sau:

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

Trong MainActivityJava.java (tệp Java) của bạn, để bắt đầu Hoạt động được viết bằng Kotlin, hãy làm như sau:

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

0

một cách đơn giản khác để điều hướng đến một hoạt động khác là

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

1
Vui lòng xem xét giải thích mã của bạn và nó sẽ giúp ích như thế nào, để những người khác có thể được hưởng lợi từ điều này.
Amit Verma
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.