I want to start another activity on Android but I get this error:
Please specify constructor invocation; classifier 'Page2' does not have a companion object
after instantiating the Intent
class. What should I do to correct the error? My 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)
}
}
This question is related to
android
kotlin
android-intent
android-activity
Get link to the context of you application
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()
}
}
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>()
How about this to consider encapsulation?
For example:
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
}
}
This is my main activity where i take the username and password from edit text and setting to the intent
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);
}
}
This is my second activity where i have to receive values from the main activity
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")
}
Simply you can start an Activity
in KOTLIN
by using this simple method,
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("key", value)
startActivity(intent)
You can use both Kotlin and Java files in your application.
To switch between the two files, make sure you give them unique < action android:name="" in AndroidManifest.xml, like so:
<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>
Then in your MainActivity.kt (Kotlin file), to start an Activity written in Java, do this:
val intent = Intent("com.genechuang.basicfirebaseproject.JavaActivity")
startActivity(intent)
In your MainActivityJava.java (Java file), to start an Activity written in Kotlin, do this:
Intent mIntent = new Intent("com.genechuang.basicfirebaseproject.KotlinActivity");
startActivity(mIntent);
Well, I found these 2 ways to be the simplest of all outcomes:
Way #1:
accoun_btn.setOnClickListener {
startActivity(Intent(this@MainActivity, SecondActivity::class.java))
}
Way#2: (In a generic way)
accoun_btn.setOnClickListener {
startActivity<SecondActivity>(this)
}
private inline fun <reified T> startActivity(context: Context) {
startActivity(Intent(context, T::class.java))
}
To start a new Activity ,
startActivity(Intent(this@CurrentClassName,RequiredClassName::class.java)
So change your code to :
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)
}
Remember to add the activity you want to present, to your AndroidManifest.xml
too :-) That was the issue for me.
Try this
val intent = Intent(this, Page2::class.java)
startActivity(intent)
You have to give the second argument of class type. You can also have it a little bit more tidy like below.
startActivity(Intent(this, Page2::class.java).apply {
putExtra("extra_1", value1)
putExtra("extra_2", value2)
putExtra("extra_3", value3)
})
I had a similar issue, I started to write my application in Kotlin, after I rewrote one of my activities I wanted to see if there are any issues, the problem was that I was not sure how to send an intent from java file to kotlin file.
In this case I created a static function in kotlin (companion object), this function is getting a context (from the current activity) and returning the new intent while using the current context ("java" context) while using the kotlin class ("::class.java").
Here is my 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);
From activity to activity
val intent = Intent(this, YourActivity::class.java)
startActivity(intent)
From fragment to activity
val intent = Intent(activity, YourActivity::class.java)
startActivity(intent)
This is because your Page2
class doesn't have a companion object which is similar to static
in Java so to use your class. To pass your class as an argument to Intent
, you will have to do something like this
val changePage = Intent(this, Page2::class.java)
val intentAct: Intent = Intent(this@YourCurrentActivity, TagentActivity::class.java)
startActivity(intentAct)
You can generally simplify the specification of the parameter BlahActivity::class.java
by defining an inline reified generic function.
inline fun <reified T: Activity> Context.createIntent() =
Intent(this, T::class.java)
Because that lets you do
startActivity(createIntent<Page2>())
Or even simpler
inline fun <reified T: Activity> Activity.startActivity() {
startActivity(createIntent<T>())
}
So it's now
startActivity<Page2>()
another simple way of navigating to another activity is
Intent(this, CodeActivity::class.java).apply {
startActivity(this)
}
Source: Stackoverflow.com