专栏首页IT派一个实例学习Kotlin 开发 Android App 的全过程(内有代码)

一个实例学习Kotlin 开发 Android App 的全过程(内有代码)

自 Google I/O 大会,Google 正式宣布 Kotlin 成为 Android 开发的官方语言的五个月以来,不少开发团队都开始使用 Kotlin 对 Android 应用进行重写。本文分享一款完整的案例——欧瑞天气,希望通过这个项目,让读者了解利用 Kotlin 开发 Android App 的全过程。

1

项目概述

这款App用于从服务端获取天气预报信息,并显示在窗口区域。这款App会首先列出省级及其所辖城市和县区信息,如图1所示。

图1 列出省级及其所辖城市和县区信息

当单击某个城市或县区名称时,会在窗口上显示该城市或县区的天气情况,如图2所示。

图2 显示天气情况

这款App使用前面章节介绍的UI技术、网络技术,并且使用Kotlin语言编写。其中有一些Library使用了Java编写,实际上,这款App是Kotlin和Java的结合体。

2

添加依赖

在App中使用了大量的第三方Library,如gson、okhttp3、glide等,这些Library需要在app/build.gradle文件中的dependencies部分指定,如下所示:

dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" compile 'com.android.support:appcompat-v7:25.1.1' testCompile 'junit:junit:4.12' compile 'com.android.support.constraint:constraint-layout:1.0.2' implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" implementation 'com.google.code.gson:gson:2.8.1' implementation 'com.squareup.okhttp3:okhttp:3.8.1' implementation 'com.github.bumptech.glide:glide:4.0.0-RC1' implementation 'com.android.support.constraint:constraint-layout:1.0.2' }

3

实现主窗口

主窗口类是MainActivity,这是该App第一个要启动的窗口。该窗口类的实现代码如下:

Kotlin代码(主窗口类)

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val prefs = PreferenceManager.getDefaultSharedPreferences(this) if (prefs.getString("weather", ) != null) { val intent = Intent(this, WeatherActivity::class.java) startActivity(intent) finish() } } }

我们可以看到,MainActivity类的实现代码并不复杂,其中利用SharedPreferences对象读取了配置信息weather,这个配置信息用于指明是否曾经查询过某个城市的天气,如果查询过,直接显示该城市的天气信息。这里面涉及一个WeatherActivity类,这是专门用于显示天气信息的窗口。

下面看一下MainActivity使用的布局文件(activity_main.xml)。

<framelayout< span=""></framelayout<> xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment< span=""></fragment<> android:id="@+id/choose_area_fragment" android:name="com.oriweather.fragment.ChooseAreaFragment" android:layout_width="match_parent" android:layout_height="match_parent" />

在布局文件中,使用标签引用了一个ChooseAreaFragment类,这是什么呢?实际上,Fragment是从Android 3.0开始加入的类,相当于一个透明的Panel,用于封装逻辑和UI,可以作为一个组件使用。ChooseAreaFragment的作用就是实现城市和县区列表,以便单击可以显示相应地区的天气情况。

4

显示地区列表

ChooseAreaFragment封装了显示地区列表的逻辑,但是只有ChooseAreaFragment类还不够,还需要很多辅助类来完成相应的工作。例如,地区列表是从服务端获取的JSON数据,因此,需要有相应的类来完成从网络上获取数据的工作,而且获取的是JSON格式的数据。因此,在使用这些数据之前,需要先将其转换为Kotlin类。本节除了实现ChooseAreaFragment类外,还会讲解如何实现这些辅助类。

描述城市信息的数据类

从服务端获取的地区信息有3个级别:省、市和县区。这3个级别分别需要一个数据类描述。

Kotlin代码(数据类)

// 描述省信息的数据类 data class Province(var id:Int = 0, var provinceName:String, var proinceCode:String) // 描述市信息的数据类 data class City(var id:Int = 0, var cityName:String, var cityCode:String, var provinceCode:String) // 描述县区信息的数据类 data class County(var id:Int = 0, var countyName:String, var countyCode:String, var cityCode:String)

处理JSON格式的城市列表信息

当JSON格式的数据从服务端获取后,需要对这些数据进行解析。这个工作是由Utility对象完成的。

Kotlin代码(解析JSON格式的数据)

object Utility { // 解析和处理服务器返回的省级数据 fun handleProvinceResponse(response: String): List{ var provinces = mutableListOf() if (!TextUtils.isEmpty(response)) { try { // 将JSON数组转换为Kotlin数组形式 val allProvinces = JSONArray(response) // 对数组循环处理,每一次循环都会创建一个Province对象 for (i in 0..allProvinces.length() - 1) { val provinceObject = allProvinces.getJSONObject(i) val province = Province(provinceName = provinceObject.getString("name"),proinceCode = provinceObje ct.getString("id")) provinces.add(provinces.size, province) } } catch (e: JSONException) { e.printStackTrace() } } return provinces } // 解析和处理服务器返回的市级数据 fun handleCityResponse(response: String, provinceCode: String): List{ var cities = mutableListOf() if (!TextUtils.isEmpty(response)) { try { val allCities = JSONArray(response) for (i in 0..allCities.length() - 1) { val cityObject = allCities.getJSONObject(i) val city = City(cityName = cityObject.getString("name"),cityCode = cityObject.getString("id"),provinceCode = provinceCode) cities.add(city) } } catch (e: JSONException) { e.printStackTrace() } } return cities } // 解析和处理服务器返回的县区级数据 fun handleCountyResponse(response: String, cityCode: String): List{ var counties = mutableListOf() if (!TextUtils.isEmpty(response)) { try { val allCounties = JSONArray(response) for (i in 0..allCounties.length() - 1) { val countyObject = allCounties.getJSONObject(i) val county = County(countyName = countyObject.getString("name"), countyCode = countyObject.getString("id"),cityCode = cityCode) counties.add(county) } } catch (e: JSONException) { e.printStackTrace() } } return counties } // 将返回的JSON数据解析成Weather实体类 fun handleWeatherResponse(response: String): Weather? { try { val jsonObject = JSONObject(response) val jsonArray = jsonObject.getJSONArray("HeWeather") val weatherContent = jsonArray.getJSONObject(0).toString() return Gson().fromJson(weatherContent, Weather::class.java) } catch (e: Exception) { e.printStackTrace() } return null } }

在Utility对象中有4个方法,其中前3个方法用于分析省、市和县区级JSON格式数据,并将这些数据转换为相应的对象。第4个方法用于分析描述天气信息的JSON数据,而且未使用Android SDK标准的API进行分析,而是使用了gson开源库对JSON数据进行分析,并返回一个Weather对象,Weather类与其他相关类的定义需要符合gson标准,这些内容会在下一节介绍。

天气信息描述类

为了演示Kotlin与Java混合开发,描述天气信息的类用Java编写。其中Weather是用于描述天气的信息的主类,还有一些相关的类一同描述整个天气信息,如Basic、AQI、Now等。总之,这些类是由服务端返回的JSON格式天气信息决定的。获取天气信息的URL格式如下:

https://geekori.com/api/weather/?id=weather_id

这里的weather_id就是地区编码,如沈阳市和平区的编码是210102。获取该地区天气信息的URL如下:

https://geekori.com/api/weather/?id=210102

Weather以及相关类的实现代码如下:

Java代码(Weather类)

public class Weather { public String status; public Basic basic; public AQI aqi; public Now now; public Suggestion suggestion; @SerializedName("daily_forecast") public ListforecastList; } Java代码(Basic类) public class Basic { @SerializedName("city") public String cityName; @SerializedName("id") public String weatherId; public Update update; public class Update { @SerializedName("loc") public String updateTime; } } Java代码(AQI类) public class AQI { public AQICity city; public class AQICity { public String aqi; public String pm25; } } Java代码(Now类) public class Now { @SerializedName("tmp") public String temperature; @SerializedName("cond") public More more; public class More { @SerializedName("txt") public String info; } } Java代码(Suggestion类) public class Suggestion { @SerializedName("comf") public Comfort comfort; @SerializedName("cw") public CarWash carWash; public Sport sport; public class Comfort { @SerializedName("txt") public String info; } public class CarWash { @SerializedName("txt") public String info; } public class Sport { @SerializedName("txt") public String info; } }

由于原文过长,本文进行了一些适当的删减。以上内容实现了一个Android App,尽管这个App不算大,但完全可以演示使用Kotlin开发Android App的完整过程。本章实现的App综合使用了UI、Activity、布局、网络等技术。希望读者根据本书提供的Demo源代码以及本书讲解的知识独立完成这个项目,这样会让自己的Android和Kotlin开发功力有大幅度提升。

本章节选自图书《Kotlin 程序开发入门精要》的第十六章内容。

本文分享自微信公众号 - IT派(it_pai)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-03-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android开发:Kotlin 取代 Java 只是时间问题?

    IT派 - {技术青年圈} 持续关注互联网、区块链、人工智能领域 在使用Kotlin进行了一段时间的Android开发之后,我深深地体验到了它的美好,Kot...

    IT派
  • 苏宁闯入二手房市场,每套服务费仅9999元

    在这个充满变数的年代,你永远不知道自己的下一个对手会是谁,继阿里、京东后,又一电商巨头“跨界打劫”,强势杀入房地产经纪市场。

    IT派
  • 从 Java 到 Kotlin,再从 Kotlin 回归 Java

    作者是 Allegro 的一名技术人员。Allegro 拥有超过 50 个开发团队。可以自由选择 他们的 PaaS 所支持的技术。他们主要使用 Java、Ko...

    IT派
  • 手把手教你从零开始做一个好看的 APP - Day four

    本文为 手把手教你从零开始做一个好看的 APP - Day four ,如果想看该系列的其他文章,请点击以下连接

    developerHaoz
  • Android 天气APP(二十三)增加灾害预警、优化主页面UI

    天气预报光有普通天气总感觉好少了点什么,所以和风天气给不上了,那就是灾害天气的预警,灾害预警API可以获取指定城市的极端天气预警数据。

    晨曦_LLW
  • Android点将台:你敢摸我猫 [- IPC -]

    张风捷特烈
  • Android WebView交互传递json字符串并解析的方法

    我们大家都知道WebView交互中可以传递基本数据类型的数据值,比如常用的int,String.

    砸漏
  • 教你用Java字节码做日志脱敏工具

    本篇是本系列的最后一篇,在这篇中教你用ASM实际开发中做一些可用的东西。包括之前说的如何修改toString,完成一些脱敏。

    用户5397975
  • 软件工程六大设计原则总结,案例演示

    知了一笑
  • Android viewpager自动轮播和小圆点联动效果

    本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下

    砸漏

扫码关注云+社区

领取腾讯云代金券