使用Kotlin在活动之间进行Android意向处理
In this tutorial, we’ll be discussing Android Intents and implement them using Kotlin in our application.
在本教程中,我们将讨论Android Intent,并在我们的应用程序中使用Kotlin来实现它们。
- What are Intents?什么是意图?
- Types Of Intents?意向类型?
- Using Intents Between Activities在活动之间使用意图
- Sending Data Using Android Intents使用Android Intent发送数据
- Using Parcelable and Serializable to pass objects使用Parcelable和Serializable传递对象
- Creating shorthand intents创建速记意图
Android意图 (Android Intents)
As the name says Intent is something that’s used to perform some action with respect to the flow of the android application. Intents can be used to:
顾名思义,Intent是用于针对android应用程序流程执行某些操作的东西。 意图可用于:
- Starting a new activity and passing some data.开始一个新的活动并传递一些数据。
- Starting Fragments/Communicating between fragments.开始片段/片段之间的通信。
- Start/End service.启动/结束服务。
- Launch activities from a broadcast receiver从广播接收器启动活动
In this tutorial, we’ll be looking mainly at intents to handle activities.
在本教程中,我们将主要研究处理活动的意图。
An intent definition mainly consists of an instance of the current activity. We set the component name which can be:
The fully qualified class name of the activity to be called. This type of Intent is an explicit intent.
An action such as URL, phone number, location. It’ll display all the available applications of those types.
This falls under the implicit intent category.
一个意图定义主要由当前活动的一个实例组成。 我们设置的组件名称可以是:
要调用的活动的全限定类名称。 这种类型的意图是显式意图 。
URL,电话号码,位置之类的操作。 它将显示这些类型的所有可用应用程序。
这属于隐式意图类别。
In Kotlin, following is the way to create an activity.
在Kotlin中,以下是创建活动的方法。
val intent = Intent(this, OtherActivity::class.java)
startActivity(intent)
startActivity
would add OtherActivity
on the activity stack and launch it.
How does our Application, realise which activity is the first to be invoked?
In the AndroidManifest.xml we set the intent filter with the action android.intent.action.MAIN
and category android.intent.category.LAUNCHER
on the first activity to be launched when our application opens.
startActivity
将在活动堆栈上添加OtherActivity
并启动它。
我们的应用程序如何实现首先调用哪个活动?
在AndroidManifest.xml中,我们在应用程序打开时要启动的第一个活动上,通过动作android.intent.action.MAIN
和类别android.intent.category.LAUNCHER
设置了意图过滤器。
finish()
is used to destroy an activity and remove it from the stack.
finish()
用于销毁活动并将其从堆栈中删除。
意图标志 (Intent Flags)
Flags are like options that can be set on intents to customise the launch process.
If you start the same activity everytime, a new instance would be created and added onto the activity stack
To prevent this, you can use the flags:
FLAG_ACTIVITY_SINGLE_TOP
– If set, the activity will not be launched if it is already running at the top of the activity stack.
标志就像可以在意图上设置以自定义启动过程的选项。
如果您每次都启动相同的活动,则会创建一个新实例并将其添加到活动堆栈中
为了防止这种情况,可以使用标志:
FLAG_ACTIVITY_SINGLE_TOP
–如果设置,则如果活动已经在活动堆栈的顶部运行,则不会启动该活动。
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
Similarly using a flag FLAT_ACTIVITY_CLEAR_TOP
would not launch another instance of the activity if it already exists. This flag would clear all the activities above the activity that’s called and set it on the top of the stack.
类似地,使用FLAT_ACTIVITY_CLEAR_TOP
标志不会启动该活动的另一个实例(如果已经存在)。 该标志将清除所调用活动上方的所有活动,并将其设置在堆栈的顶部。
通过意图传递数据 (Passing Data Through Intents)
To pass data onto the new activities we use key value pairs inside the function putExtra
, putStringArrayListExtra
etc.
putExtra generally passes the basic types such as Int, Float, Char, Double, Boolean, String along with
传递数据到新的活动中,我们使用函数内键值对putExtra
, putStringArrayListExtra
等。
putExtra通常会传递基本类型,例如Int,Float,Char,Double,Boolean,String和
val intent = Intent(this, OtherActivity::class.java)
intent.putExtra("keyString", "Androidly String data")
These Extras fields are under the hood wrapped into the Bundle
object which ultimately holds all the data to be passed.
这些Extras字段位于包装到Bundle
对象中的Bundle
对象最终包含所有要传递的数据。
To retrieve the data in the other activity, we need to use the extras
property over the bundles
.
要检索其他活动中的数据,我们需要在bundles
上使用extras
属性。
Retrieving Data in the new Activity
在新活动中检索数据
val bundle: Bundle? = intent.extras
val string: String? = intent.getString("keyString")
val myArray: ArrayList<String>? = intent.getStringArrayList("myArray")
intent
, extras
are equivalent to getIntent()
, getExtras()
in Java.
We’ve used a nullable type Bundle?
to prevent NullPointerExceptions
when not data exists. Similarly, for the data that’s fetched using the keys, we’ve used the nullable types to prevent NPE that can occur when the key is incorrect.
intent
, extras
等效于Java中的getIntent()
和getExtras()
。
我们使用了可为空的Bundle?
类型Bundle?
当不存在数据时防止NullPointerExceptions
。 同样,对于使用密钥获取的数据,我们使用了可为空的类型,以防止密钥不正确时发生NPE。
使用可打包和可序列化的数据 (Using Parcelable and Serializable Data)
Sometimes we need to pass a complete object from one activity to another. It’s not possible to do so unless we implement the Parcelable or Serializable interface.
有时我们需要将一个完整的对象从一个活动传递到另一个活动。 除非我们实现Parcelable或Serializable接口,否则不可能这样做。
Difference between Parcelable and Serializable
可打包和可序列化之间的区别
- Parcelable interface is a part of the Android SDK. Serializable is a standard interface of Java.可打包界面是Android SDK的一部分。 可序列化是Java的标准接口。
- In Parcelable you need to set all of the data you need to pass in a Parcel object and also override the writeToParcel() methods etc. In serializable implementing the interface is sufficient to pass the data.在Parcelable中,您需要设置需要在Parcel对象中传递的所有数据,并覆盖writeToParcel()方法等。在可序列化的实现中,接口足以传递数据。
- Parcelable is faster than Serializable.可打包比可序列化更快。
发送包裹数据 (Sending Parcelable Data)
Kotlin comes up with some handy annotations to save us from overriding the writeToParcel() method to set the data on the Parcelable. Instead, we can use @Parcelize annotation as shown below:
Kotlin提供了一些方便的注释,使我们免于重写writeToParcel()方法来设置Parcelable上的数据。 相反,我们可以使用@Parcelize注释,如下所示:
@Parcelize
data class Student(val name: String = "Anupam",val age: Int = 24
) : Parcelable
Note: Currently in your build.gradle you must add the following code for the @Parcelize annotation to work:
注意:当前,在build.gradle中,您必须添加以下代码以使@Parcelize批注起作用:
android {androidExtensions {experimental = true}
//..
....
}
In your Activity you do:
在您的活动中,您可以执行以下操作:
val student = Student()
val intent = Intent(this, OtherActivity::class.java)
intent.putExtra("studentData", student)
startActivity(intent)
发送可序列化的数据 (Sending Serializable Data)
data class Blog(val name: String = "Androidly", val year: Int = 2018) : Serializableval blog = Blog("a", 1)
val intent = Intent(this, OtherActivity::class.java)
intent.putExtra("blogData", blog as Serializable)
startActivity(intent)
Let’s use over above knowledge in our Android Studio Project.
让我们在我们的Android Studio项目中使用以上知识。
项目结构 (Project Structure)
布局代码 (Layout Code)
The code for the activity_main.xml
layout is given below:
下面给出了activity_main.xml
布局的代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"tools:context=".MainActivity"><Buttonandroid:id="@+id/btnSimpleIntent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="SIMPLE INTENT" /><Buttonandroid:id="@+id/btnSimpleIntentAndData"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="SIMPLE INTENT WITH DATA" /><Buttonandroid:id="@+id/btnParcelableIntent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Parcelable Intent" /><Buttonandroid:id="@+id/btnSerializableIntent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Serializable Intent" /><Buttonandroid:id="@+id/btnBrowserIntent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Browser Intent" /><Buttonandroid:id="@+id/btnMapsIntent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Maps Intent" /><Buttonandroid:id="@+id/btnGenericIntent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Generic Intent" /></LinearLayout>
The code for the activity_other.xml layout is given below:
下面给出了activity_other.xml布局的代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"tools:context=".MainActivity"><TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Intent Data goes here" /></LinearLayout>
活动代码 (Activity Code)
The code for the MainActivity.kt class is given below:
MainActivity.kt类的代码如下:
package net.androidly.androidlyintentsimport android.app.Activity
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.Parcelable
import android.view.View
import android.widget.Toast
import android.widget.Toast.LENGTH_LONG
import kotlinx.android.parcel.Parcelize
import kotlinx.android.synthetic.main.activity_main.*
import java.io.Serializable@Parcelize
data class Student(val name: String = "Anupam",val age: Int = 24
) : Parcelabledata class Blog(val name: String = "Androidly", val year: Int = 2018) : Serializableclass MainActivity : AppCompatActivity(), View.OnClickListener {fun Context.gotoClass(targetType: Class<*>) =ComponentName(this, targetType)fun Context.startActivity(f: Intent.() -> Unit): Unit =Intent().apply(f).run(this::startActivity)inline fun <reified T : Activity> Context.start(noinline createIntent: Intent.() -> Unit = {}) = startActivity {component = gotoClass(T::class.java)createIntent(this)}var arrayList = ArrayList<String>()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)btnSimpleIntent.setOnClickListener(this)btnSimpleIntentAndData.setOnClickListener(this)btnParcelableIntent.setOnClickListener(this)btnSerializableIntent.setOnClickListener(this)btnBrowserIntent.setOnClickListener(this)btnMapsIntent.setOnClickListener(this)btnGenericIntent.setOnClickListener(this)arrayList.add("Androidly")arrayList.add("Android")arrayList.add("Intents")}override fun onClick(v: View?) {when (v?.id) {R.id.btnSimpleIntent -> {val intent = Intent(this, OtherActivity::class.java)startActivity(intent)}R.id.btnSimpleIntentAndData -> {val intent = Intent(this, OtherActivity::class.java)with(intent){putExtra("keyString", "Androidly String data")putStringArrayListExtra("arrayList", arrayList)putExtra("keyBoolean", true)putExtra("keyFloat", 1.2f)}startActivity(intent)}R.id.btnParcelableIntent -> {val student = Student()val intent = Intent(this, OtherActivity::class.java)intent.putExtra("studentData", student)startActivity(intent)}R.id.btnSerializableIntent -> {val blog = Blog("a", 1)val intent = Intent(this, OtherActivity::class.java)intent.putExtra("blogData", blog as Serializable)startActivity(intent)}R.id.btnBrowserIntent -> {val url = "https://www.androidly.net"val uri = Uri.parse(url)val intent = Intent(Intent.ACTION_VIEW, uri)if (intent.resolveActivity(packageManager) != null) {startActivity(intent)} else {Toast.makeText(applicationContext, "No application found", LENGTH_LONG).show()}}R.id.btnMapsIntent -> {val loc = "12.9538477,77.3507442"val addressUri = Uri.parse("geo:0,0?q=" + loc)val intent = Intent(Intent.ACTION_VIEW, addressUri)if (intent.resolveActivity(packageManager) != null) {startActivity(intent)} else {Toast.makeText(applicationContext, "No application found", LENGTH_LONG).show()}}else -> start<OtherActivity> {putExtra("keyString", "Androidly Generic Intent")}}}}
In the above code, we’ve used Buttons for each type of Intent.
We’ve used Kotlin’s with
expression to prevent setting data over the intent
object every time.
Besides, we’ve created three different intents apart from the ones already discussed above.
A browser intent is used to launch the url present in the intent in the browser app.
It uses Intent(Intent.ACTION_VIEW, uri)
.
A location intent is used to launch the lat,lng location in the maps application.
Both of these are implicit intents.
Lastly, we’ve used a generic intent in which we use the Kotlin’s extension functions and lambda expressions to create a shorthand function to launch an intent.
For this we use the following functions:
在上面的代码中,我们对每种Intent类型都使用了Buttons 。
我们使用Kotlin的with
表达式来防止每次都在intent
对象上设置数据。
此外,除了上面已经讨论的目的之外,我们还创建了三种不同的目的。
浏览器意图用于启动浏览器应用程序中意图中存在的URL。
它使用Intent(Intent.ACTION_VIEW, uri)
。
位置意图用于在地图应用程序中启动纬度,经度位置。
两者都是隐含的意图。
最后,我们使用了通用意图,其中我们使用Kotlin的扩展函数和lambda表达式创建速记函数来启动意图。
为此,我们使用以下功能:
fun Context.gotoClass(targetType: Class<*>) =ComponentName(this, targetType)fun Context.startActivity(createIntent: Intent.() -> Unit): Unit =Intent().apply(createIntent).run(this::startActivity)inline fun <reified T : Activity> Context.start(noinline createIntent: Intent.() -> Unit = {}) = startActivity {component = gotoClass(T::class.java)createIntent(this)}
startActivity is an exension function which looks for a higher order function as it’s parameter.
Thanks to this, we can now launch intents in as few lines as:
start<OtherActivity>
startActivity是一个扩展函数,它将寻找更高阶的函数作为其参数。
因此,我们现在可以在以下几行中启动意图:
start<OtherActivity>
The code for the OtherActivity.kt class is given below.
下面给出了OtherActivity.kt类的代码。
package net.androidly.androidlyintentsimport android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_other.*class OtherActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_other)val bundle: Bundle? = intent.extrasbundle?.let {bundle.apply {//Intent with dataval string: String? = getString("keyString")textView.text = stringval myArray: ArrayList<String>? = getStringArrayList("myArray")showToast(message = "MyArrayList size:${myArray?.size}")val arrayList: ArrayList<String>? = getStringArrayList("arrayList")showToast(message = "ArrayList size:${arrayList?.size}")val float: Float? = bundle.get("keyFloat") as Float?var boolean = bundle.get("boolean") as? BooleanshowToast(message = "Float data is:$float")showToast(message = "Boolean data is:$boolean")boolean = bundle.get("keyBoolean") as? BooleanshowToast(message = "Boolean correct key data is:$boolean")}bundle.apply {//Serializable Dataval blog = getSerializable("blogData") as Blog?if (blog != null) {textView.text = "Blog name is ${blog?.name}. Year started: ${blog?.year}"}}bundle.apply {//Parcelable Dataval student: Student? = getParcelable("studentData")if (student != null) {textView.text = "Name is ${student?.name}. Age: ${student?.age}"}}}}private fun showToast(context: Context = applicationContext, message: String, duration: Int = Toast.LENGTH_SHORT) {if (!message.contains("null"))Toast.makeText(context, message, duration).show()}
}
We’ve used let
and apply
to handle nullable types and prevent doing bundle.field in every line.
我们使用let
和apply
处理可空类型并防止在每一行中执行bundle.field。
The output of the above application in action is given below:
上面应用程序的输出如下:
This brings an end to this tutorial on Android intents in Kotlin. You can download the project from the link below.
这结束了有关Kotlin中Android意图的教程。 您可以从下面的链接下载项目。
翻译自: https://www.journaldev.com/37763/android-intent-handling-between-activities-using-kotlin
使用Kotlin在活动之间进行Android意向处理相关推荐
- android实例教程_活动之间的Android意向处理示例教程
android实例教程 In our last Android Tutorial, we discussed the Android Hello World Application. In this ...
- android 活动传递数据,如何在Android应用程序的“活动”之间传递数据?
我有一种情况,在通过登录页面登录后,每个activity上都会有一个退出button . 点击sign-out ,我将传递已登录用户的session id以便退出. 谁能指导我如何使session i ...
- android 活动切换动画,android – 在使用ChangeImageTransform共享元素转换的两个活动之间动画化ImageView...
要在具有共享元素的两个活动之间进行屏幕转换动画, 您可以阅读 this article并按照上述步骤: Enable window content transitions in your theme. ...
- Android学习之碎片与活动之间的通信
一.碎片虽然是嵌入在活动中显示的,但是碎片和活动都是各自存在不同的类当中的,并没有什么明显的方式来直接进行通信的.那么如果要在活动中调用碎片里的方法,在碎片里调用活动的方法,一个碎片调用另一碎片的方法 ...
- kotlin 垂直滚动_在Android的Kotlin中检测点击或滚动
kotlin 垂直滚动 Build a responsive UI that shows or hides the toolbar in response to user clicks whilst ...
- 坑中速记整理! 使用 kotlin 写第一个 ReactNative Android 模块
Kotlin 和 Swift, 两大新宠! 借 ReactNative 熟悉下 kotlin 的用法,不料掉坑里面了.昨晚花了大半夜,趁这会儿思路清晰,把涉及到的一些关键信息,迅速整理下. 最佳的使用 ...
- 自发和诱发电生理活动之间的动态关系
文章来源于微信公众号(茗创科技),欢迎有兴趣的朋友搜索关注. 自发的神经活动波动已被证明会影响感知.认知和行为结果的变化.然而,这些波动形成刺激诱发的神经活动的复杂电生理机制仍有待进一步探索.自发和诱 ...
- Android Google Map实例 - 在地图和卫星图之间切换(Android mapview)
之前讲述的例子中显示的 为地图模式,如何你想使用类似google earth的卫星图模式显示,如何操作? 在android上将变得非常简单: 增加两个Button按钮和两个对应的Button.OnCl ...
- Android:《Kotlin 从零到精通Android开发》读书笔记
原文发布在我的公众号:CnPeng 所有文章将优先发布于公众号,随后才会更新简书. 前前后后整整四十天,终于利用非工作时间读完了 欧阳燊(shen)写的 <Kotlin 从零到精通Android ...
最新文章
- 指定域的名称或安全标识(SID)与该域的信任信息不一致
- bzoj2111,P2606-[ZJOI2010]排列计数【Lucas,组合计数,dp】
- 服务器被一堆系统登录_WIN10做天高服务器客户端登录出现“操作系统原因无法登录”...
- 通过数据扩充来扩展数据集
- matlab给图像加云,matlab怎么给图像加雾
- gof 设计模式 java_javaSE中的GOF设计模式
- 新东方 词根词缀 excel_14张图搞定高中英语词汇常见词缀词根!
- Apache Tomcat漏洞总结
- android测试用例编写
- 炸了炸了~翻译器中的王者,科大讯飞翻译器2.0横空出世!| 钛空智慧星球推荐...
- EXCEL VBA批量下载URL链接地址图片、URL链接地址图片转为图片
- 【算法:leetcode】双指针:142. 环形链表 II 633. 平方数之和
- Java web实时进度条整个系统共用(如java上传、下载进度条、导入、导出excel进度条等)...
- for...in 和 for...of
- 985大学计算机考研报录比,68:1!这所985率先公布2020考研报录比,部分专业数据惊人...
- 物联网的物流企业信息集成综合管理平台,主要有哪些特征?
- 『论文笔记』TensorFlow1.6.0+Keras 2.1.5+Python3.5+Yolov3训练自己的数据集!
- 开票系统导出的OFD文档如何转换PDF格式?
- iOS开发 ---- 其他控件,弹窗,滑块,菊花,步进,分段等
- 阿里云备案管局审核需要几天能通过?