首页 >> 教育

androidapp开发教程(androidapp开发入门)

2022年04月13日 02:56:03 教育 40 投稿:用户投稿
androidapp开发教程

在上一篇文章中,我们完成了UI界面的编写

接下来我们就要把搜索的结果,显示在界面上。

在Android开发中有很多种方式访问网络,本次视频将向大家介绍Retrofit,

Retrofit由Square 开发的,它构建在OkHttp之上。它是一个流行的库,可以轻松地进行异步网络调用并将JSON数据处理为模型对象。

在Android开发中有很多种方式访问网络,本次视频将向大家介绍Retrofit,Retrofit由Square 开发的,它构建在OkHttp之上。它是一个流行的库,可以轻松地进行异步网络调用并将JSON数据处理为模型对象。本次视频您将了解Retrofit库的简单实用,Moshi解析Json等知识。

在使用Retrofit之前,我们需要先在项目中添加Retrofit库的依赖。编辑app/build.gradle文件,在dependencies闭包中添加如下内容:

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

retrofit库的依赖,主要负责网络请求,允许我们发送GET,POST请求

moshi库的依赖,moshi库将帮助我们将json数据转换为kotlin对象

converter-moshi库,增加了对retrofit使用moshi进行JSON解析的支持

coil库,允许我们使用url加载网络图片,我们可以使用少量的代码,完成图片的加载,coil库也是采用kotlin编写

kotlin coroutine,我们使用kotlin coroutine 的Flow处理网路的异步请求

ViewModel依赖,使用ViewModel使视图和数据能够分离开

完成之后我们重新编译一下项目

Postman是查看API接口返回结果非常优秀的程序,我们启动Postman。

使用默认的GET方法,输入下面的URL地址https://api.map.baidu.com/weather/v1/?district_id=110100&data_type=all&ak=m5ABoErD6VuCKdyGfqoEjflYvSmn1XqR,然后单击Send。如下图:

androidapp开发教程

在搜索结果中,将输出类型设置为JSON。您将看到格式良好的JSON显示:如下图:

androidapp开发教程

接下来,我们将创建天气信息的数据类

数据类的创建,我们借助Kotlin插件,将Json字符串快速转换为Kotlin数据类代码

在model包下右键;如下图:

androidapp开发教程

androidapp开发教程

点击 Advanced,这个支持(几乎)各种JSON库注释(Gson、Jackson、Fastjson、MoShi和LoganSquare)这个我们选择MoShi

点击生成,如下图:

androidapp开发教程

这样我们的数据类型就很方便的创建了。如下图:

androidapp开发教程

接下来,编写我们的网络服务

object WeatherApiClient { private val BASE_URL = "https://api.map.baidu.com" private val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() private val retrofit: Retrofit by lazy { Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(MoshiConverterFactory.create(moshi)) .build() } val weatherApiService: WeatherApiService by lazy { retrofit.create(WeatherApiService::class.java) }}interface WeatherApiService{ @GET("/weather/v1/") suspend fun getWeatherData(@Query("district_id") district_id: String, @Query("data_type") data_type: String, @Query("ak") ak: String) : WeatherModel}

在上面的代码中,我们创建一个私有的BASE_URL变量,我们需要为moshi构造器创建一个变量,添加KotlinJson的适配器工厂 (KotlinJsonAdapterFactory),创建Retrofit,这里使用by lazy 关键字创建Retrofit实例,这样仅在需要时进行初始化,传入BASE_URL,添加MoshiConverterFactory转换器工厂,然后构建.接下来,创建一个接口,获取api接口数据,这里我们创建一个函数,设置了查询参数,调用这个方法就会返回查询的数据。接下来,创建api接口的实例 这里也是使用by lazy关键字创建延迟加载的实例,通过创建好的Retrofit来创建api接口服务。

下面创建Repository(数据仓库)

class WeatherRepository { companion object{ fun getWeather(district_id: String, data_type: String, ak: String): Flow<WeatherModel> = flow { var weather = WeatherApiClient.weatherApiService.getWeatherData( district_id, data_type, ak ) emit(weather) }.flowOn(Dispatchers.IO) }}

下面创建ViewModel

class WeatherViewModel: ViewModel() { val weatherData: MutableState<WeatherState> = mutableStateOf(WeatherState.Empty) init { getWeatherData("110100","all","m5ABoErD6VuCKdyGfqoEjflYvSmn1XqR"); } fun getWeatherData(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) } } }}

在创建ViewModel之前,需要创建Model的状态类

sealed class WeatherState { class Success(val weather: WeatherModel) : WeatherState() class Failure(val error: Throwable) : WeatherState() object Loading : WeatherState() object Empty : WeatherState()}

创建好之后,我们在Activity中使用ViewModel

class MainActivity : ComponentActivity() { private val weatherViewModel: WeatherViewModel by viewModels() @ExperimentalMaterialApi override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { WeatherAppTheme { Surface(color = MaterialTheme.colors.background) { setWeather(weatherViewModel = weatherViewModel) } } } }}

添加数据请求的状态,如下图:

androidapp开发教程

@ExperimentalMaterialApi@Composablefun setWeather(weatherViewModel: WeatherViewModel) { when (val result = weatherViewModel.weatherData.value) { is WeatherState.Success -> { Log.d("--result--",result.weather.toString()) } is WeatherState.Failure -> { Text(text = "${result.error}") } is WeatherState.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 = "加载天气数据中...", textColor = Color.White, fontSize = 16.sp) } } } } WeatherState.Empty -> { } }}

在上面的代码中,我们添加Loading,状态的UI。

下面在WeatherState.Success状态下,对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)}设置定位信息@Composablefun LocationScreen(location: WeatherModel.Result.Location) { ComposeText(text = "${location.city},${location.name}",fontSize = 30.sp)}

2.设置当天天气信息

@Composablefun NowScreen(now: WeatherModel.Result.Now) { Column(horizontalAlignment = Alignment.CenterHorizontally) { val img_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.设置未来5天的天气信息

@Composablefun WeatherDaysScreen(forecasts: List<WeatherModel.Result.Forecast>) { LazyRow { items(forecasts){ forecast -> WeatherItems(forecast) } }}@Composablefun WeatherItems(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)) val img_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) }}androidapp开发教程

版权声明:
本文内容由互联网用户自发贡献,该文观点仅代表作者本人,因此内容不代表本站观点、本站不对文章中的任何观点负责,内容版权归原作者所有、内容只用于提供信息阅读,无任何商业用途。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站(文章、内容、图片、音频、视频)有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至353049283@qq.com举报,一经查实,本站将立刻删除、维护您的正当权益。
tags:

关于我们

主题百科知识栏目每天分享日常生活小知识,互联为资讯,IT科技百科,家常知识科普等,旨在让大家快乐生活,开心学习,主题百科为您分享!

最火推荐

小编推荐

联系我们


Copyright 帝国主题之家 版权所有 TXT地图 | XML地图 | HTML地图 深圳市南山区海象营销策划工作室 备案号:粤ICP备2020139403号