Android 天气APP(二十)增加欢迎页及白屏黑屏处理、展示世界国家/地区的城市数据
上一篇:Android 天气APP(十九)更换新版API接口(更高、更快、更强)
文本最终效果图

前言
本来这一篇文章应该和上一篇放到一起的,但是考虑到篇幅的问题,我就分成两篇文章了,我真的很怕读者看的时候失去动力,动不动就七八万字的博客,看着就害怕。虽然主要是代码比较多,中间穿插一些讲解而已。开始吧!
正文
我相信很多APP都会有这个欢迎页的,也就是启动页面,常规的就是一个页面展示APP的定位,还有就是广告之类的。这个页面更多的功能其实是对APP冷启动和数据的处理,相当于一个缓冲区。先来看一下白屏黑屏的效果

可以看到虽然这个GIF很多,白屏和黑屏的时间也很短,一刹那间就过去了,但这个就是细节啊,你不处理能行吗?
再看优化后的

这样虽然说看上去没有啥太大的作用,但是体验就会比较好呀,你说呢?
好了接下来看怎么实现的。
一、欢迎页及黑白屏处理
先创建一个SplashActivity的EmptyActivity,
这里放入启动页的背景图片

然后修改布局文件activity_splash.xml

直接改为ImageView,OK,现在这里就不用管了,进入AndroidManifest.xml

将MainActivit下面的intent-filter剪切到SplashActivity下来,意思就是把SplashActivity作为第一个页面。

进入styles.xml新增
- "android:windowIsTranslucent">true
- "android:windowBackground">@android:color/transparent
如下图所示

这个意思就是将APP的所以主题背景改为透明,这样就不存在黑屏白屏的问题了,现在你运行一下之后就不会有这个黑屏白屏了,其实这种处理方式不止一种,更多的方法给我留言,我会考虑单独写一篇博客来讲这个白屏和黑屏的处理。然后我们要在SplashActivity中进行页面的跳转。
写一个延时跳转方法
/*** 进入主页面*/private void goToMain() {new Handler().postDelayed(new Runnable() {@Overridepublic void run() {finish();Intent intent = new Intent(context, MainActivity.class);startActivity(intent);}}, 1000);}
然后在onCreate方法中调用即可。因为现在所有Activity的背景色都变了透明,所以记得在每个Acitivity对应的布局文件中,在主布局中,如果没有设置背景颜色就增加背景颜色,通常是白色就可以了,否则会出现诡异的现象。
这里先告一段落。
二、世界城市
首先把之前的关于热门城市的东西都删掉,这个里面和热门城市就已经没有关系了。
首先要获取到世界国家/地区的列表。和风提供的国家/地区的城市代码是用的.csv格式,也就是说需要在Android中需要读取CSV文件中的数据读取。可以看看这一篇文章Android 读取csv格式数据文件,

这是我自己弄好的一个文件,和风的都是英文的,所以我就自己翻译好了,需要的就直接到项目中去下载好了,像这种文件,通常都是放在欢迎页中就要完成数据读取的。这里使用Sqlite来保存这些数据吧。在mvplibrary中的bean中新建一个Country实体

代码如下:
package com.llw.mvplibrary.bean;import org.litepal.crud.LitePalSupport;public class Country extends LitePalSupport {private String name;//名称private String code;//代码public String getName() {return name;}public void setName(String name) {this.name = name;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}
}

新增一个映射,然后版本改为2。
数据库有了,然后就是数据读取和填充了,回到SplashActivity
新增如下代码:
private List<Country> list;//数据列表private void initCountryData() {list = LitePal.findAll(Country.class);if (list.size() > 0){//有数据了goToMain();}else {//第一次加载InputStreamReader is = null;try {is = new InputStreamReader(getAssets().open("world_country.csv"), "UTF-8");BufferedReader reader = new BufferedReader(is);reader.readLine();String line;while ((line = reader.readLine()) != null) {String[] result = line.split(",");Country country = new Country();country.setName(result[0]);country.setCode(result[1]);country.save();}goToMain();} catch (IOException e) {e.printStackTrace();}}}
在这方法中,先获取是否存在数据,不存在则读取文件中的数据,遍历每一行,遍历之后逗号截取为字符串数组分别赋值,最后保存数据,保存好之后则进入主页面,如果已有数据则直接进入主页面。其实我们还可以把权限请求也放到这个里面来,这样就不用在MainActivity中进行动态权限请求了。很多APP都会在第一启动的时候请求所需要的权限,达到一劳永逸。

现在只要进入到MainActivity中就开始定位,当然如果你没有权限你就看不到这个页面。
现在回到SplashActivity中,先继承BaseActivity,实现两个对应的方法,删除onCreate方法。
private RxPermissions rxPermissions;//权限请求框架@Overridepublic void initData(Bundle savedInstanceState) {StatusBarUtil.transparencyBar(context);//透明状态栏rxPermissions = new RxPermissions(this);//实例化这个权限请求框架,否则会报错permissionVersion();//权限判断}//权限判断private void permissionVersion() {if (Build.VERSION.SDK_INT >= 23) {//6.0或6.0以上//动态权限申请permissionsRequest();} else {//6.0以下//发现只要权限在AndroidManifest.xml中注册过,均会认为该权限granted 提示一下即可ToastUtils.showShortToast(this, "你的版本在Android6.0以下,不需要动态申请权限。");}}//动态权限申请private void permissionsRequest() {//使用这个框架需要制定JDK版本,建议用1.8rxPermissions.request(Manifest.permission.ACCESS_FINE_LOCATION).subscribe(granted -> {if (granted) {//申请成功//得到权限可以进入APP//加载世界国家数据到本地数据库,已有则不加载initCountryData();} else {//申请失败finish();ToastUtils.showShortToast(this, "权限未开启");}});}
这个代码之前我已经解释过一次,就不再做解释了。现在这个欢迎页的使命就已经完成了。OK,世界城市数据有了,下面就是怎么显示的问题了。
在app的ui包下,新建WorldCityActivity。然后修改activity_world_city.xml,代码如下:
"1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:orientation="vertical"android:fitsSystemWindows="true"android:background="@color/shallow_gray"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".ui.WorldCityActivity">android:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"android:background="@color/white"app:layout_constraintEnd_toEndOf="parent"app:navigationIcon="@mipmap/icon_return"app:contentInsetLeft="@dimen/dp_16"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toTopOf="parent"app:popupTheme="@style/AppTheme.PopupOverlay">android:id="@+id/tv_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textSize="@dimen/sp_16"android:textColor="@color/black"android:text="国家/地区" /> android:id="@+id/rv"android:background="@color/white"android:layout_marginTop="@dimen/dp_2"android:paddingBottom="@dimen/dp_10"android:layout_width="match_parent"android:layout_height="match_parent"/>
在contract包下新建一个WorldCityContract
代码如下:
package com.llw.goodweather.contract;import com.llw.goodweather.api.ApiService;
import com.llw.goodweather.bean.WorldCityResponse;
import com.llw.mvplibrary.base.BasePresenter;
import com.llw.mvplibrary.base.BaseView;
import com.llw.mvplibrary.net.NetCallBack;
import com.llw.mvplibrary.net.ServiceGenerator;import retrofit2.Call;
import retrofit2.Response;/*** 世界城市订阅器*/
public class WorldCityContract {public static class WorldCityPresenter extends BasePresenter<IWorldCityView> {/*** 世界城市 V7* @param range 类型*/public void worldCity(String range) {ApiService service = ServiceGenerator.createService(ApiService.class, 4);//指明访问的地址service.worldCity(range).enqueue(new NetCallBack<WorldCityResponse>() {@Overridepublic void onSuccess(Call<WorldCityResponse> call, Response<WorldCityResponse> response) {if(getView() != null){getView().getWorldCityResult(response);}}@Overridepublic void onFailed() {if(getView() != null){getView().getDataFailed();}}});}}public interface IWorldCityView extends BaseView {//热门城市返回数据 V7void getWorldCityResult(Response<WorldCityResponse> response);//错误返回void getDataFailed();}
}
在layout下新建一个item_country_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:background="@color/white"android:layout_width="match_parent"android:layout_height="wrap_content"><TextViewandroid:id="@+id/tv_country_name"android:text="国家"android:padding="@dimen/dp_16"android:textColor="@color/black"android:textSize="@dimen/sp_16"android:ellipsize="end"android:background="?android:attr/selectableItemBackground"android:maxLines="1"android:layout_width="match_parent"android:layout_height="wrap_content"/><LinearLayoutandroid:layout_marginLeft="@dimen/dp_16"android:background="@color/line_gray"android:layout_width="match_parent"android:layout_height="@dimen/dp_1"/></LinearLayout>
用于展示世界上的国家/地区
然后就是适配器了。在adapter下新建一个CountryAdapter,代码如下:
package com.llw.goodweather.adapter;import androidx.annotation.Nullable;import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.llw.goodweather.R;
import com.llw.mvplibrary.bean.Country;import java.util.List;/*** 国家列表适配器*/
public class CountryAdapter extends BaseQuickAdapter<Country, BaseViewHolder> {public CountryAdapter(int layoutResId, @Nullable List<Country> data) {super(layoutResId, data);}@Overrideprotected void convert(BaseViewHolder helper, Country item) {helper.setText(R.id.tv_country_name,item.getName());helper.addOnClickListener(R.id.tv_country_name);}
}

继承MvpActivity,然后实现方法,下面会逐个说明
初始化这个页面控件,和创建对象
@BindView(R.id.tv_title)TextView tvTitle;@BindView(R.id.toolbar)Toolbar toolbar;@BindView(R.id.rv)RecyclerView rv;CountryAdapter mAdapter;List<Country> mList = new ArrayList<>();
在initData中,这个其实就是取代了onCreate,所以onCreate可以删掉了。
@Overridepublic void initData(Bundle savedInstanceState) {StatusBarUtil.setStatusBarColor(context, R.color.white);//白色底 状态栏StatusBarUtil.StatusBarLightMode(context);//黑色字体Back(toolbar);initList();}
@Overridepublic int getLayoutId() {return R.layout.activity_world_city;}@Overrideprotected WorldCityContract.WorldCityPresenter createPresent() {return new WorldCityContract.WorldCityPresenter();}
/*** 初始化列表数据*/private void initList() {mList = LitePal.findAll(Country.class);mAdapter = new CountryAdapter(R.layout.item_country_list, mList);rv.setLayoutManager(new LinearLayoutManager(context));rv.setAdapter(mAdapter);mAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {@Overridepublic void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {showLoadingDialog();mPresent.worldCity(mList.get(position).getCode());}});}
/*** 世界城市返回* @param response*/@Overridepublic void getWorldCityResult(Response<WorldCityResponse> response) {}/*** 失败异常返回*/@Overridepublic void getDataFailed() {dismissLoadingDialog();ToastUtils.showShortToast(context,"其他异常");}
现在只要运行就会看到国家/地区数据

然后做这个点击之后的城市弹窗
首先是弹窗的布局。
在layout下新建window_world_city_list.xml
代码如下:
"1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:orientation="vertical"android:fitsSystemWindows="true"android:background="@color/white"android:layout_width="wrap_content"android:layout_height="match_parent"tools:ignore="MissingDefaultResource">android:id="@+id/tv_title"android:gravity="center"android:textColor="@color/black"android:padding="@dimen/dp_16"android:textSize="@dimen/sp_16"android:textStyle="bold"android:layout_width="@dimen/dp_240"android:layout_height="?attr/actionBarSize"/>android:layout_width="@dimen/dp_240"android:layout_height="@dimen/dp_2"android:background="@color/line_gray"/>android:id="@+id/rv_city"android:layout_width="@dimen/dp_240"android:layout_height="match_parent"/>
在adapter中新建一个WorldCityAdapter,代码如下:
package com.llw.goodweather.adapter;import androidx.annotation.Nullable;import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.llw.goodweather.R;
import com.llw.goodweather.bean.WorldCityResponse;import java.util.List;/*** 国家/地区中的城市适配器*/
public class WorldCityAdapter extends BaseQuickAdapter<WorldCityResponse.TopCityListBean, BaseViewHolder> {public WorldCityAdapter(int layoutResId, @Nullable List<WorldCityResponse.TopCityListBean> data) {super(layoutResId, data);}@Overrideprotected void convert(BaseViewHolder helper, WorldCityResponse.TopCityListBean item) {helper.setText(R.id.tv_city,item.getName());helper.addOnClickListener(R.id.tv_city);}
}
回到WorldCityActivity

新增

点击列表中某一个国家,然后获取到这个code,通过code来请求接口获取城市数据,然后返回中将城市的数据传递到弹窗中,在弹窗中渲染数据。

城市弹窗代码如下:
/*** 城市弹窗*/private void showCityWindow(String countryName,List<WorldCityResponse.TopCityListBean> list) {LiWindow liWindow = new LiWindow(context);final View view = LayoutInflater.from(context).inflate(R.layout.window_world_city_list, null);TextView windowTitle = (TextView) view.findViewById(R.id.tv_title);windowTitle.setText(countryName);RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.rv_city);liWindow.showRightPopupWindowMatchParent(view);//显示弹窗mCityAdapter = new WorldCityAdapter(R.layout.item_city_list,list);recyclerView.setLayoutManager(new LinearLayoutManager(context));recyclerView.setAdapter(mCityAdapter);mCityAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {@Overridepublic void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {Intent intent = new Intent(context, WorldCityWeatherActivity.class);intent.putExtra("name",list.get(position).getName());intent.putExtra("locationId",list.get(position).getId());startActivity(intent);liWindow.closePopupWindow();}});}
到此为止,世界城市这个也买那就写完了,然后就写这个城市点击之后的天气查询了。在ui包下新建一个WorldCityWeatherActivity,作为点击跳转的Activity。
在修改布局之前先在mvplibrary下的values中的colors.xml中新增一个

"world_city_color">#243440
然后修改activity_world_city_weather.xml
这里面用到一个icon_hot_city_bg_2的图片


这里提供两个给你选择
"1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:background="@color/world_city_color"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".ui.WorldCityWeatherActivity">android:id="@+id/appbar"android:layout_width="match_parent"android:layout_height="wrap_content"android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">android:id="@+id/toolbar"android:background="@mipmap/icon_hot_city_bg_2"android:layout_width="match_parent"android:layout_height="wrap_content"app:contentInsetStart="0dp"android:fitsSystemWindows="true"app:layout_scrollFlags="scroll|enterAlways"app:popupTheme="@style/ThemeOverlay.AppCompat.Light">android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical">android:padding="@dimen/dp_12"android:id="@+id/tv_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="城市"android:textColor="@color/white"android:textSize="@dimen/sp_18" />android:padding="@dimen/dp_12"android:gravity="top"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="wrap_content">android:id="@+id/iv_weather_state"android:layout_width="@dimen/dp_150"android:layout_height="@dimen/dp_150" />android:layout_marginRight="@dimen/dp_20"android:layout_alignParentRight="true"android:orientation="vertical"android:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center_horizontal">android:layout_alignParentRight="true"android:id="@+id/tv_temperature"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="0°"android:textColor="@color/white"android:textSize="@dimen/sp_48" />android:id="@+id/tv_weather_state"android:layout_toRightOf="@+id/tv_temperature"android:text="天气状态"android:textColor="@color/white"android:layout_width="wrap_content"android:layout_height="wrap_content"/>android:layout_marginTop="@dimen/dp_8"android:orientation="horizontal"android:layout_width="wrap_content"android:layout_height="wrap_content">android:id="@+id/tv_tem_max"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="@dimen/dp_8"android:textColor="@color/white"android:textSize="@dimen/sp_14" />android:id="@+id/tv_tem_min"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="@dimen/dp_8"android:alpha="0.5"android:textColor="@color/white"android:textSize="@dimen/sp_14" /> android:layout_marginTop="@dimen/dp_8"android:textSize="@dimen/sp_14"android:id="@+id/tv_wind_state"android:textColor="@color/white"android:layout_width="wrap_content"android:layout_height="wrap_content"/> android:layout_width="match_parent"android:layout_height="match_parent"android:fillViewport="true"android:orientation="vertical"app:layout_behavior="@string/appbar_scrolling_view_behavior">android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical">android:id="@+id/rv_hourly"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/world_city_color" />
这里页面用了协调布局,形成折叠效果,具体的说明可以看这一篇文章Android 折叠式布局,这也是之前写的文章了,说明可能会详细一些,可以看看。
布局写好之后,在app中的contract下创建一个WorldCityWeatherContract订阅器,代码如下:
package com.llw.goodweather.contract;import com.llw.goodweather.api.ApiService;
import com.llw.goodweather.bean.DailyResponse;
import com.llw.goodweather.bean.HourlyResponse;
import com.llw.goodweather.bean.NowResponse;
import com.llw.mvplibrary.base.BasePresenter;
import com.llw.mvplibrary.base.BaseView;
import com.llw.mvplibrary.net.NetCallBack;
import com.llw.mvplibrary.net.ServiceGenerator;
import retrofit2.Call;
import retrofit2.Response;/*** 世界城市天气订阅器*/
public class WorldCityWeatherContract {public static class WorldCityWeatherPresenter extends BasePresenter<IWorldCityWeatherView> {/*** 实况天气 V7版本* @param location 城市名*/public void nowWeather(String location){//这个3 表示使用新的V7API访问地址ApiService service = ServiceGenerator.createService(ApiService.class,3);service.nowWeather(location).enqueue(new NetCallBack<NowResponse>() {@Overridepublic void onSuccess(Call<NowResponse> call, Response<NowResponse> response) {if(getView() != null){getView().getNowResult(response);}}@Overridepublic void onFailed() {if(getView() != null){getView().getDataFailed();}}});}/*** 天气预报 V7版本 7d 表示天气的数据 为了和之前看上去差别小一些,这里先用七天的* @param location 城市名*/public void dailyWeather(String location){//这个3 表示使用新的V7API访问地址ApiService service = ServiceGenerator.createService(ApiService.class,3);service.dailyWeather("7d",location).enqueue(new NetCallBack<DailyResponse>() {@Overridepublic void onSuccess(Call<DailyResponse> call, Response<DailyResponse> response) {if(getView() != null){getView().getDailyResult(response);}}@Overridepublic void onFailed() {if(getView() != null){getView().getDataFailed();}}});}/*** 逐小时预报(未来24小时)* @param location 城市名*/public void hourlyWeather(String location){ApiService service = ServiceGenerator.createService(ApiService.class,3);service.hourlyWeather(location).enqueue(new NetCallBack<HourlyResponse>() {@Overridepublic void onSuccess(Call<HourlyResponse> call, Response<HourlyResponse> response) {if(getView() != null){getView().getHourlyResult(response);}}@Overridepublic void onFailed() {if(getView() != null){getView().getDataFailed();}}});}}public interface IWorldCityWeatherView extends BaseView {/* 以下为V7版本新增 *///实况天气void getNowResult(Response<NowResponse> response);//天气预报 7天void getDailyResult(Response<DailyResponse> response);//逐小时天气预报void getHourlyResult(Response<HourlyResponse> response);//错误返回void getDataFailed();}
}
在layout下新建一个item_weather_hourly_world_list.xml布局文件,代码如下:
"1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_vertical"android:orientation="horizontal"android:paddingLeft="@dimen/dp_16"android:paddingRight="@dimen/dp_16">android:id="@+id/tv_time"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="上午10:00"android:textColor="#FFF"android:textSize="14sp" />android:layout_width="@dimen/dp_70"android:layout_height="@dimen/dp_70">android:layout_width="@dimen/dp_1"android:layout_height="match_parent"android:layout_centerHorizontal="true"android:background="#374552" />android:id="@+id/iv_weather_state"android:layout_width="50dp"android:layout_height="50dp"android:layout_centerInParent="true"android:background="@mipmap/icon_100" /> android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical">android:id="@+id/tv_weather_state"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="晴"android:textColor="#FFF"android:textSize="@dimen/sp_16" />android:id="@+id/tv_temperature"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="25℃"android:textColor="#FFF"android:textSize="@dimen/sp_16" /> android:gravity="center"android:id="@+id/tv_wind_info"android:layout_width="@dimen/dp_0"android:layout_weight="1"android:layout_height="wrap_content"android:layout_marginLeft="@dimen/dp_16"android:textColor="#FFF"android:textSize="@dimen/sp_14" />
然后写适配器,在adapter包下新建一个HourlyWorldCityAdapter,代码如下:
package com.llw.goodweather.adapter;import android.os.Build;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.llw.goodweather.R;
import com.llw.goodweather.bean.HourlyResponse;
import com.llw.goodweather.utils.DateUtils;
import com.llw.goodweather.utils.WeatherUtil;
import java.util.List;/*** V7 API 热门城市 逐小时预报数据列表适配器*/
public class HourlyWorldCityAdapter extends BaseQuickAdapter<HourlyResponse.HourlyBean, BaseViewHolder> {public HourlyWorldCityAdapter(int layoutResId, @Nullable List<HourlyResponse.HourlyBean> data) {super(layoutResId, data);}@RequiresApi(api = Build.VERSION_CODES.O)@Overrideprotected void convert(BaseViewHolder helper, HourlyResponse.HourlyBean item) {/*** V7 API 涉及到时间的,都会返回 2020-07-16T09:39+08:00 这种格式* 所以最好写一个通用的返回进行处理 方法已经写好了使用可以了*/String time = DateUtils.updateTime(item.getFxTime());helper.setText(R.id.tv_time, WeatherUtil.showTimeInfo(time) + time)//时间.setText(R.id.tv_temperature, item.getTemp() + "℃").setText(R.id.tv_weather_state, item.getText()).setText(R.id.tv_wind_info, item.getWindDir() + "," + item.getWindScale() + "级");//温度//天气状态图片ImageView weatherStateIcon = helper.getView(R.id.iv_weather_state);int code = Integer.parseInt(item.getIcon());//获取天气状态码,根据状态码来显示图标WeatherUtil.changeIcon(weatherStateIcon, code);}
}
然后回到WorldCityWeatherActivity中,

@BindView(R.id.tv_title)TextView tvTitle;//城市@BindView(R.id.toolbar)Toolbar toolbar;//标题bar@BindView(R.id.tv_temperature)TextView tvTemperature;//温度@BindView(R.id.iv_weather_state)ImageView ivWeatherState;//天气状况图片@BindView(R.id.tv_tem_max)TextView tvTemMax;//最高温@BindView(R.id.tv_tem_min)TextView tvTemMin;//最低温@BindView(R.id.rv_hourly)RecyclerView rvHourly;//逐小时列表@BindView(R.id.tv_weather_state)TextView tvWeatherState;//天气状态文字描述@BindView(R.id.tv_wind_state)TextView tvWindState;//风状态文字描述HourlyWorldCityAdapter mAdapter;//逐小时列表适配器List<HourlyResponse.HourlyBean> mList = new ArrayList<>();//列表数据
初始化 ,删除掉onCreate方法
@Overridepublic void initData(Bundle savedInstanceState) {initView();}
/*** 初始化页面*/private void initView() {StatusBarUtil.transparencyBar(context);//设置状态栏背景颜色Back(toolbar);showLoadingDialog();//加载弹窗mAdapter = new HourlyWorldCityAdapter(R.layout.item_weather_hourly_world_list, mList);rvHourly.setLayoutManager(new LinearLayoutManager(context));rvHourly.setAdapter(mAdapter);String locationId = getIntent().getStringExtra("locationId");//获取上一个页面传递过来的城市idtvTitle.setText(getIntent().getStringExtra("name"));//城市名称显示mPresent.nowWeather(locationId);//查询实况天气mPresent.dailyWeather(locationId);//查询天气预报mPresent.hourlyWeather(locationId);//查询逐小时天气预报}
@Overridepublic int getLayoutId() {return R.layout.activity_world_city_weather;}@Overrideprotected WorldCityWeatherContract.WorldCityWeatherPresenter createPresent() {return new WorldCityWeatherContract.WorldCityWeatherPresenter();}
接口返回处理和异常返回处理
/*** 实况天气返回 V7** @param response*/@Overridepublic void getNowResult(Response<NowResponse> response) {if (response.body().getCode().equals(Constant.SUCCESS_CODE)) {Typeface typeface = Typeface.createFromAsset(getAssets(), "fonts/GenJyuuGothic-ExtraLight.ttf");tvTemperature.setText(response.body().getNow().getTemp() + "°");tvTemperature.setTypeface(typeface);//使用字体int code = Integer.parseInt(response.body().getNow().getIcon());//获取天气状态码,根据状态码来显示图标WeatherUtil.changeIcon(ivWeatherState, code);//调用工具类中写好的方法tvWeatherState.setText("当前:" + response.body().getNow().getText());tvWindState.setText(response.body().getNow().getWindDir()+" "+response.body().getNow().getWindScale()+"级");} else {ToastUtils.showShortToast(context, CodeToStringUtils.WeatherCode(response.body().getCode()));}}/*** 天气预报 V7** @param response*/@Overridepublic void getDailyResult(Response<DailyResponse> response) {if (response.body().getCode().equals(Constant.SUCCESS_CODE)) {if (response.body().getDaily() != null && response.body().getDaily().size() > 0) {tvTemMax.setText(response.body().getDaily().get(0).getTempMax());tvTemMin.setText(" / " + response.body().getDaily().get(0).getTempMin());} else {ToastUtils.showShortToast(context, "暂无天气预报数据");}} else {ToastUtils.showShortToast(context, CodeToStringUtils.WeatherCode(response.body().getCode()));}}/*** 逐小时天气预报 V7** @param response*/@Overridepublic void getHourlyResult(Response<HourlyResponse> response) {if (response.body().getCode().equals(Constant.SUCCESS_CODE)) {List<HourlyResponse.HourlyBean> data = response.body().getHourly();if (data != null && data.size() > 0) {mList.clear();mList.addAll(data);mAdapter.notifyDataSetChanged();dismissLoadingDialog();} else {ToastUtils.showShortToast(context, "逐小时天气查询不到");}} else {ToastUtils.showShortToast(context, CodeToStringUtils.WeatherCode(response.body().getCode()));}}//异常返回@Overridepublic void getDataFailed() {dismissLoadingDialog();ToastUtils.showShortToast(context, "请求超时");}
还差最后一步,修改window_add.xml

回到MainActivity


修改热门城市为世界城市,id也改了。

源码地址:GoodWeather
欢迎 Star 和 Fork
下一篇:Android 天气APP(二十一)滑动改变UI、增加更多天气数据展示,最多未来15天天气预报
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
