Kotlin Android yeni Aktivite başlat


106

Android'de başka bir etkinlik başlatmak istiyorum ancak şu hatayı alıyorum:

Lütfen yapıcı çağrısını belirtin; 'Sayfa2' sınıflandırıcısının tamamlayıcı nesnesi yok

Intentsınıfı örnekledikten sonra . Hatayı düzeltmek için ne yapmalıyım? Kodum:

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 o sayfa artık yok.
2018

Yanıtlar:


186

Yazdığımız bir Activityin java'yı başlatmak için Intent(this, Page2.class), temel Contextolarak birinci parametrede ve ikinci parametrede hedef sınıfı tanımlamanız gerekir . IntentKaynak kodundaki yönteme göre -

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

Gördüğünüz gibi Class<?>ikinci parametrede tipe geçmemiz gerekiyor.

Yazarak Intent(this, Page2)dersi geçeceğimizi asla belirtmiyoruz, classkabul edilemez olan türü geçmeye çalışıyoruz .

Kotlin in ::class.javaalternatifi olan kullanın .class. Başlamak için aşağıdaki kodu kullanınActivity

Intent(this, Page2::class.java)

Misal -

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
Neden ::class.javayerine olarak değiştirdiklerine dair bir fikriniz var .classmı? Kotlin yaklaşımı, Java'ya kıyasla alışılmadık derecede karmaşıktır.
Mr-IDE

3
@ Mr-IDE classbir Kotlin döndürür KClass, ancak Android bir Java bekler Class<...>, dolayısıyla .javamülk olur.
kirbyfan64sos

34

Basitçe bir başlayabilirsiniz Activityiçinde KOTLINbu basit yöntemi kullanarak,

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

1
Yeni aktiviteye başlamak için putExtra yöntemini kullanmanıza gerek yoktur.
ShadeToD

@ShadeToD Evet! putExtraYöntem kullanmaya gerek yok . Yeni başlarken değerleri geçmek için ekledimActivity
Gowtham Subramaniam

31

Yeni bir Aktivite başlatmak için,

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

Bu yüzden kodunuzu şu şekilde değiştirin:

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'nın Activity.this :)
leoelstin

12

Genel olarak, BlahActivity::class.javasatır içi reified jenerik bir işlev tanımlayarak parametrenin belirtimini basitleştirebilirsiniz .

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

Çünkü bu yapmanıza izin verir

startActivity(createIntent<Page2>()) 

Veya daha basit

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

Yani şimdi

startActivity<Page2>() 

Kotlin'e acemi olarak, bununla putExtra () 'ların değişken sayısını (veya hiçbirini) nasıl ekersiniz?
2018

1
inline fun <reified T: Activity> Context.createIntent(vararg extras: Pair<String, Any?>) = Intent(this, T::class.java).apply { putExtras(bundleOf(*extras)) }Söylediklerimin yerine kurabilirsiniz ve işe yarayacaktır ( bundleOfandroid-ktx veya anko'dan aldığınızı varsayarsak )
EpicPandaForce

11

Sınıf türünün ikinci argümanını vermelisiniz. Ayrıca aşağıdaki gibi biraz daha derli toplu da yapabilirsiniz.

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

7

Bunu dene

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

6

Bu, kullanıcı adı ve şifreyi metin düzenleme ve amaca göre ayarlamadan aldığım ana faaliyetim

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

Bu, ana faaliyetten değerler almam gereken ikinci faaliyetim

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

Bunun nedeni, Page2sınıfınızın, staticsınıfınızı kullanmak için Java'dakine benzer bir tamamlayıcı nesneye sahip olmamasıdır . Sınıfınızı bir argüman olarak geçirmek için Intentböyle bir şey yapmanız gerekecek

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

4

Aktiviteden aktiviteye

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

Parçadan aktiviteye

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

4

Pekala, bu 2 yolu tüm sonuçların en basiti olarak buldum:

Yol 1:

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

Yol # 2: (Genel bir şekilde)

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

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

örneklem


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

1

Benzer bir sorun yaşadım, başvurumu Kotlin'de yazmaya başladım, faaliyetlerimden birini yeniden yazdıktan sonra herhangi bir sorun olup olmadığını görmek istedim, sorun java dosyasından kotlin'e nasıl niyet göndereceğimi bilmiyordum dosya.

Bu durumda kotlin'de (tamamlayıcı nesne) statik bir işlev oluşturdum, bu işlev bir bağlam (mevcut etkinlikten) alıyor ve kotlin sınıfını (") kullanırken mevcut bağlamı (" java "bağlamı) kullanırken yeni amacı döndürüyor :: class.java ").

İşte kodum:

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

Eğer eklerseniz @JvmStaticsizin için newIntentyöntemin olmadan java onu çağırabilir Companionparçası.
Wirling

0

Detaylar

  • Android Studio 3.1.4
  • Kotlin sürümü: 1.2.60

Adım 1. Uygulama ()

Başvurunuzun bağlamına bağlantı alı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()
    }

}

Adım 2. Yönlendirici nesnesi ekleyin

object Router {
    inline fun <reified T: Activity> start() {
         val context =  MY_APPLICATION_NAME.getAppContext()
         val intent = Intent(context, T::class.java)
         context.startActivity(intent)
    }
}

Kullanım

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

0

Sunmak istediğiniz aktiviteyi kendinize eklemeyi unutmayın AndroidManifest.xml:-) Benim için sorun buydu.


0

Kapsüllemeyi düşünmeye ne dersiniz?

Örneğin:


    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

Uygulamanızda hem Kotlin hem de Java dosyalarını kullanabilirsiniz.

İki dosya arasında geçiş yapmak için, AndroidManifest.xml'de onlara benzersiz <action android: name = "" verdiğinizden emin olun, örneğin:

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

Daha sonra MainActivity.kt'nizde (Kotlin dosyası), Java ile yazılmış bir Aktivite başlatmak için şunu yapın:

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

MainActivityJava.java'nızda (Java dosyası), Kotlin'de yazılmış bir Aktivite başlatmak için şunu yapın:

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

0

Başka bir etkinliğe gitmenin başka bir basit yolu da

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

1
Pls, başkalarının bundan faydalanabilmesi için kodunuzu ve nasıl yardımcı olacağını açıklamayı düşünür.
Amit Verma
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.