Android Studio中天气API调用与定制求助(需实现指定天气界面)
Android天气界面实现指南(API调用+UI定制)
一、选API并获取密钥
- 优先选免费且文档友好的天气API,比如OpenWeatherMap、和风天气,注册账号就能拿到API密钥(API Key),免费额度足够新手开发测试。
- 拿到密钥后先在浏览器测试接口,比如OpenWeatherMap的当前天气请求:
https://api.openweathermap.org/data/2.5/weather?q=Beijing&appid=你的密钥,确认能返回合法JSON数据。
二、配置项目网络权限
在AndroidManifest.xml中添加必要权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
如果是Android 9及以上,要么用HTTPS接口,要么在res/xml/network_security_config.xml中配置允许明文请求,再在Manifest的application标签里关联:
android:networkSecurityConfig="@xml/network_security_config"
三、用Retrofit实现网络请求
Retrofit是Android主流网络框架,配置简单易维护:
- 在模块级
build.gradle添加依赖:
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.github.bumptech.glide:glide:4.15.1' // 用于加载天气图标
- 创建API接口类:
interface WeatherApi { @GET("data/2.5/weather") suspend fun getCurrentWeather( @Query("q") cityName: String, @Query("appid") apiKey: String, @Query("units") units: String = "metric" // 指定摄氏度单位 ): Response<WeatherResponse> }
- 根据API返回的JSON结构生成数据模型类(可借助GsonFormat插件自动生成),比如
WeatherResponse,包含城市名、温度、湿度、天气图标代码等核心字段。 - 初始化Retrofit并发起协程请求(避免主线程阻塞):
val retrofit = Retrofit.Builder() .baseUrl("https://api.openweathermap.org/") .addConverterFactory(GsonConverterFactory.create()) .build() val weatherApi = retrofit.create(WeatherApi::class.java) // 在Activity/Fragment的协程作用域中发起请求 lifecycleScope.launch { try { val response = weatherApi.getCurrentWeather("Beijing", "你的API密钥") if (response.isSuccessful) { response.body()?.let { updateWeatherUI(it) } } else { // 处理请求失败逻辑,比如弹Toast提示 } } catch (e: Exception) { // 处理网络异常,比如无网络时的提示 } }
四、定制UI匹配目标界面
参考你提供的界面,用基础布局组件实现:
- 编写布局文件示例:
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <TextView android:id="@+id/tv_city" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="24sp" android:text="Beijing"/> <TextView android:id="@+id/tv_temp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="48sp" android:text="25°C"/> <ImageView android:id="@+id/iv_weather_icon" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center_horizontal" android:layout_marginVertical="16dp"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/tv_humidity" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Humidity: 60%"/> <TextView android:id="@+id/tv_wind" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Wind: 3m/s"/> </LinearLayout> </LinearLayout>
- 编写UI更新方法:
private fun updateWeatherUI(data: WeatherResponse) { tv_city.text = data.name tv_temp.text = "${data.main.temp}°C" // 拼接图标URL并加载 val iconUrl = "https://openweathermap.org/img/wn/${data.weather[0].icon}@2x.png" Glide.with(this).load(iconUrl).into(iv_weather_icon) tv_humidity.text = "Humidity: ${data.main.humidity}%" tv_wind.text = "Wind: ${data.wind.speed}m/s" }
五、关键注意事项
- 不要硬编码API密钥,建议放在
local.properties中,通过build.gradle引用,防止密钥泄露。 - 务必处理各种异常场景(无网络、请求超时、API返回错误码等),给用户明确提示。
- 如果需要自动获取当前城市,可结合Android定位API拿到经纬度,调用API的经纬度查询接口替代城市名参数。
内容的提问来源于stack exchange,提问作者Huỳnh Nam
相关产品推荐
相关产品推荐

