亚洲情人网-亚洲情人-亚洲欧洲综合-亚洲欧洲自拍-欧美专区亚洲

androidapp開發(fā)教程(androidapp開發(fā)入門)

  • 生活
  • 2023-04-24 13:15

在上一篇文章中,我們完成了UI界面的編寫

接下來我們就要把搜索的結(jié)果,顯示在界面上。

在Android開發(fā)中有很多種方式訪問網(wǎng)絡(luò),本次視頻將向大家介紹Retrofit,

Retrofit由Square開發(fā)的,它構(gòu)建在OkHttp之上。它是一個流行的庫,可以輕松地進(jìn)行異步網(wǎng)絡(luò)調(diào)用并將JSON數(shù)據(jù)處理為模型對象。

在Android開發(fā)中有很多種方式訪問網(wǎng)絡(luò),本次視頻將向大家介紹Retrofit,Retrofit由Square開發(fā)的,它構(gòu)建在OkHttp之上。它是一個流行的庫,可以輕松地進(jìn)行異步網(wǎng)絡(luò)調(diào)用并將JSON數(shù)據(jù)處理為模型對象。本次視頻您將了解Retrofit庫的簡單實用,Moshi解析Json等知識。

在使用Retrofit之前,我們需要先在項目中添加Retrofit庫的依賴。編輯app/build.gradle文件,在dependencies閉包中添加如下內(nèi)容:

//retrofitimplementation"com.squareup.retrofit2:retrofit:2.9.0"//moshiimplementation("com.squareup.moshi:moshi-kotlin:1.12.0")//retrofitwithmoshiimplementation"com.squareup.retrofit2:converter-moshi:2.9.0"//coilimplementation("io.coil-kt:coil-compose:1.3.2")//kotlincoroutineimplementation"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3"implementation"org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3"//viewmodeldeflifecycle_version="2.3.1"implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")

retrofit庫的依賴,主要負(fù)責(zé)網(wǎng)絡(luò)請求,允許我們發(fā)送GET,POST請求

moshi庫的依賴,moshi庫將幫助我們將json數(shù)據(jù)轉(zhuǎn)換為kotlin對象

converter-moshi庫,增加了對retrofit使用moshi進(jìn)行JSON解析的支持

coil庫,允許我們使用url加載網(wǎng)絡(luò)圖片,我們可以使用少量的代碼,完成圖片的加載,coil庫也是采用kotlin編寫

kotlincoroutine,我們使用kotlincoroutine的Flow處理網(wǎng)路的異步請求

ViewModel依賴,使用ViewModel使視圖和數(shù)據(jù)能夠分離開

完成之后我們重新編譯一下項目

Postman是查看API接口返回結(jié)果非常優(yōu)秀的程序,我們啟動Postman。

使用默認(rèn)的GET***,輸入下面的URL地址https://api.map.baidu.com/weather/v1/?district_id=110100&data_type=all&ak=m5ABoErD6VuCKdyGfqoEjflYvSmn1XqR,然后單擊Send。如下圖:

在搜索結(jié)果中,將輸出類型設(shè)置為JSON。您將看到格式良好的JSON顯示:如下圖:

接下來,我們將創(chuàng)建天氣信息的數(shù)據(jù)類

數(shù)據(jù)類的創(chuàng)建,我們借助Kotlin插件,將Json字符串快速轉(zhuǎn)換為Kotlin數(shù)據(jù)類代碼

在model包下右鍵;如下圖:

點擊Advanced,這個支持(幾乎)各種JSON庫注釋(Gson、Jackson、Fastjson、MoShi和LoganSquare)這個我們選擇MoShi

點擊生成,如下圖:

這樣我們的數(shù)據(jù)類型就很方便的創(chuàng)建了。如下圖:

接下來,編寫我們的網(wǎng)絡(luò)服務(wù)

objectWeatherApiClient{privatevalBASE_URL="https://api.map.baidu.com"privatevalmoshi=Moshi.Builder().add(KotlinJsonAdapterFactory()).build()privatevalretrofit:Retrofitbylazy{Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(MoshiConverterFactory.create(moshi)).build()}valweatherApiService:WeatherApiServicebylazy{retrofit.create(WeatherApiService::class.java)}}interfaceWeatherApiService{@GET("/weather/v1/")suspendfungetWeatherData(@Query("district_id")district_id:String,@Query("data_type")data_type:String,@Query("ak")ak:String):WeatherModel}

在上面的代碼中,我們創(chuàng)建一個私有的BASE_URL變量,我們需要為moshi構(gòu)造器創(chuàng)建一個變量,添加KotlinJson的適配器工廠(KotlinJsonAdapterFactory),創(chuàng)建Retrofit,這里使用bylazy關(guān)鍵字創(chuàng)建Retrofit實例,這樣僅在需要時進(jìn)行初始化,傳入BASE_URL,添加MoshiConverterFactory轉(zhuǎn)換器工廠,然后構(gòu)建.接下來,創(chuàng)建一個接口,獲取api接口數(shù)據(jù),這里我們創(chuàng)建一個函數(shù),設(shè)置了查詢參數(shù),調(diào)用這個***就會返回查詢的數(shù)據(jù)。接下來,創(chuàng)建api接口的實例這里也是使用bylazy關(guān)鍵字創(chuàng)建延遲加載的實例,通過創(chuàng)建好的Retrofit來創(chuàng)建api接口服務(wù)。

下面創(chuàng)建Repository(數(shù)據(jù)倉庫)

classWeatherRepository{companionobject{fungetWeather(district_id:String,data_type:String,ak:String):Flow<WeatherModel>=flow{varweather=WeatherApiClient.weatherApiService.getWeatherData(district_id,data_type,ak)emit(weather)}.flowOn(Dispatchers.IO)}}

下面創(chuàng)建ViewModel

classWeatherViewModel:ViewModel(){valweatherData:MutableState<WeatherState>=mutableStateOf(WeatherState.Empty)init{getWeatherData("110100","all","m5ABoErD6VuCKdyGfqoEjflYvSmn1XqR");}fungetWeatherData(district_id:String,data_type:String,ak:String){viewModelScope.launch{WeatherRepository.getWeather(district_id,data_type,ak).onStart{weatherData.value=WeatherState.Loading}.catch{e->weatherData.value=WeatherState.Failure(e)}.collect{response->weatherData.value=WeatherState.Success(response)}}}}

在創(chuàng)建ViewModel之前,需要創(chuàng)建Model的狀態(tài)類

sealedclassWeatherState{classSuccess(valweather:WeatherModel):WeatherState()classFailure(valerror:Throwable):WeatherState()objectLoading:WeatherState()objectEmpty:WeatherState()}

創(chuàng)建好之后,我們在Activity中使用ViewModel

classMainActivity:ComponentActivity(){privatevalweatherViewModel:WeatherViewModelbyviewModels()@ExperimentalMaterialApioverridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContent{WeatherAppTheme{Surface(color=MaterialTheme.colors.background){setWeather(weatherViewModel=weatherViewModel)}}}}}

添加數(shù)據(jù)請求的狀態(tài),如下圖:

@ExperimentalMaterialApi@ComposablefunsetWeather(weatherViewModel:WeatherViewModel){when(valresult=weatherViewModel.weatherData.value){isWeatherState.Success->{Log.d("--result--",result.weather.toString())}isWeatherState.Failure->{Text(text="${result.error}")}isWeatherState.Loading->{Column(horizontalAlignment=Alignment.CenterHorizontally,modifier=Modifier.fillMaxSize().background(brush=Brush.verticalGradient(colors=listOf(color1,color2)))){Surface(onClick={},modifier=Modifier.fillMaxWidth(0.6f),color=Color.Transparent){Row(modifier=Modifier.padding(12.dp),verticalAlignment=Alignment.CenterVertically,horizontalArrangement=Arrangement.Center){CircularProgressIndicator(modifier=Modifier.height(16.dp).width(16.dp),strokeWidth=2.dp,color=Color.White)Spacer(modifier=Modifier.width(10.dp))ComposeText(text="加載天氣數(shù)據(jù)中...",textColor=Color.White,fontSize=16.sp)}}}}WeatherState.Empty->{}}}

在上面的代碼中,我們添加Loading,狀態(tài)的UI。

下面在WeatherState.Success狀態(tài)下,對UI界面賦值。

Column(horizontalAlignment=Alignment.CenterHorizontally,modifier=Modifier.fillMaxSize().background(brush=Brush.verticalGradient(colors=listOf(color1,color2)))){Spacer(modifier=Modifier.height(20.dp))LocationScreen(result.weather.result.location)Spacer(modifier=Modifier.height(40.dp))NowScreen(result.weather.result.now)Spacer(modifier=Modifier.height(20.dp))WeatherDaysScreen(result.weather.result.forecasts)}設(shè)置定位信息@ComposablefunLocationScreen(location:WeatherModel.Result.Location){ComposeText(text="${location.city},${location.name}",fontSize=30.sp)}

2.設(shè)置當(dāng)天天氣信息

@ComposablefunNowScreen(now:WeatherModel.Result.Now){Column(horizontalAlignment=Alignment.CenterHorizontally){valimg_url=when(now.text){"陰"->"http://www.moji.com/templets/mojichina/images/weather/weather/w2.png""雷陣雨"->"http://www.moji.com/templets/mojichina/images/weather/weather/w4.png""多云"->"http://www.moji.com/templets/mojichina/images/weather/weather/w1.png"else->"http://www.moji.com/templets/mojichina/images/weather/weather/w1.png"}Image(painter=rememberImagePainter(img_url),contentDescription="",modifier=Modifier.size(100.dp))ComposeText(text="${now.temp}°",fontSize=48.sp)}Surface(modifier=Modifier.fillMaxWidth(0.5f),color=color3,shape=RoundedCornerShape(48)){Row(horizontalArrangement=Arrangement.SpaceBetween,verticalAlignment=Alignment.CenterVertically,modifier=Modifier.fillMaxWidth().padding(8.dp)){ComposeText(text="${now.windDir}",textColor=colortext,fontSize=12.sp)ComposeText(text="${now.windClass}",textColor=colortext,fontSize=12.sp)ComposeText(text="濕度",textColor=colortext,fontSize=12.sp)ComposeText(text="${now.rh}%",textColor=colortext,fontSize=12.sp)}}}

3.設(shè)置未來5天的天氣信息

@ComposablefunWeatherDaysScreen(forecasts:List<WeatherModel.Result.Forecast>){LazyRow{items(forecasts){forecast->WeatherItems(forecast)}}}@ComposablefunWeatherItems(forecast:WeatherModel.Result.Forecast){Column(horizontalAlignment=Alignment.CenterHorizontally,modifier=Modifier.padding(start=8.dp,end=10.dp)){ComposeText(text="${forecast.week}",fontSize=16.sp)Spacer(modifier=Modifier.height(18.dp))valimg_url=when(forecast.textDay){"陰"->"http://www.moji.com/templets/mojichina/images/weather/weather/w2.png""雷陣雨"->"http://www.moji.com/templets/mojichina/images/weather/weather/w4.png""多云"->"http://www.moji.com/templets/mojichina/images/weather/weather/w1.png"else->"http://www.moji.com/templets/mojichina/images/weather/weather/w1.png"}Image(painter=rememberImagePainter(img_url),contentDescription="",modifier=Modifier.size(50.dp))Spacer(modifier=Modifier.height(2.dp))ComposeText(text="${forecast.high}°/${forecast.low}°",fontSize=22.sp)}}

猜你喜歡

主站蜘蛛池模板: 九色精品高清在线播放 | 婷婷亚洲综合五月天小说在线 | 视频一区欧美 | 欧美久久综合九色综合 | 亚洲六月丁香婷婷综合 | 日韩城人视频 | 亚洲天堂资源网 | 在线观看日韩欧美 | 亚洲天堂第一页 | 久久综合九色综合欧洲 | 成人羞羞视频在线观看免费 | 在线免费国产 | 九九365资源稳定资源站 | 亚洲精品乱码久久久久 | 日本免费二区三区久久 | 四虎4hu亚洲精品 | 大量精子注入波多野结衣 | 五月婷婷激情 | 精品中文字幕乱码一区二区 | 日韩极品视频 | 羞羞视频在线免费观看 | 深爱激情站| 日本国产在线观看 | 日韩综合网站 | 伊人情人综合网 | 人人爽人人爽人人片av | 亚洲成人国产 | 亚洲狠狠成人综合网 | 久久久久久九九 | 中文国产成人精品久久久 | 国产97在线视频观看 | 羞羞视频在线免费观看 | 国产成人精品久久亚洲高清不卡 | 蜜桃视频黄色 | 丝袜天堂 | 九月丁香婷婷亚洲综合色 | 丁香五月亚洲综合在线 | 小处雏高清一区二区三区 | 久久精品成人一区二区三区 | 亚洲国产欧美日韩精品一区二区三区 | 欧美一级久久 |