Итак, я пытаюсь создать приложение coinTracker, которое отслеживает биткойны с помощью API-интерфейса Coin Cap. Но я не знаю, почему мой экран пуст. Я бы включил этот скриншот. Итак, я думаю, что либо мои списки не обновляются, либо моя функция getCoin просто работает в основном потоке. Я проверил эти две вещи, были обновления здесь и там, но я не смог изолировать проблему. Даже мой логарифм ничего не показывает.
@Composable
fun CoinList_Screen(
modifier: Modifier = Modifier,
viewModel : CoinsViewModel
){
val coinList = viewModel.coins.collectAsState().value
if(coinList.isLoading){
Box(modifier = modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
CircularProgressIndicator()
}
}else{
LazyColumn(modifier = modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(8.dp)){
items(coinList.coins){
coin ->
val coin_new = coin.toCoin()
CoinComp(coinUi =coin_new.toCoinUi(),modifier = modifier.fillMaxWidth(),{})
}
}
}
}
ViewModel –
class CoinsViewModel(
private val repo : CoinRepo
):ViewModel() {
private val _coins = MutableStateFlow(screenState())
val coins = _coins.asStateFlow()
private val showSnackar = Channel()
val showSnackBat = showSnackar.receiveAsFlow()
init{
getCoin()
}
private fun getCoin() {
viewModelScope.launch {
_coins.update {
it.copy(isLoading = true)
}
repo.getCoins().collectLatest { result ->
when (result) {
is Result.Error -> {
_coins.update {
it.copy(isLoading = false)
}
showSnackar.send(true)
}
is Result.Success -> {
result.data?.let { coin ->
_coins.update {
it.copy(
isLoading = false,
coins = coin
)
}
}
}
}
}
}
}
}
Репозитории ->
interface CoinRepo {
suspend fun getCoins(): Flow
}
class CoinRepoImpl(
private val api: ApiInterface
) :CoinRepo{
override suspend fun getCoins(): Flow {
return flow{
val coins = try {
api.getCoin()
}catch (e: IOException){
e.printStackTrace()
emit(Result.Error(message = "Error loading coins"))
return@flow
}catch (e :HttpException){
e.printStackTrace()
emit(Result.Error(message = "Error loading coins"))
return@flow
}catch(e:Exception){
e.printStackTrace()
emit(Result.Error(message = "Error loading coins"))
return@flow
}
emit(Result.Success(coins.Coins))
}
}
}
Результат –>
sealed class Result(
val data : T? = null,
val message : String? = null
){
class Success(data : T) : Result(data = data)
class Error(data : T?= null,message: String) : Result(data,message=message)
}
API ->
interface ApiInterface {
@GET("assets")
fun getCoin() : Coins
}
Модернизация экземпляра ->
object RetrofitInstance {
private val interceptor:HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
private val client: OkHttpClient = OkHttpClient.Builder().addInterceptor(interceptor).build()
val api:ApiInterface = Retrofit.Builder().addConverterFactory(GsonConverterFactory.create()).baseUrl("https://api.coincap.io/v2/").client(
client).build().create(ApiInterface::class.java)
}
Основная деятельность ->
class MainActivity : ComponentActivity() {
private val viewModel by viewModels(factoryProducer = {
object : ViewModelProvider.Factory {
override fun create(modelClass: Class): T {
return CoinsViewModel(CoinRepoImpl(RetrofitInstance.api))
as T
}
}
})
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
CryptoTrackerTheme {
CoinList_Screen(viewModel = viewModel
)
}
}
}
}
ШТАТЫ ->
data class CoinUi(
val id : String,
val name : String,
val rank : Int,
val Symbol : String,
val MarketCap : FormatedNumber,
val changeIn24hr : FormatedNumber,
val price : FormatedNumber,
@DrawableRes val iconRes : Int
)
data class FormatedNumber(
val number : Double,
val formatedNumber: String
)
data class Coins(
val Coins : List
)
data class Coin2(
val changePercent24Hr: String,
val explorer: String,
val id: String,
val marketCapUsd: String,
val maxSupply: String,
val name: String,
val priceUsd: String,
val rank: String,
val supply: String,
val symbol: String,
val volumeUsd24Hr: String,
val vwap24Hr: String
)
fun Coin2.toCoin():Coin{
return Coin(
id = id,
name = name,
marketCap = marketCapUsd.toDouble(),
changeIn24Hour = changePercent24Hr.toDouble(),
rank = rank.toInt(),
priceUsd = priceUsd.toDouble(),
symbol = symbol
)
}
data class Coin(
val id : String,
val name : String,
val rank : Int,
val symbol : String,
val priceUsd : Double,
val changeIn24Hour : Double,
val marketCap : Double
)
fun Coin.toCoinUi(): CoinUi{
return CoinUi(
name = name,
id = id,
rank = rank,
Symbol = symbol,
price = priceUsd.toFormattedNumber(),
changeIn24hr = changeIn24Hour.toFormattedNumber(),
MarketCap = marketCap.toFormattedNumber(),
iconRes = getDrawableIdForCoin(symbol)
)
}
fun Double.toFormattedNumber(): FormatedNumber{
val formatter = NumberFormat.getNumberInstance(Locale.getDefault()).apply {
minimumFractionDigits = 2
maximumFractionDigits = 2
}
return FormatedNumber(number = this, formatedNumber = formatter.format(this))
}
Подробнее здесь: https://stackoverflow.com/questions/791 ... in-my-code
Я не могу изолировать проблему здесь, в моем коде. ⇐ Android
Форум для тех, кто программирует под Android
-
Anonymous
1731070799
Anonymous
Итак, я пытаюсь создать приложение coinTracker, которое отслеживает биткойны с помощью API-интерфейса Coin Cap. Но я не знаю, почему мой экран пуст. Я бы включил этот скриншот. Итак, я думаю, что либо мои списки не обновляются, либо моя функция getCoin просто работает в основном потоке. Я проверил эти две вещи, были обновления здесь и там, но я не смог изолировать проблему. Даже мой логарифм ничего не показывает.
@Composable
fun CoinList_Screen(
modifier: Modifier = Modifier,
viewModel : CoinsViewModel
){
val coinList = viewModel.coins.collectAsState().value
if(coinList.isLoading){
Box(modifier = modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
CircularProgressIndicator()
}
}else{
LazyColumn(modifier = modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(8.dp)){
items(coinList.coins){
coin ->
val coin_new = coin.toCoin()
CoinComp(coinUi =coin_new.toCoinUi(),modifier = modifier.fillMaxWidth(),{})
}
}
}
}
ViewModel –
class CoinsViewModel(
private val repo : CoinRepo
):ViewModel() {
private val _coins = MutableStateFlow(screenState())
val coins = _coins.asStateFlow()
private val showSnackar = Channel()
val showSnackBat = showSnackar.receiveAsFlow()
init{
getCoin()
}
private fun getCoin() {
viewModelScope.launch {
_coins.update {
it.copy(isLoading = true)
}
repo.getCoins().collectLatest { result ->
when (result) {
is Result.Error -> {
_coins.update {
it.copy(isLoading = false)
}
showSnackar.send(true)
}
is Result.Success -> {
result.data?.let { coin ->
_coins.update {
it.copy(
isLoading = false,
coins = coin
)
}
}
}
}
}
}
}
}
Репозитории ->
interface CoinRepo {
suspend fun getCoins(): Flow
}
class CoinRepoImpl(
private val api: ApiInterface
) :CoinRepo{
override suspend fun getCoins(): Flow {
return flow{
val coins = try {
api.getCoin()
}catch (e: IOException){
e.printStackTrace()
emit(Result.Error(message = "Error loading coins"))
return@flow
}catch (e :HttpException){
e.printStackTrace()
emit(Result.Error(message = "Error loading coins"))
return@flow
}catch(e:Exception){
e.printStackTrace()
emit(Result.Error(message = "Error loading coins"))
return@flow
}
emit(Result.Success(coins.Coins))
}
}
}
Результат –>
sealed class Result(
val data : T? = null,
val message : String? = null
){
class Success(data : T) : Result(data = data)
class Error(data : T?= null,message: String) : Result(data,message=message)
}
API ->
interface ApiInterface {
@GET("assets")
fun getCoin() : Coins
}
Модернизация экземпляра ->
object RetrofitInstance {
private val interceptor:HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
private val client: OkHttpClient = OkHttpClient.Builder().addInterceptor(interceptor).build()
val api:ApiInterface = Retrofit.Builder().addConverterFactory(GsonConverterFactory.create()).baseUrl("https://api.coincap.io/v2/").client(
client).build().create(ApiInterface::class.java)
}
Основная деятельность ->
class MainActivity : ComponentActivity() {
private val viewModel by viewModels(factoryProducer = {
object : ViewModelProvider.Factory {
override fun create(modelClass: Class): T {
return CoinsViewModel(CoinRepoImpl(RetrofitInstance.api))
as T
}
}
})
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
CryptoTrackerTheme {
CoinList_Screen(viewModel = viewModel
)
}
}
}
}
ШТАТЫ ->
data class CoinUi(
val id : String,
val name : String,
val rank : Int,
val Symbol : String,
val MarketCap : FormatedNumber,
val changeIn24hr : FormatedNumber,
val price : FormatedNumber,
@DrawableRes val iconRes : Int
)
data class FormatedNumber(
val number : Double,
val formatedNumber: String
)
data class Coins(
val Coins : List
)
data class Coin2(
val changePercent24Hr: String,
val explorer: String,
val id: String,
val marketCapUsd: String,
val maxSupply: String,
val name: String,
val priceUsd: String,
val rank: String,
val supply: String,
val symbol: String,
val volumeUsd24Hr: String,
val vwap24Hr: String
)
fun Coin2.toCoin():Coin{
return Coin(
id = id,
name = name,
marketCap = marketCapUsd.toDouble(),
changeIn24Hour = changePercent24Hr.toDouble(),
rank = rank.toInt(),
priceUsd = priceUsd.toDouble(),
symbol = symbol
)
}
data class Coin(
val id : String,
val name : String,
val rank : Int,
val symbol : String,
val priceUsd : Double,
val changeIn24Hour : Double,
val marketCap : Double
)
fun Coin.toCoinUi(): CoinUi{
return CoinUi(
name = name,
id = id,
rank = rank,
Symbol = symbol,
price = priceUsd.toFormattedNumber(),
changeIn24hr = changeIn24Hour.toFormattedNumber(),
MarketCap = marketCap.toFormattedNumber(),
iconRes = getDrawableIdForCoin(symbol)
)
}
fun Double.toFormattedNumber(): FormatedNumber{
val formatter = NumberFormat.getNumberInstance(Locale.getDefault()).apply {
minimumFractionDigits = 2
maximumFractionDigits = 2
}
return FormatedNumber(number = this, formatedNumber = formatter.format(this))
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79170122/i-am-not-able-to-isolate-the-problem-here-in-my-code[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия