Feature: pagination

This commit is contained in:
ArtemEmelyanov 2023-11-10 22:19:18 +04:00
parent a78c75ef07
commit 14dabf5f60
9 changed files with 84 additions and 34 deletions

View File

@ -7,11 +7,11 @@
<deviceKey> <deviceKey>
<Key> <Key>
<type value="VIRTUAL_DEVICE_PATH" /> <type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\Admin\.android\avd\Pixel_2_API_30.avd" /> <value value="C:\Users\Admin\.android\avd\Pixel_7_Pro_API_30.avd" />
</Key> </Key>
</deviceKey> </deviceKey>
</Target> </Target>
</targetSelectedWithDropDown> </targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-10-29T18:24:53.426357Z" /> <timeTargetWasSelectedWithDropDown value="2023-11-10T15:46:58.753378100Z" />
</component> </component>
</project> </project>

View File

@ -83,4 +83,8 @@ dependencies {
kapt("androidx.room:room-compiler:$room_version") kapt("androidx.room:room-compiler:$room_version")
implementation("androidx.room:room-ktx:$room_version") implementation("androidx.room:room-ktx:$room_version")
implementation("androidx.room:room-paging:$room_version") implementation("androidx.room:room-paging:$room_version")
//Paging
implementation ("androidx.paging:paging-compose:3.2.1")
implementation ("androidx.paging:paging-runtime:3.2.1")
} }

View File

@ -1,41 +1,62 @@
package com.example.android_programming.composeui.Screens.AdminPanel package com.example.android_programming.composeui.Screens.AdminPanel
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize 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.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.paging.LoadState
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemKey
import com.example.android_programming.model.Sneaker
import com.example.android_programming.vmodel.AppViewModelProvider import com.example.android_programming.vmodel.AppViewModelProvider
import com.example.android_programming.vmodel.SneakerViewModel import com.example.android_programming.vmodel.SneakerViewModel
import kotlinx.coroutines.delay
@Composable @Composable
fun ChangePanel(navHostController: NavHostController, sneakerViewModel: SneakerViewModel = viewModel(factory = AppViewModelProvider.Factory)) { fun ChangePanel(navHostController: NavHostController, sneakerViewModel: SneakerViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
val list = sneakerViewModel.SneakerList.collectAsState(initial = emptyList()).value val list = sneakerViewModel.sneakerList.collectAsLazyPagingItems()
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background(Color.White) .background(Color.White)
.padding(16.dp) .padding(16.dp, 80.dp)
) { ) {
Row { Row {
LazyColumn( LazyColumn(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
) { ) {
itemsIndexed(list items(list.itemCount) { index ->
){_, item-> list[index]?.let { sneaker ->
CardSneakerForChange(item = item, navHostController) CardSneakerForChange(item = sneaker, navController = navHostController)
} }
} }
} }
} }
} }
}

View File

@ -28,13 +28,11 @@ import com.example.android_programming.vmodel.OrderViewModel
@Composable @Composable
fun HomeScreen(navHostController: NavHostController, orderViewModel: OrderViewModel) { fun HomeScreen(navHostController: NavHostController, orderViewModel: OrderViewModel) {
val context = LocalContext.current
val sneakers = remember { mutableStateListOf<Sneaker>() }
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background(Color.White) .background(Color.White)
.verticalScroll(rememberScrollState()) /*.verticalScroll(rememberScrollState())*/
) { ) {
Row { Row {
// Поле для поиска // Поле для поиска

View File

@ -1,17 +1,18 @@
package com.example.android_programming.composeui.Screens.HomeScreen.SneakerRecyclerView package com.example.android_programming.composeui.Screens.HomeScreen.SneakerRecyclerView
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemKey
import com.example.android_programming.model.Sneaker
import com.example.android_programming.vmodel.AppViewModelProvider import com.example.android_programming.vmodel.AppViewModelProvider
import com.example.android_programming.vmodel.OrderViewModel import com.example.android_programming.vmodel.OrderViewModel
import com.example.android_programming.vmodel.SneakerViewModel import com.example.android_programming.vmodel.SneakerViewModel
@ -23,17 +24,18 @@ fun RecyclerView(navHostController : NavHostController, orderViewModel: OrderVie
.fillMaxSize() .fillMaxSize()
.padding(bottom = 60.dp) .padding(bottom = 60.dp)
) { ) {
val list = sneakerViewModel.SneakerList.collectAsState(initial = emptyList()).value val sneakerLazyPagingItems = sneakerViewModel.sneakerList.collectAsLazyPagingItems()
val numColumns = 2
val chunkedList = list.chunked(numColumns)
for (chunkedListItem in chunkedList) { LazyVerticalGrid(
Row( columns = GridCells.Fixed(2)
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
) { ) {
for (item in chunkedListItem) { items(
CardSneaker(item, navHostController, orderViewModel.selectedItems) { selectedItem -> count = sneakerLazyPagingItems.itemCount,
key = sneakerLazyPagingItems.itemKey { sneaker -> sneaker.sneakerId!! }
) { index: Int ->
val sneaker: Sneaker? = sneakerLazyPagingItems[index]
if (sneaker != null) {
CardSneaker(sneaker, navHostController, orderViewModel.selectedItems) { selectedItem ->
orderViewModel.addSelectedItem(selectedItem) orderViewModel.addSelectedItem(selectedItem)
} }
} }
@ -42,3 +44,5 @@ fun RecyclerView(navHostController : NavHostController, orderViewModel: OrderVie
} }
} }

View File

@ -1,5 +1,6 @@
package com.example.android_programming.dao package com.example.android_programming.dao
import androidx.paging.PagingSource
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
@ -20,7 +21,7 @@ interface SneakerDao {
suspend fun delete(sneaker: Sneaker) suspend fun delete(sneaker: Sneaker)
@Query("SELECT*FROM Sneaker") @Query("SELECT*FROM Sneaker")
fun getAllSneakers(): Flow<List<Sneaker>> fun getAllSneakersPaged(): PagingSource<Int, Sneaker>
@Query("SELECT * FROM Sneaker WHERE sneakerId = :id") @Query("SELECT * FROM Sneaker WHERE sneakerId = :id")
suspend fun getSneakerById(id: Int): Sneaker suspend fun getSneakerById(id: Int): Sneaker

View File

@ -1,5 +1,10 @@
package com.example.android_programming.repository package com.example.android_programming.repository
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.PagingSource
import androidx.paging.cachedIn
import com.example.android_programming.dao.SneakerDao import com.example.android_programming.dao.SneakerDao
import com.example.android_programming.model.Sneaker import com.example.android_programming.model.Sneaker
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -13,6 +18,12 @@ class SneakerRepoImpl(private val sneakerDao: SneakerDao) : SneakerRepository {
override suspend fun deleteSneaker(sneaker: Sneaker) = sneakerDao.delete(sneaker) override suspend fun deleteSneaker(sneaker: Sneaker) = sneakerDao.delete(sneaker)
override suspend fun getSneakerById(id: Int): Sneaker = sneakerDao.getSneakerById(id) override suspend fun getSneakerById(id: Int): Sneaker = sneakerDao.getSneakerById(id)
override fun getAllSneakersPaged(): PagingSource<Int, Sneaker> = sneakerDao.getAllSneakersPaged()
override fun getAllSneakers(): Flow<List<Sneaker>> = sneakerDao.getAllSneakers() override fun call(): Flow<PagingData<Sneaker>> {
return Pager(
PagingConfig(pageSize = 5)
) {
sneakerDao.getAllSneakersPaged()
}.flow
}
} }

View File

@ -1,5 +1,7 @@
package com.example.android_programming.repository package com.example.android_programming.repository
import androidx.paging.PagingData
import androidx.paging.PagingSource
import com.example.android_programming.model.Sneaker import com.example.android_programming.model.Sneaker
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -8,5 +10,6 @@ interface SneakerRepository {
suspend fun updateSneaker(sneaker: Sneaker) suspend fun updateSneaker(sneaker: Sneaker)
suspend fun deleteSneaker(sneaker: Sneaker) suspend fun deleteSneaker(sneaker: Sneaker)
suspend fun getSneakerById(id: Int): Sneaker suspend fun getSneakerById(id: Int): Sneaker
fun getAllSneakers(): Flow<List<Sneaker>> fun getAllSneakersPaged(): PagingSource<Int, Sneaker>
fun call(): Flow<PagingData<Sneaker>>
} }

View File

@ -1,16 +1,24 @@
package com.example.android_programming.vmodel package com.example.android_programming.vmodel
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras import androidx.lifecycle.viewmodel.CreationExtras
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.cachedIn
import androidx.paging.map
import com.example.android_programming.App import com.example.android_programming.App
import com.example.android_programming.R import com.example.android_programming.R
import com.example.android_programming.database.AppDatabase import com.example.android_programming.database.AppDatabase
import com.example.android_programming.model.Sneaker import com.example.android_programming.model.Sneaker
import com.example.android_programming.repository.SneakerRepository import com.example.android_programming.repository.SneakerRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class SneakerViewModel(private val sneakerRepository: SneakerRepository): ViewModel() { class SneakerViewModel(private val sneakerRepository: SneakerRepository): ViewModel() {
@ -18,8 +26,8 @@ class SneakerViewModel(private val sneakerRepository: SneakerRepository): ViewMo
val model = mutableStateOf("") val model = mutableStateOf("")
val description = mutableStateOf("") val description = mutableStateOf("")
val price = mutableStateOf("") val price = mutableStateOf("")
val photo = mutableStateOf(R.drawable.img) val photo = mutableIntStateOf(R.drawable.img)
val SneakerList = sneakerRepository.getAllSneakers() val sneakerList = sneakerRepository.call().cachedIn(viewModelScope)
var sneaker: Sneaker? = null var sneaker: Sneaker? = null
fun insertSneaker() = viewModelScope.launch { fun insertSneaker() = viewModelScope.launch {