Kotlin Android 启动新 Activity
Posted
技术标签:
【中文标题】Kotlin Android 启动新 Activity【英文标题】:Kotlin Android start new Activity 【发布时间】:2018-01-13 01:28:37 【问题描述】:我想在 android 上开始另一个活动,但出现此错误:
请指定构造函数调用;分类器“Page2”没有伴随对象
在实例化 Intent
类之后。我应该怎么做才能纠正错误?我的代码:
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 该页面已不存在。 在将 Java 应用程序转换为 Kotlin 时出现同样的错误。必须添加依赖项。 IDE实际上是在警告我。但我也在这里找到了答案***.com/questions/34144392/… 【参考方案1】:要在java中启动Activity
,我们编写了Intent(this, Page2.class)
,基本上你必须在第一个参数中定义Context
,在第二个参数中定义目标类。根据源码中的Intent
方法——
public Intent(Context packageContext, Class<?> cls)
如您所见,我们必须在第二个参数中传递Class<?>
类型。
通过写Intent(this, Page2)
,我们从未指定我们将通过类,我们试图通过class
类型,这是不可接受的。
在 kotlin 中使用 ::class.java
替代 .class
。使用以下代码启动您的Activity
Intent(this, Page2::class.java)
例子-
val intent = Intent(this, NextActivity::class.java)
// To pass any data to next activity
intent.putExtra("keyIdentifier", value)
// start your next activity
startActivity(intent)
【讨论】:
知道为什么他们将其更改为::class.java
而不是 .class
吗?与 Java 相比,Kotlin 方法异常复杂。
@Mr-IDE class
返回 Kotlin KClass
,但 Android 需要 Java Class<...>
,因此需要 .java
属性。【参考方案2】:
只需使用这个简单的方法,您就可以在KOTLIN
中启动一个Activity
,
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("key", value)
startActivity(intent)
【讨论】:
你不需要使用 putExtra 方法来开始新的活动。 @ShadeToD 是的!无需使用putExtra
方法。我刚刚添加它是为了在开始新的Activity
时传递值【参考方案3】:
要开始一个新的活动,
startActivity(Intent(this@CurrentClassName,RequiredClassName::class.java)
所以把你的代码改成:
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)
【讨论】:
this@Activity 等于 Java 的 Activity.this :) 您忘记在 startActivity(Intent(this@CurrentClassName,RequiredClassName::class.java) 中添加结尾 ')'【参考方案4】:您通常可以通过定义内联具体化的泛型函数来简化参数BlahActivity::class.java
的规范。
inline fun <reified T: Activity> Context.createIntent() =
Intent(this, T::class.java)
因为这样可以让你做
startActivity(createIntent<Page2>())
甚至更简单
inline fun <reified T: Activity> Activity.startActivity()
startActivity(createIntent<T>())
现在是这样
startActivity<Page2>()
【讨论】:
作为 kotlin 的新手,您将如何使用它植入可变数量(或没有)的 putExtra()? 你可以设置inline fun <reified T: Activity> Context.createIntent(vararg extras: Pair<String, Any?>) = Intent(this, T::class.java).apply putExtras(bundleOf(*extras))
而不是我说的,它会起作用(假设你有来自android-ktx或anko的bundleOf
)【参考方案5】:
你必须给出类类型的第二个参数。你也可以让它更整洁一点,如下所示。
startActivity(Intent(this, Page2::class.java).apply
putExtra("extra_1", value1)
putExtra("extra_2", value2)
putExtra("extra_3", value3)
)
【讨论】:
干净多了?我现在正在改变我所有的意图以匹配这种格式【参考方案6】:试试这个
val intent = Intent(this, Page2::class.java)
startActivity(intent)
【讨论】:
【参考方案7】:嗯,我发现这两种方法是所有结果中最简单的:
方式#1:
accoun_btn.setOnClickListener
startActivity(Intent(this@MainActivity, SecondActivity::class.java))
方式#2:(通用方式)
accoun_btn.setOnClickListener
startActivity<SecondActivity>(this)
private inline fun <reified T> startActivity(context: Context)
startActivity(Intent(context, T::class.java))
【讨论】:
【参考方案8】:这是我的主要活动,我从编辑文本中获取用户名和密码并设置为意图
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);
这是我的第二个活动,我必须从主要活动中接收值
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")
【讨论】:
【参考方案9】:这是因为您的 Page2
类没有类似于 Java 中的 static
的伴随对象,因此要使用您的类。要将你的类作为参数传递给Intent
,你必须做这样的事情
val changePage = Intent(this, Page2::class.java)
【讨论】:
【参考方案10】:从活动到活动
val intent = Intent(this, YourActivity::class.java)
startActivity(intent)
从片段到活动
val intent = Intent(activity, YourActivity::class.java)
startActivity(intent)
【讨论】:
【参考方案11】:另一种导航到另一个活动的简单方法是
Intent(this, CodeActivity::class.java).apply
startActivity(this)
【讨论】:
请考虑解释您的代码以及它将如何提供帮助,以便其他人可以从中受益。【参考方案12】:fun Context.launchActivity(
cls: Class<*>,
flags: Int = 0,
intentTransformer: Intent.() -> Unit =
)
val intent = Intent(this, cls).apply
addFlags(flags)
intentTransformer()
this.startActivity(intent)
【讨论】:
没有任何解释的代码转储很少有帮助。 Stack Overflow 是关于学习的,而不是提供 sn-ps 来盲目复制和粘贴。请edit您的问题并解释它如何比 OP 提供的更好。见How to Answer。 对我来说它就像手套一样,让我试着解释一下。在创建这样的函数时,您使用的是先进且有益的 kotlin 技术,这种技术的名称是扩展函数。下面我举个例子:【参考方案13】:val intentAct: Intent = Intent(this@YourCurrentActivity, TagentActivity::class.java)
startActivity(intentAct)
【讨论】:
【参考方案14】:我有一个类似的问题,我开始在 Kotlin 中编写我的应用程序,在我重写了我的一个活动之后,我想看看是否有任何问题,问题是我不确定如何从 java 发送意图文件到 kotlin 文件。
在这种情况下,我在 kotlin(伴随对象)中创建了一个静态函数,该函数在使用 kotlin 的同时使用当前上下文(“java”上下文)获取上下文(从当前活动)并返回新意图类(“::class.java”)。
这是我的代码:
//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);
【讨论】:
如果您将@JvmStatic
添加到您的newIntent
方法中,您可以在没有Companion
部分的情况下从java 调用它。【参考方案15】:
这样考虑封装怎么样? 例如:
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
【讨论】:
【参考方案16】:详情
Android Studio 3.1.4 Kotlin 版本:1.2.60步骤 1.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()
步骤 2. 添加路由器对象
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>()
【讨论】:
【参考方案17】:记得将你想要展示的活动添加到你的AndroidManifest.xml
:-) 这对我来说是个问题。
【讨论】:
【参考方案18】:您可以在应用程序中同时使用 Kotlin 和 Java 文件。
要在两个文件之间切换,请确保在 AndroidManifest.xml 中为它们提供唯一的
<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>
然后在您的 MainActivity.kt(Kotlin 文件)中,要启动一个用 Java 编写的 Activity,请执行以下操作:
val intent = Intent("com.genechuang.basicfirebaseproject.JavaActivity")
startActivity(intent)
在您的 MainActivityJava.java(Java 文件)中,要启动一个用 Kotlin 编写的 Activity,请执行以下操作:
Intent mIntent = new Intent("com.genechuang.basicfirebaseproject.KotlinActivity");
startActivity(mIntent);
【讨论】:
【参考方案19】:扩展功能
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)
在活动调用中
showToast("message to be shown", 1)
在片段调用中
showToast("message to be shown", 1)
从任何地方开始活动
launchActivity(MainActivity::class.java, Intent.FLAG_ACTIVITY_NEW_TASK)
Kotlin Extension function
【讨论】:
以上是关于Kotlin Android 启动新 Activity的主要内容,如果未能解决你的问题,请参考以下文章