Промежуточное

This commit is contained in:
ElEgEv 2023-12-11 15:29:25 +04:00
parent 38cb371048
commit 8f116e2005
21 changed files with 198 additions and 1 deletions

View File

@ -84,4 +84,8 @@ dependencies {
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
// Paging | +
val pagingVersion = "3.3.0-alpha02"
implementation("androidx.paging:paging-compose:$pagingVersion")
}

View File

@ -63,9 +63,11 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.navigation.NavController
import ru.ulstu.`is`.pmu.tank.composeui.TankList
import ru.ulstu.`is`.pmu.tank.composeui.list.NationListViewModel
import ru.ulstu.`is`.pmu.tanks.composeui.Account
import ru.ulstu.`is`.pmu.tanks.composeui.Constructor
import ru.ulstu.`is`.pmu.tanks.composeui.Hangar
import ru.ulstu.`is`.pmu.tanks.composeui.NationList
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -143,6 +145,7 @@ fun Navhost(
startDestination = Screen.TankList.route,
) {
composable(Screen.TankList.route) { TankList(navController) }
composable(Screen.NATIONS.route) { NationList(navController) }
composable(
Screen.Constructor.route,
arguments = listOf(navArgument("id") { type = NavType.LongType })

View File

@ -4,6 +4,7 @@ import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AccountCircle
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Create
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.List
@ -36,11 +37,14 @@ enum class Screen(
),
StudentView(
"student-view/{id}", R.string.student_view_title, showInBottomBar = false
);
),
NATIONS("nations", R.string.nation, Icons.Filled.Create),
EDIT_NATIONS("edit-nation/{id}", R.string.nation);
companion object {
val bottomBarItems = listOf(
TankList,
NATIONS,
Hangar,
Account
)
@ -49,5 +53,9 @@ enum class Screen(
val findRoute = route.split("/").first()
return values().find { value -> value.route.startsWith(findRoute) }
}
fun getEntityRoute(screen: Screen, itemId: Long): String {
return screen.route.replace("{id}", itemId.toString())
}
}
}

View File

@ -0,0 +1,21 @@
package ru.ulstu.`is`.pmu.tank.composeui.list
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import ru.ulstu.`is`.pmu.tank.repository.NationRepository
class NationListViewModel(
nationRepository: NationRepository
) : ViewModel() {
private val pager = Pager(
config = PagingConfig(pageSize = 10),
pagingSourceFactory = {
nationRepository.pagingSource()
}
)
val nationPagingFlow = pager.flow.cachedIn(viewModelScope)
}

View File

@ -1,5 +1,6 @@
package ru.ulstu.`is`.pmu.tank.dao
import androidx.paging.PagingSource
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
@ -31,6 +32,9 @@ interface NationDao {
)
open fun getSimpleNationUid(uid: Long): Flow<Nation?>
@Query("SELECT * FROM nations")
fun pagingSource(): PagingSource<Int, Nation>
@Insert
suspend fun insert(nation: Nation)

View File

@ -53,6 +53,10 @@ abstract class AppDatabase : RoomDatabase() {
val nation8 = Nation( 8L, "Китай")
val nation9 = Nation( 9L, "Япония")
val nation10 = Nation(10L, "Италия")
val nation11 = Nation(11L, "Бангладеш")
val nation12 = Nation(12L, "Зимбамбве")
val nation13 = Nation(13L, "Гондурас")
val nation14 = Nation(14L, "Майами")
nationDao.insert(nation1)
nationDao.insert(nation2)
@ -64,6 +68,10 @@ abstract class AppDatabase : RoomDatabase() {
nationDao.insert(nation8)
nationDao.insert(nation9)
nationDao.insert(nation10)
nationDao.insert(nation11)
nationDao.insert(nation12)
nationDao.insert(nation13)
nationDao.insert(nation14)
// Levels
val levelDao = database.levelDao()

View File

@ -1,5 +1,6 @@
package ru.ulstu.`is`.pmu.tank.repository
import androidx.paging.PagingSource
import kotlinx.coroutines.flow.Flow
import ru.ulstu.`is`.pmu.tank.model.Nation
import ru.ulstu.`is`.pmu.tank.model.NationWithTanks
@ -8,6 +9,7 @@ interface NationRepository {
suspend fun getAllNations(): List<Nation>
fun getSimpleNation(uid: Long): Flow<Nation?>
fun getFullNation(uid: Long): Flow<NationWithTanks?>
fun pagingSource(): PagingSource<Int, Nation>
suspend fun insertNation(nation: Nation)
suspend fun updateNation(nation: Nation)
suspend fun deleteNation(nation: Nation)

View File

@ -1,5 +1,6 @@
package ru.ulstu.`is`.pmu.tank.repository
import androidx.paging.PagingSource
import kotlinx.coroutines.flow.Flow
import ru.ulstu.`is`.pmu.tank.dao.NationDao
import ru.ulstu.`is`.pmu.tank.model.Nation
@ -12,6 +13,8 @@ class OfflineNationRepository(private val nationDao: NationDao) : NationReposito
override fun getFullNation(uid: Long): Flow<NationWithTanks?> = nationDao.getNationUid(uid)
override fun pagingSource(): PagingSource<Int, Nation> = nationDao.pagingSource()
override suspend fun insertNation(nation: Nation) = nationDao.insert(nation)
override suspend fun updateNation(nation: Nation) = nationDao.update(nation)

View File

@ -0,0 +1,108 @@
package ru.ulstu.`is`.pmu.tanks.composeui
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.LocalOverscrollConfiguration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.overscroll
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemKey
import ru.ulstu.`is`.pmu.R
import ru.ulstu.`is`.pmu.composeui.navigation.Screen
import ru.ulstu.`is`.pmu.tank.composeui.list.NationListViewModel
import ru.ulstu.`is`.pmu.tank.model.Nation
import ru.ulstu.`is`.pmu.tanks.composeui.image.Dimensions
import ru.ulstu.`is`.pmu.ui.AppViewModelProvider
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun NationList(
navController: NavController,
viewModel: NationListViewModel = viewModel(factory = AppViewModelProvider.Factory)
) {
val nations = viewModel.nationPagingFlow.collectAsLazyPagingItems()
fun handleAddButtonClick() {
val route = Screen.getEntityRoute(Screen.Constructor, 0)
navController.navigate(route)
}
Box(
modifier = Modifier
.fillMaxSize()
.padding(10.dp)
) {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(10.dp),
modifier = Modifier.height(300.dp * nations.itemCount / 5),
) {
items(
count = nations.itemCount,
key = nations.itemKey { it.uid!! }
) {
val nation: Nation = nations[it] ?: return@items
NationBox(
nation = nation,
navController = navController
)
}
}
}
}
@Composable
fun NationBox(
nation: Nation,
navController: NavController
) {
fun handleOnClick() {
val route = Screen.getEntityRoute(Screen.EDIT_NATIONS, nation.uid!!)
navController.navigate(route)
}
Box(
modifier = Modifier
.fillMaxWidth()
.clickable(
onClick = {
handleOnClick()
}
)
.background(
MaterialTheme.colorScheme.surface,
shape = RoundedCornerShape(Dimensions.cornerRadius)
)
.padding(15.dp)
) {
Text(
text = nation.nationName,
color = MaterialTheme.colorScheme.onSurface
)
}
}

View File

@ -8,8 +8,10 @@ import androidx.lifecycle.viewmodel.viewModelFactory
import ru.ulstu.`is`.pmu.TankApplication
import ru.ulstu.`is`.pmu.tank.composeui.edit.LevelDropDownViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationDropDownViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationsListUiState
import ru.ulstu.`is`.pmu.tank.composeui.edit.TankEditViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.UserEditViewModel
import ru.ulstu.`is`.pmu.tank.composeui.list.NationListViewModel
import ru.ulstu.`is`.pmu.tank.composeui.list.TankListViewModel
object AppViewModelProvider {
@ -35,6 +37,9 @@ object AppViewModelProvider {
initializer {
NationDropDownViewModel(tankApplication().container.nationRepository)
}
initializer {
NationListViewModel(tankApplication().container.nationRepository)
}
}
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android">
<svg fill="#000000" height="200px" width="200px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" xml:space="preserve"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <g> <g> <g> <path d="M511.765,73.235c-0.064-0.533-0.107-1.045-0.256-1.557c-0.085-0.299-0.171-0.576-0.277-0.853 c-0.149-0.405-0.405-0.747-0.597-1.131c-0.235-0.427-0.405-0.875-0.683-1.259c-0.213-0.299-0.469-0.555-0.725-0.832 c-0.32-0.363-0.661-0.661-1.024-0.96c-0.277-0.235-0.512-0.533-0.811-0.747c-0.363-0.256-0.768-0.384-1.173-0.576 c-0.448-0.235-0.896-0.448-1.387-0.619c-0.277-0.107-0.512-0.277-0.811-0.363l-245.333-64c-1.749-0.448-3.627-0.448-5.376,0 l-245.333,64c-0.299,0.085-0.512,0.256-0.811,0.363c-0.491,0.171-0.939,0.384-1.387,0.619c-0.384,0.213-0.811,0.341-1.173,0.576 c-0.32,0.213-0.533,0.512-0.811,0.747c-0.363,0.32-0.704,0.619-1.024,0.96c-0.256,0.277-0.512,0.533-0.725,0.832 c-0.277,0.384-0.448,0.832-0.683,1.259c-0.213,0.384-0.448,0.725-0.597,1.131c-0.107,0.277-0.192,0.555-0.277,0.853 c-0.149,0.512-0.192,1.024-0.256,1.557C0.171,73.725,0,74.173,0,74.664v426.667c0,5.888,4.779,10.667,10.667,10.667h490.667 c5.888,0,10.667-4.779,10.667-10.667V74.664C512,74.173,511.829,73.725,511.765,73.235z M490.667,362.664H373.333 c-5.888,0-10.667,4.779-10.667,10.667v21.333c0,5.888,4.779,10.667,10.667,10.667h117.333v21.333h-160 c-5.888,0-10.667,4.779-10.667,10.667v53.333h-85.333v-53.333c0-5.888-4.779-10.667-10.667-10.667h-42.667 c-5.888,0-10.667,4.779-10.667,10.667v53.333h-21.333v-53.333c0-5.888-4.779-10.667-10.667-10.667H53.333 c-5.888,0-10.667,4.779-10.667,10.667v53.333H21.333V341.331h469.333V362.664z M490.667,277.331H21.333v-21.333h469.333V277.331z M490.667,191.997H21.333v-21.333h469.333V191.997z M490.667,106.664H21.333V85.331h469.333V106.664z"></path> <path d="M53.333,405.331h64c5.888,0,10.667-4.779,10.667-10.667v-21.333c0-5.888-4.779-10.667-10.667-10.667h-64 c-5.888,0-10.667,4.779-10.667,10.667v21.333C42.667,400.552,47.445,405.331,53.333,405.331z"></path> </g> </g> </g> </g></svg>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M18.41,5.8L17.2,4.59c-0.78,-0.78 -2.05,-0.78 -2.83,0l-2.68,2.68L3,15.96V20h4.04l8.74,-8.74 2.63,-2.63c0.79,-0.78 0.79,-2.05 0,-2.83zM6.21,18H5v-1.21l8.66,-8.66 1.21,1.21L6.21,18zM11,20l4,-4h6v4H11z"/>
</vector>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:pathData="M2,8L14,8"
android:strokeLineJoin="round"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"
android:strokeLineCap="round"/>
<path
android:pathData="M8,2L8,14"
android:strokeLineJoin="round"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"
android:strokeLineCap="round"/>
</vector>

View File

@ -26,6 +26,7 @@
<string name="t_34_85">T-34-85</string>
<string name="sherman">Sherman</string>
<string name="tiger_1">Tiger 1</string>
<string name="nation">Нации</string>
<string name="about_text">
<p>Это текст <b>о нас</b>!</p>\n\n
<p>Здесь могла быть Ваша реклама!</p>\n\n