android布局,使用Kotlin在活動之間進行Android意向處理

 2023-11-19 阅读 28 评论 0

摘要: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?

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:

android布局, 顧名思義,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.

Android10使用? 一個意圖定義主要由當前活動的一個實例組成。 我們設置的組件名稱可以是:
要調用的活動的全限定類名稱。 這種類型的意圖是顯式意圖
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.

java調用kotlin方法。 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.

Android10, 標志就像可以在意圖上設置以自定義啟動過程的選項。
如果您每次都啟動相同的活動,則會創建一個新實例并將其添加到活動堆棧中
為了防止這種情況,可以使用標志:
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

android-intent-put-extra-types IntArray…. etc.

Android。 傳遞數據到新的活動中,我們使用函數內鍵值對putExtraputStringArrayListExtra等。
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.

android kotlin、 要檢索其他活動中的數據,我們需要在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.

android contentprovider。 intentextras等效于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

kotlin協程, 可打包和可序列化之間的區別

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

我們使用letapply處理可空類型并防止在每一行中執行bundle.field。

The output of the above application in action is given below:

android-intent-output

上面應用程序的輸出如下:

This brings an end to this tutorial on Android intents in Kotlin. You can download the project from the link below.

這結束了有關Kotlin中Android意圖的教程。 您可以從下面的鏈接下載項目。

AndroidlyIntentsAndroidlyIntents

翻譯自: https://www.journaldev.com/37763/android-intent-handling-between-activities-using-kotlin

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/183102.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息