MainActivity.kt
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import com.neco_desarrollo.roomdb.ui.MainScreen
import com.neco_desarrollo.roomdb.ui.theme.RoomDbTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
RoomDbTheme {
MainScreen()
}
}
}
}
Dao.kt
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import kotlinx.coroutines.flow.Flow
@Dao
interface Dao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertItem(nameEntity: NameEntity)
@Delete
suspend fun deleteItem(nameEntity: NameEntity)
@Query("SELECT * FROM name_table")
fun getAllItems(): Flow<List<NameEntity>>
}
NameEntity.kt
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "name_table")
data class NameEntity(
@PrimaryKey(autoGenerate = true)
val id: Int? = null,
val name: String
)
MainScreen.kt
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.neco_desarrollo.roomdb.MainViewModel
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen(
mainViewModel: MainViewModel = viewModel(factory = MainViewModel.factory)
) {
val itemsList = mainViewModel.itemsList.collectAsState(initial = emptyList())
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
) {
Row(
modifier = Modifier
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
TextField(
value = mainViewModel.newText.value,
onValueChange = {
mainViewModel.newText.value = it
},
label = {
Text(text = "Name...")
},
modifier = Modifier.weight(1f),
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.White
)
)
IconButton(
onClick = {
mainViewModel.insertItem()
}) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = "Add"
)
}
}
Spacer(modifier = Modifier.height(5.dp))
LazyColumn(
modifier = Modifier.fillMaxSize()
){
items(itemsList.value) { item ->
ListItem(
item, {
mainViewModel.nameEntity = it
mainViewModel.newText.value = it.name
},
{
mainViewModel.deleteItem(it)
}
)
}
}
}
}
ListItem.kt
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.Card
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.neco_desarrollo.roomdb.data.NameEntity
@Composable
fun ListItem(
item: NameEntity,
onClick: (NameEntity) -> Unit,
onClickDelete: (NameEntity) -> Unit
) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(5.dp)
.clickable {
onClick(item)
}
) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Text(
item.name,
modifier = Modifier
.fillMaxWidth()
.weight(1f)
.padding(10.dp)
)
IconButton(
onClick = {
onClickDelete(item)
}) {
Icon(
imageVector = Icons.Default.Delete,
contentDescription = "Delete"
)
}
}
}
}
MainViewModel.kt
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import com.neco_desarrollo.roomdb.data.MainDb
import com.neco_desarrollo.roomdb.data.NameEntity
import kotlinx.coroutines.launch
class MainViewModel(val database: MainDb) : ViewModel() {
val itemsList = database.dao.getAllItems()
val newText = mutableStateOf("")
var nameEntity: NameEntity? = null
fun insertItem() = viewModelScope.launch {
val nameItem = nameEntity?.copy(name = newText.value)
?: NameEntity(name = newText.value)
database.dao.insertItem(nameItem)
nameEntity = null
newText.value = ""
}
fun deleteItem(item: NameEntity) = viewModelScope.launch {
database.dao.deleteItem(item)
}
companion object{
val factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory{
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras): T {
val database = (checkNotNull(extras[APPLICATION_KEY]) as App).database
return MainViewModel(database) as T
}
}
}
}
MainDb.kt
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(
entities = [
NameEntity::class
],
version = 1
)
abstract class MainDb : RoomDatabase() {
abstract val dao: Dao
companion object{
fun createDataBase(context: Context): MainDb{
return Room.databaseBuilder(
context,
MainDb::class.java,
"test.db"
).build()
}
}
}
App.kt
import android.app.Application
import com.neco_desarrollo.roomdb.data.MainDb
class App : Application() {
val database by lazy { MainDb.createDataBase(this) }
}
зависимости:
implementation 'androidx.room:room-ktx:2.5.1'
kapt 'androidx.room:room-compiler:2.5.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.5.0'
Здравствуйте N.E.C.O у меня скорее просьба, а не комментарий. Я живу в РФ и на нашей территории теперь Youtube замедлили на столько, что он практически не работает (вчера для интереса заходил на один из Ваших видео уроков по Jetpack Compose примерно 20 мин). Просьба о переносе Вашего {N.E.C.O} на rutube.ru или на Платформу (plvideo.ru). Оба этих сайта на территории РФ доступны. Впрочем хочу оговориться: я совсем ничего не знаю о Вашей русскоговорящей аудитории, возможно она не на территории РФ и у неё (аудитории) нет проблем с Youtube. Возможно существует еще масса проблем с переносом. Я пишу только из соображений, что с одной стороны возможность переноса малопроблемная, а с другой – Вам не известно о проблемах с доступом к Вашему {N.E.C.O} в РФ.
В любом случае я (и уверен вся знакомая с Вашей работой аудитория РФ) Вам очень признателен за ту огромную работу по популяризации Котлин и Андроид для русскоговорящей аудитории.
С благодарность и уважением за Ваш огромный труд!
Valerii Vorobev!