4 подписчика

Rust & Compose

t.me/oneRustnoqRust Ежедневная рассылка Для чего нужна данная статья? : Научиться интегрировать Rust с Compose через Java Native Interface (JNI) на платформе Android. Зачем Вам это уметь?

t.me/oneRustnoqRust Ежедневная рассылка

Для чего нужна данная статья? :

Научиться интегрировать Rust с Compose через Java Native Interface (JNI) на платформе Android.

Зачем Вам это уметь? :

Создать безопасный и производительный бэкенд.

Разработать красивый и декларативный пользовательский интерфейс.

_____________________________________________________________________________________

Создайте новый проект Rust:

cargo new --bin rust_and_compose
cd rust_and_compose

Отредактируйте файл src/main.rs:

// src/main.rs
use std::os::raw::c_int;
#[no_mangle]
pub extern "C" fn add_numbers(a: c_int, b: c_int) -> c_int {
a + b
}

Создайте новый проект Android в Android Studio с использованием Compose. Добавьте следующий код в файл MainActivity.kt:

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.material3.icons.Icons
import androidx.compose.material3.icons.filled.Add
import androidx.compose.material3.icons.filled.Clear
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.LocalTextInputService
import androidx.compose.ui.platform.LocalTextInputServiceOwner
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.platform.LocalViewConfiguration
import androidx.compose.ui.platform.LocalViewTreeObserver
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import com.example.featherandroidtasksampleapp.ui.theme.FeatherAndroidTaskSampleAppTheme
import com.sample.featherandroidtasksampleapp.R
import com.sample.featherandroidtasksampleapp.ui.theme.FeatherAndroidTaskSampleAppTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
FeatherAndroidTaskSampleAppTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting()
}
}
}
}
}
@Composable
fun Greeting() {
var number1 by remember { mutableStateOf(0) }
var number2 by remember { mutableStateOf(0) }
var result by remember { mutableStateOf(0) }
val context = LocalContext.current
Column(
modifier = Modifier
.padding(16.dp)
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
OutlinedTextField(
value = number1.toString(),
onValueChange = {
number1 = it.toIntOrNull() ?: 0
},
label = { Text("Number 1") },
keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done)
)
OutlinedTextField(
value = number2.toString(),
onValueChange = {
number2 = it.toIntOrNull() ?: 0
},
label = { Text("Number 2") },
keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done)
)
Spacer(modifier = Modifier.height(16.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
IconButton(
onClick = {
// Вызов функции из библиотеки Rust
result = add_numbers(number1, number2)
},
modifier = Modifier.size(48.dp)
) {
Icon(imageVector = Icons.Default.Add, contentDescription = "Add")
}
Spacer(modifier = Modifier.width(16.dp))
IconButton(
onClick = {
// Очистка значений
number1 = 0
number2 = 0
result = 0
},
modifier = Modifier.size(48.dp)
) {
Icon(imageVector = Icons.Default.Clear, contentDescription = "Clear")
}
}
Spacer(modifier = Modifier.height(16.dp))
// Отображение результата
Text(
text = "Result: $result",
style = MaterialTheme.typography.h6
)
}
}