Взаимодействие с кодом Kotlin

Последнее обновление: 30.03.2024

Jetpack Compose предполагает применение декларативного стиля при определении визуального интерфейса и работы с ним. В этом отношении иногда возникает вопрос как определять какие-то свои собственные данные в виде переменных или действия в виде функций и использовать эти переменные и функции в компонентах для создания графического интерфейса. Рассмотрим некоторые случаи.

Использование переменных

Как и в общем случае переменные можно определять на уровне класса (например, на уровне класса MainActivity), либо на уровне отдельного метода/функции, в том числе и в функциях Composable. Например, используем пару переменных:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text
import androidx.compose.ui.unit.sp


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Hello()
        }
    }
}

@Composable
fun Hello(){
    val message = "Hello Metanit.com"
    val size = 28.sp
    Text(text = message, fontSize = size)
}

В данном случае в компоненте Hello определяются две переменных, и их значения передаются параметрам компонента Text:

Переменные в компонентах в Jetpack Compose и Kotlin

Это относится ко всем функциям, которые принимают компоненты в качестве параметров. Причем функция каждого компонента определяет свою область видимости, в рамках которой доступны ее переменные. Вложенные компоненты имеют доступ к переменным, определенным в родительских компонентах. Например:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text
import androidx.compose.ui.unit.sp
import androidx.compose.runtime.Composable


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val textSize = 28.sp
            Hello{
                val content = "Hello Work"
                Text(content, fontSize = textSize)
            }
        }
    }
}

Здесь иерархию компонентов можно представить следующим образом: setContent -> Hello -> Text. На уровне компонента setContent определяется переменная textSize - она видна на уровне компонентов в setContent.

На уровне компонента Hello определена переменная content - она доступна во вложенных компонентах, в частности, в компоненте Text, но недоступна вне компонента Hello.

Вызов функций Kotlin

Стоит отметить, что @Composable-функция может вызывать и стандартные функции Kotlin, однако стандартные функции не могут вызывать @Composable-функции. Например, изменим код MainActivity.kt следующим образом:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text
import androidx.compose.ui.unit.sp
import java.util.Calendar

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text(text = getTime(), fontSize = 28.sp)
        }
    }
}

fun getTime() : String{
    val calendar = Calendar.getInstance()
    val hours = calendar.get(Calendar.HOUR_OF_DAY)
    val minutes = calendar.get(Calendar.MINUTE)
    return "$hours:$minutes"
}

В данном случае определена стандартная функция getTime, которая с помощью встроенного класса Calendar получает текущее время (часы и минуты) и возвращает его в виде строки. В компоненте Text эта функция используется для установки текста.

Переменные и функции в компонентах в Jetpack Compose и Kotlin и Android

Подобным образом можно определять и вызывать лямбда-выражения:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text
import androidx.compose.ui.unit.sp
import java.util.Calendar

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val getTime ={
                val calendar = Calendar.getInstance()
                val hours = calendar.get(Calendar.HOUR_OF_DAY)
                val minutes = calendar.get(Calendar.MINUTE)
                "$hours:$minutes"
            }
            Text(text = getTime(), fontSize = 28.sp)
        }
    }
}

Условные конструкции

Внутри компонентов также можно использовать все стандартные управляющие конструкции, например, условные конструкции, в том числе для создания интерфейса:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val hours = 19
            if(hours<18) {
                Text(text = "Добрый день", fontSize = 28.sp)
            }
            else{
                Text(text = "Добрый вечер", fontSize = 28.sp)
            }
        }
    }
}

Здесь в зависимости от переменной hour в качестве внутренного содержимого установливается определенный компонент.

Циклы

Если необходимо создать ряд отднотиных компонентов, то удобно определить различающиеся данные в виде списка, а в цикле по этому списку создать набор компонентов:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val langs = listOf("Kotlin", "Java", "JavaScript", "Python")
            Column{
                for(lang in langs){
                    Text(text = lang, fontSize = 28.sp)
                }
            }
        }
    }
}

Здесь применяется встроенный компонент Column, который располагает вложенные компоненты в столбик. Но эти компоненты здесь создаются динамически. В начале определяем данные в виде списке langs. В столбце Column пробегаемся по этому списку и создаем для каждого свой компонент Text

создание компонентов в цикле в Jetpack Compose и Kotlin и Android

Причем в данном случае мы также могли бы применить и встроенную функцию forEach() списка, которая позволяет перебрать все объекты:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val langs = listOf("Kotlin", "Java", "JavaScript", "Scala")
            Column{
                langs.forEach{lang ->
                        Text(text = lang, fontSize = 28.sp)
                }
            }
        }
    }
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850