Reputation: 1945
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)
}
}
Upvotes: 150
Views: 258832
Reputation: 10625
To start an Activity
in java we wrote Intent(this, Page2.class)
, basically you have to define Context
in first parameter and destination class in second parameter. According to Intent
method in source code -
public Intent(Context packageContext, Class<?> cls)
As you can see we have to pass Class<?>
type in second parameter.
By writing Intent(this, Page2)
we never specify we are going to pass class, we are trying to pass class
type which is not acceptable.
Use ::class.java
which is alternative of .class
in kotlin. Use below code to start your Activity
Intent(this, Page2::class.java)
Example -
// start your activity by passing the intent
startActivity(Intent(this, Page2::class.java).apply {
// you can add values(if any) to pass to the next class or avoid using `.apply`
putExtra("keyIdentifier", value)
})
Upvotes: 247
Reputation: 1144
extension Functions
fun Activity.showToast(message: String, toastLength: Int){
//LENGTH_SHORT = 0;
//LENGTH_LONG = 1;
Toast.makeText(this, message, toastLength).show()
}
fun Fragment.showToast(message: String, toastLength: Int){
//LENGTH_SHORT = 0;
//LENGTH_LONG = 1;
Toast.makeText(requireContext(), message, toastLength).show()
}
fun Context.launchActivity(
cls: Class<*>,
flags: Int = 0,
intentTransformer: Intent.() -> Unit = {}
) {
val intent = Intent(this, cls).apply {
addFlags(flags)
intentTransformer()
}
this.startActivity(intent)
}
in an activity call
showToast("message to be shown", 1)
in a fragment call
showToast("message to be shown", 1)
start activity from any place
launchActivity(MainActivity::class.java, Intent.FLAG_ACTIVITY_NEW_TASK)
Upvotes: 1
Reputation: 199
fun Context.launchActivity(
cls: Class<*>,
flags: Int = 0,
intentTransformer: Intent.() -> Unit = {}
) {
val intent = Intent(this, cls).apply {
addFlags(flags)
intentTransformer()
}
this.startActivity(intent)
}
Upvotes: 4
Reputation: 2809
another simple way of navigating to another activity is
Intent(this, CodeActivity::class.java).apply {
startActivity(this)
}
Upvotes: 4
Reputation: 11267
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);
Upvotes: 0
Reputation: 551
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
}
}
Upvotes: 3
Reputation: 2070
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))
}
Upvotes: 10
Reputation: 3478
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)
Upvotes: 63
Reputation: 845
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);
Upvotes: 1
Reputation: 31
val intentAct: Intent = Intent(this@YourCurrentActivity, TagentActivity::class.java)
startActivity(intentAct)
Upvotes: 1
Reputation: 1169
Remember to add the activity you want to present, to your AndroidManifest.xml
too :-) That was the issue for me.
Upvotes: 0
Reputation: 3258
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)
}
Upvotes: 38
Reputation: 25294
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>()
Upvotes: 0
Reputation: 81539
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>()
Upvotes: 16
Reputation: 4959
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)
Upvotes: 5
Reputation: 4064
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)
})
Upvotes: 16
Reputation: 361
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")
}
Upvotes: 8
Reputation: 368
Try this
val intent = Intent(this, Page2::class.java)
startActivity(intent)
Upvotes: 11
Reputation: 7427
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)
Upvotes: 7