Kotlin Android startet neue Aktivität

101

Ich möchte eine andere Aktivität auf Android starten, erhalte jedoch folgende Fehlermeldung:

Bitte geben Sie den Konstruktoraufruf an. Der Klassifikator 'Seite2' hat kein Begleitobjekt

nach dem Instanziieren der IntentKlasse. Was soll ich tun, um den Fehler zu beheben? Mein Code:

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
quelle
@BakaWaii diese Seite existiert nicht mehr.
Scre

Antworten:

176

Um ein Activityin Java zu starten, das wir geschrieben haben Intent(this, Page2.class), müssen Sie grundsätzlich Contextim ersten Parameter und die Zielklasse im zweiten Parameter definieren. Nach IntentMethode im Quellcode -

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

Wie Sie sehen, müssen wir den Class<?>zweiten Parameter eingeben.

Durch das Schreiben geben Intent(this, Page2)wir niemals an, dass wir die Klasse bestehen werden. Wir versuchen, einen classTyp zu übergeben, der nicht akzeptabel ist.

Verwenden Sie ::class.javadie Alternative zu .classKotlin. Verwenden Sie den folgenden Code, um Ihre zu startenActivity

Intent(this, Page2::class.java)

Beispiel -

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
quelle
4
Irgendeine Idee, warum sie es geändert haben, ::class.javaanstatt .class? Der Kotlin-Ansatz ist im Vergleich zu Java ungewöhnlich kompliziert.
Mr-IDE
2
@ Mr-IDE classgibt einen Kotlin zurück KClass, aber Android erwartet ein Java Class<...>, daher die .javaEigenschaft.
kirbyfan64sos
34

Mit dieser einfachen Methode können Sie einfach ein ActivityIn starten.KOTLIN

val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("key", value)
startActivity(intent)
Gowtham Subramaniam
quelle
1
Sie müssen die putExtra-Methode nicht verwenden, um neue Aktivitäten zu starten.
ShadeToD
@ShadeToD Ja! Keine Notwendigkeit, putExtraMethode zu verwenden . Ich habe es gerade hinzugefügt, um Werte zu übergeben, wenn ich neu Activity
anfange
31

Um eine neue Aktivität zu starten,

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

Ändern Sie also Ihren Code in:

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
quelle
2
this @ Activity ist gleich Java Activity.this :)
Leoelstin
12

Sie können die Angabe des Parameters im Allgemeinen vereinfachen, BlahActivity::class.javaindem Sie eine generische Inline-Funktion definieren.

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

Weil du das kannst

startActivity(createIntent<Page2>()) 

Oder noch einfacher

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

So ist es jetzt

startActivity<Page2>() 
EpicPandaForce
quelle
Wie würden Sie als Neuling bei kotlin eine variable Anzahl (oder keine) von putExtra () damit pflanzen?
Scre
1
Sie könnten inline fun <reified T: Activity> Context.createIntent(vararg extras: Pair<String, Any?>) = Intent(this, T::class.java).apply { putExtras(bundleOf(*extras)) }anstelle von dem, was ich gesagt habe, einrichten und es wird funktionieren (vorausgesetzt, Sie haben bundleOfvon Android-Ktx oder Anko)
EpicPandaForce
9

Sie müssen das zweite Argument des Klassentyps angeben. Sie können es auch ein bisschen aufgeräumter haben, wie unten.

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

Versuche dies

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

Dies ist meine Hauptaktivität, bei der ich den Benutzernamen und das Passwort von der Textbearbeitung und der Einstellung zur Absicht nehme

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

Dies ist meine zweite Aktivität, bei der ich Werte von der Hauptaktivität erhalten muss

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

Dies liegt daran, dass Ihre Page2Klasse kein Begleitobjekt hat, das staticJava ähnelt , um Ihre Klasse zu verwenden. Um Ihre Klasse als Argument zu übergeben Intent, müssen Sie so etwas tun

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

Von Aktivität zu Aktivität

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

Vom Fragment zur Aktivität

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

Nun, ich fand diese beiden Möglichkeiten die einfachsten aller Ergebnisse:

Weg Nr. 1:

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

Weg Nr. 2: (Allgemein)

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

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

Stichprobe

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

Ich hatte ein ähnliches Problem. Ich begann meine Bewerbung in Kotlin zu schreiben. Nachdem ich eine meiner Aktivitäten umgeschrieben hatte, wollte ich sehen, ob es irgendwelche Probleme gibt. Das Problem war, dass ich nicht sicher war, wie ich eine Absicht von einer Java-Datei an Kotlin senden sollte Datei.

In diesem Fall habe ich eine statische Funktion in Kotlin (Begleitobjekt) erstellt. Diese Funktion ruft einen Kontext (aus der aktuellen Aktivität) ab und gibt die neue Absicht zurück, während der aktuelle Kontext ("Java" -Kontext) verwendet wird, während die Kotlin-Klasse (") verwendet wird. :: class.java ").

Hier ist mein Code:

 //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
quelle
Wenn Sie @JvmStaticIhrer newIntentMethode hinzufügen , können Sie sie ohne das CompanionTeil aus Java aufrufen .
Wirling
0

Einzelheiten

  • Android Studio 3.1.4
  • Kotlin-Version: 1.2.60

Schritt 1. Anwendung ()

Holen Sie sich einen Link zum Kontext Ihrer Anwendung

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

}

Schritt 2. Router-Objekt hinzufügen

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

Verwendung

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

Denken Sie daran, die Aktivität, die Sie präsentieren möchten, auch zu Ihrer hinzuzufügen AndroidManifest.xml:-) Das war das Problem für mich.

Nicolai Harbo
quelle
0

Wie wäre es damit, die Kapselung in Betracht zu ziehen?

Beispielsweise:


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

Sie können sowohl Kotlin- als auch Java-Dateien in Ihrer Anwendung verwenden.

Um zwischen den beiden Dateien zu wechseln, stellen Sie sicher, dass Sie ihnen in AndroidManifest.xml eine eindeutige <action android: name = "" geben, wie folgt:

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

Gehen Sie dann in Ihrer MainActivity.kt (Kotlin-Datei) folgendermaßen vor, um eine in Java geschriebene Aktivität zu starten:

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

Gehen Sie in Ihrer MainActivityJava.java (Java-Datei) folgendermaßen vor, um eine in Kotlin geschriebene Aktivität zu starten:

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

Eine andere einfache Möglichkeit, zu einer anderen Aktivität zu navigieren, ist

Intent(this, CodeActivity::class.java).apply {
                    startActivity(this)
                }
Mohamed AbdelraZek
quelle
1
Bitte überlegen Sie, Ihren Code zu erklären und wie er helfen würde, damit andere davon profitieren können.
Amit Verma