У меня есть функция, которая извлекает данные из API и отображает эти данные. Я хочу, чтобы на экране отображался круговой индикатор выполнения, пока страница не будет готова.
fun Preview(Number: String) {
var selected by remember { mutableStateOf<Train?>(null) }
//var isLoading = remember { mutableStateOf(true) }
LaunchedEffect(key1 = Unit) {
//Simulate an API delay
delay(1000)
selected = data from API
}
if (selected != null) {
HorizontalPager(
state = pagerState,
modifier = Modifier.fillMaxSize(),
beyondBoundsPageCount = 2
)
{ index ->
selected?.get(index)?.let {
PagerContent(it)
}
}
} else {
Column(
Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
CircularProgressIndicator(color = Color.Blue)
Spacer(modifier = Modifier.height(10.dp))
Text(text = "Loading Please Wait...")
}
}
}
Этот код показывает индикатор выполнения, а затем он зависает. Я думаю, подождите, пока PagerContent() загрузится. Я хочу, чтобы он продолжал показывать индикатор выполнения до тех пор, пока PagerContent() не будет загружен/данные не отобразятся на странице.
Это не вызывает никаких проблем, индикатор выполнения работает нормально, пока выбранное не станет нулевым, затем он какое-то время зависает, а затем страница отображается с данными. Я думаю, что функции PagerContent требуется время для загрузки/отображения данных. Мой вопрос: как я могу проверить, загружен ли PagerContent() или все еще загружается?
Я думаю, вам следует попробовать разделить операторы условий IF и ELSE и проверить.
if (selected != null) {
HorizontalPager(
state = pagerState,
modifier = Modifier.fillMaxSize(),
beyondBoundsPageCount = 2
)
{ index ->
selected?.get(index)?.let {
PagerContent(it)
}
}
}
if (selected == null) {
Column(
Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
CircularProgressIndicator(color = Color.Blue)
Spacer(modifier = Modifier.height(10.dp))
Text(text = "Loading Please Wait...")
}
}
Почему вы думаете, что это что-то изменит? Пожалуйста, отредактируйте свой ответ и добавьте пояснение. И пока вы это делаете, пожалуйста, также правильно отформатируйте код и сделайте отступы.
Не работает, такой же как у меня был.
Как сейчас написано, ваш ответ неясен. Пожалуйста, отредактируйте , чтобы добавить дополнительную информацию, которая поможет другим понять, как это относится к заданному вопросу. Более подробную информацию о том, как писать хорошие ответы, вы можете найти в справочном центре.
Пользовательский интерфейс работает в одном потоке — главном потоке. Вы можете запускать сопрограммы, но, как правило, они не могут вызывать составные функции. Это также означает, что пользовательский интерфейс не может быть создан асинхронно. Поэтому вы можете либо отобразить кадр анимации, либо создать какую-то другую часть пользовательского интерфейса, но не то и другое одновременно. Если создание какого-либо элемента пользовательского интерфейса занимает слишком много времени, следующий кадр анимации не может быть выполнен достаточно быстро, поэтому анимация кажется «зависающей».
Настоящий вопрос, который вы должны задать себе, заключается в том, почему PagerContent выполнение занимает так много времени, что это заметно.
Функции Compose предназначены для очень быстрого выполнения, поскольку они выполняются каждый раз, когда происходит рекомпозиция. Рекомпозиции вообще могут происходить так часто, как каждый кадр, обычно не менее 60 раз в секунду. «Может произойти» означает, что это худший случай, и обычно у вас будет гораздо меньше рекомпозиций. Тем не менее, вам нужно, чтобы ваши компонуемые функции выполнялись как можно быстрее, чтобы избежать подобных зависаний, с которыми вы столкнулись.
Что вам нужно сделать, так это сделать PagerContent быстрее. Поскольку вы не поделились кодом PagerContent, мы можем только предполагать, почему его выполнение занимает так много времени. Возможные причины:
Этот список не является исчерпывающим, но суть вы, вероятно, поняли: переместите все, что не имеет прямого отношения к созданию элементов пользовательского интерфейса (которые должны выполняться в основном потоке), из PagerContent в модель представления, одновременно выполняя это в другом, более соответствующий диспетчер.
Когда PagerContent будет достаточно быстрым и время его выполнения больше не будет заметно, проблема, которую вы описали в своем вопросе, также исчезнет.
Кажется, это работает так, как задумано. Можете ли вы убедиться, что приведенный выше код действительно воспроизводит проблему? Убедитесь, что это не вызвано каким-то кодом, который вы не предоставили, например классом
Train, как на самом деле рассчитываетсяselectedилиPagerContent.