Sobes.tech
Junior

Как се осъществява навигацията между Activity в Android?

sobes.tech AI

Отговор от AI

Навигацията между Activity се осъществява с помощта на Intent.

Intent е обект за обмен на съобщения, който позволява на компонентите (като Activity, Services, Broadcast Receivers) да изискват действия един от друг.

Има два основни типа Intent:

  • Явни Intent: посочват конкретен компонент за стартиране (например, клас Activity).
  • Неявни Intent: посочват типа на действието, което трябва да бъде изпълнено (например, разглеждане на уеб страница), и системата Android избира подходящия компонент за изпълнение.

За стартиране на нов Activity с помощта на явен Intent се използва методът startActivity().

// В текущия Activity
val intent = Intent(this, TargetActivity::class.java) // Явно Intent
startActivity(intent)

За прехвърляне на данни между Activity може да се използва методът putExtra() на обекта Intent:

// Изпращане на данни
val intent = Intent(this, TargetActivity::class.java)
intent.putExtra("key_name", "some_value")
startActivity(intent)

// Получаване на данни в TargetActivity (в метода onCreate() или onNewIntent())
val data = intent.getStringExtra("key_name")

За получаване на резултат от Activity, която е била стартирана, се използва startActivityForResult(). След приключване на дъщерното Activity, то може да изпрати резултат обратно с setResult() и finish(). Родителското Activity получава този резултат в метода onActivityResult().

// В родителското Activity
val intent = Intent(this, ChildActivity::class.java)
startActivityForResult(intent, REQUEST_CODE) // REQUEST_CODE е уникален идентификатор

// Получаване на резултата
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
        val resultData = data?.getStringExtra("result_key")
        // Обработка на резултата
    }
}

// В дъщерното Activity (преди затваряне)
val resultIntent = Intent()
resultIntent.putExtra("result_key", "result_value")
setResult(RESULT_OK, resultIntent)
finish()

От AndroidX нататък се препоръчва използването на API за резултати от Activity вместо startActivityForResult()/onActivityResult():

// В родителското Activity
private val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        val data = result.data
        // Обработка на резултата
    }
}

// Стартиране на Activity
val intent = Intent(this, ChildActivity::class.java)
startForResult.launch(intent)

// В дъщерното Activity (преди затваряне)
val resultIntent = Intent()
resultIntent.putExtra("result_key", "result_value")
setResult(RESULT_OK, resultIntent)
finish()

Също така, за по-сложна навигация в съвременните Android приложения често се използва компонентът Navigation от Jetpack:

  • Navigation Component: Позволява да се дефинира навигационен граф, който описва всички възможни пътища между екрана на приложението. Използва NavController за управление на преместването по графа.
<!-- Пример nav_graph.xml -->
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mobile_navigation"
    app:startDestination="@+id/firstFragment">

    <fragment
        android:id="@+id/firstFragment"
        android:name="com.example.app.FirstFragment"
        android:label="First" >
        <action
            android:id="@+id/action_firstFragment_to_secondFragment"
            app:destination="@id/secondFragment" />
    </fragment>
    <fragment
        android:id="@+id/secondFragment"
        android:name="com.example.app.SecondFragment"
        android:label="Second" />
</navigation>
// В Activity (например, в Fragment)
findNavController().navigate(R.id.action_firstFragment_to_secondFragment)

Navigation Component улеснява реализирането на навигацията, включително прехвърлянето на аргументи, поддръжка на диалогови прозорци и управление на back stack.