Индикатор загрузки не отображается при загрузке данных в Jetpack Compose (управление состоянием)Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Индикатор загрузки не отображается при загрузке данных в Jetpack Compose (управление состоянием)

Сообщение Anonymous »

В настоящее время я изучаю Jetpack Compose и пытаюсь реализовать индикатор загрузки во время загрузки данных.
Я управляю состоянием пользовательского интерфейса с помощью управления состоянием (StateFlow/MutableStateFlow). Моя цель — показать загрузчик во время загрузки данных и отобразить содержимое после загрузки данных.
Однако загрузчик не отображается во время загрузки данных.
Как правильно управлять состоянием, чтобы загрузчик отображался во время процесса загрузки, а пользовательский интерфейс правильно обновлялся после того, как данные стали доступны?
Модернизация
private val BASE_URL =
"https://jsonplaceholder.typicode.com/"
object ApiClient {
private val logging : HttpLoggingInterceptor = HttpLoggingInterceptor().setLevel(
HttpLoggingInterceptor.Level.BODY)

private val okHttpClient =
OkHttpClient.Builder()
.addInterceptor(logging)
.build()

private val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.client(okHttpClient)
.build()

val apiService : GetDataService by lazy {
retrofit.create(GetDataService::class.java)
}
}

interface GetDataService {
@GET("users")
suspend fun getData() : List
}

class UserRepository(val api: GetDataService,private val db: AppDatabase) {
suspend fun getUser(): List {
return try {
val apiUsers = api.getData().map { User(firstName = it.name, lastName = it.email) }
db.userDao().insertAlls(apiUsers)
apiUsers
} catch (e: Exception) {
db.userDao().getAll()
}
}
}

data class UserDataModel(val name : String,val username : String, val email : String,val image :String = "")

@Dao
interface UserDao {
@Query("SELECT * FROM user")
fun getAll(): List

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAlls(users: List)

@Delete
suspend fun delete(users: List)
}

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao

companion object {
@Volatile
private var INSTANCE: AppDatabase? = null

// Thread-safe singleton to get the database
fun getDatabase(context: Context): AppDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"database-name"
).build()
INSTANCE = instance
instance
}
}
}
}

@Entity
data class User(
@PrimaryKey(autoGenerate = true) val uid: Int = 0,
@ColumnInfo(name = "first_name") val firstName: String?,
@ColumnInfo(name = "last_name") val lastName: String?
)


@Composable
fun HomeScreen(modifier: Modifier)
{
val context = LocalContext.current
val db = AppDatabase.getDatabase(context)
val repository = UserRepository(ApiClient.apiService,db)

val viewModel: HomeViewModel = viewModel(
factory = HomeViewModelFactory(
application = context.applicationContext as Application,
repository = repository
)
)

val users = viewModel.uiState.collectAsState().value

when(users)
{
is HomeUIState.Loading -> {
CircularProgressIndicator()
}

is HomeUIState.NoData -> {
Text("No data found")
}

is HomeUIState.Error -> {
val errormsg = users.error
Text(errormsg)
}

is HomeUIState.Success ->{
val list = users.list
Column() {
LazyColumn(modifier= Modifier.weight(1f)) {

items(list.size) { index ->
Row() {
AsyncImage("",
contentDescription = list[index].firstName.toString(),
modifier = Modifier.size(100.dp))
list[index].firstName?.let { Text(it) }
}
}
}

Button(onClick = { viewModel.loadMore() }) {
Text("Load More")
}
}
}
}
}

class HomeViewModel(
application: Application,
private val repository: UserRepository
) : AndroidViewModel(application) {

private val _uiState = MutableStateFlow(HomeUIState.Loading)
val uiState: StateFlow = _uiState

private var currentPage = 1
private val pageSize = 3

init {
loadData()
}

fun loadData() {
viewModelScope.launch {
_uiState.value = HomeUIState.Loading
try {
val users = repository.getUser()
if (users.isEmpty()) {
_uiState.value = HomeUIState.NoData
} else {
_uiState.value = HomeUIState.Success(users)
}
} catch (e: Exception) {
_uiState.value = HomeUIState.Error(e.localizedMessage ?: "Something went wrong")
}
}
}

fun loadMore() {
currentPage++
loadData()
}
}

class HomeViewModelFactory(
private val application: Application,
private val repository: UserRepository
) : ViewModelProvider.Factory {

override fun create(modelClass: Class): T {
if (modelClass.isAssignableFrom(HomeViewModel::class.java)) {
return HomeViewModel(application, repository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}

data class UserDataModel(val name : String,val username : String, val email : String)

sealed interface HomeUIState {
data object Loading : HomeUIState
data object NoData : HomeUIState
data class Success(val list: List) : HomeUIState
data class Error(val error: String) : HomeUIState
}

implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.okhttp3:okhttp:4.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
testImplementation("io.mockk:mockk:1.13.8")
implementation("io.coil-kt:coil-compose:2.6.0")
implementation("androidx.room:room-runtime:2.8.4")
implementation("androidx.room:room-ktx:2.8.4")
kapt("androidx.room:room-compiler:2.8.4")


Подробнее здесь: https://stackoverflow.com/questions/799 ... e-state-ma
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»