**接着上一篇**
然后我们在util包内建立一个名为HttpUtil的类
功能:传入请求地址,并注册一个回调来处理服务器响应
public class HttpUtil {
public static void sendOkHttpRequest(String address, okhttp3.Callback callback)
{
//OkHttpClient client = new OkHttpClient();
//传入请求地址
Request request = new Request.Builder().url(address).build();
OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(60000, TimeUnit.MILLISECONDS)
.readTimeout(60000, TimeUnit.MILLISECONDS)
.build();
//注册一个回调来处理服务器响应
client.newCall(request).enqueue(callback);
}
}
然后在包内继续建立一个名为Utility的类
分别用于处理来自服务器的省市县三级的数据
public class Utility {
/**
* 解析和处理服务器返回的省级数据
*/
public static boolean handleProvinceResponse(String response)
{
if(!TextUtils.isEmpty(response))
{
try
{
JSONArray allProvinces = new JSONArray(response);
for (int i = 0; i < allProvinces.length(); i++)
{
JSONObject provinceObject = allProvinces.getJSONObject(i);
Province province = new Province();
province.setProvinceName(provinceObject.getString("name"));
province.setProvinceCode(provinceObject.getInt("id"));
//调用save()方法将数据存储到数据库中
province.save();
}
return true;
}catch (JSONException e)
{
e.printStackTrace();
}
}
return false;
}
/**
* 解析和处理服务器返回的市级数据
*/
public static boolean handleCityResponse(String response, int provinceId)
{
if(!TextUtils.isEmpty(response))
{
try {
JSONArray allCities = new JSONArray(response);
for (int i = 0; i < allCities.length(); i++)
{
JSONObject cityObject = allCities.getJSONObject(i);
City city = new City();
city.setCityName(cityObject.getString("name"));
city.setCityCode(cityObject.getInt("id"));
city.setProvinceId(provinceId);
//调用save()方法将数据存储到数据库中
city.save();
}
return true;
}catch (JSONException e)
{
e.printStackTrace();
}
}
return false;
}
/**
* 解析和处理服务器返回的县级数据
*/
public static boolean handleCountyResponse(String response, int cityId)
{
if(!TextUtils.isEmpty(response))
{
try {
JSONArray allCounties = new JSONArray(response);
for (int i = 0; i < allCounties.length(); i++)
{
JSONObject countyObject = allCounties.getJSONObject(i);
County county = new County();
county.setCountyName(countyObject.getString("name"));
county.setWeatherId(countyObject.getString("weather_id"));
county.setCityId(cityId);
//调用save()方法将数据存储到数据库中
county.save();
}
return true;
}catch (JSONException e)
{
e.printStackTrace();
}
}
return false;
}
/**
* 将返回的JSON数据解析成Weather实体类
*/
public static Weather handleWeatherResponse(String response)
{
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("HeWeather");
String weatherContent = jsonArray.getJSONObject(0).toString();
return new Gson().fromJson(weatherContent,Weather.class);
}catch (Exception e)
{
e.printStackTrace();
}
return null;
}
}
接下来我们建立一个名为choose_area的布局文件,用于存放标题,返回键,还有省市县列表
back图片是我们事先准备好的
代码如下:
效果如下:
然后写一个遍历省市县三级的碎片类
名为:ChooseAreaFragment继承于Fragment
代码如下:
public class ChooseAreaFragment extends Fragment {
public static final int LEVEL_PROVINCE = 0;
public static final int LEVEL_CITY = 1;
public static final int LEVEL_COUNTY = 2;
private ProgressDialog progressDialog;
private TextView titleText;
private Button backButton;
private ListView listView;
private ArrayAdapter adapter;
private List dataList = new ArrayList<>();
/**
* 省列表
*/
private List provinceList;
/**
* 市列表
*/
private List cityList;
/**
* 县列表
*/
private List countyList;
/**
* 选中的省份
*/
private Province selectedProvince;
/**
* 选中的城市
*/
private City selectedCity;
/**
* 当前选中的级别
*/
private int currentLevel;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.choose_area, container, false);
titleText = (TextView) view.findViewById(R.id.title_text);
backButton = (Button)view.findViewById(R.id.back_button);
listView = (ListView) view.findViewById(R.id.list_view);
adapter = new ArrayAdapter<>(getContext(),android.R.layout.simple_list_item_1, dataList);
listView.setAdapter(adapter);
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
if(currentLevel == LEVEL_PROVINCE)
{
selectedProvince = provinceList.get(position);
queryCities();
}
else if (currentLevel == LEVEL_CITY)
{
selectedCity = cityList.get(position);
queryCounties();
}
else if(currentLevel == LEVEL_COUNTY)
{
String weatherId = countyList.get(position).getWeatherId();
if(getActivity() instanceof MainActivity)
{
Intent intent = new Intent(getActivity(), WeatherActivty.class);
intent.putExtra("weather_id",weatherId);
startActivity(intent);
getActivity().finish();
}
else if(getActivity() instanceof WeatherActivty)
{
WeatherActivty activity = (WeatherActivty)getActivity();
activity.drawerLayout.closeDrawers();
activity.swipeRefresh.setRefreshing(true);
activity.requestWeather(weatherId);
}
}
}
});
backButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(currentLevel == LEVEL_COUNTY)
{
queryCities();
}
else if (currentLevel == LEVEL_CITY)
{
queryProvinces();
}
}
});
queryProvinces();
}
private void queryProvinces()
{
titleText.setText("中国");
backButton.setVisibility(View.GONE);
provinceList = LitePal.findAll(Province.class);
if(provinceList.size() > 0)
{
dataList.clear();
for (Province province:provinceList)
{
dataList.add(province.getProvinceName());
}
adapter.notifyDataSetChanged();
listView.setSelection(0);
currentLevel = LEVEL_PROVINCE;
}
else
{
String address = "http://guolin.tech/api/china";
queryFromServer(address,"province");
}
}
/**
* 查询选中省内所有的市,优先从数据库查询,如果没有查询到再去服务器上查询
*/
private void queryCities()
{
titleText.setText(selectedProvince.getProvinceName());
backButton.setVisibility(View.VISIBLE);
cityList = LitePal.where("provinceid = ?", String.valueOf(selectedProvince.getId())).find(City.class);
if(cityList.size() > 0)
{
dataList.clear();
for (City city: cityList)
{
dataList.add(city.getCityName());
}
adapter.notifyDataSetChanged();
listView.setSelection(0);
currentLevel = LEVEL_CITY;
}
else
{
int provinceCode = selectedProvince.getProvinceCode();
String address = "http://guolin.tech/api/china/" + provinceCode;
queryFromServer(address,"city");
}
}
/**
* 查询选中市内所有的县,优先从数据库查询,如果没有查询到再去服务器上查询
*/
private void queryCounties()
{
titleText.setText(selectedCity.getCityName());
backButton.setVisibility(View.VISIBLE);
countyList = LitePal.where("cityid = ?", String.valueOf(selectedCity.getId())).find(County.class); if(countyList.size() > 0)
{
dataList.clear();
for (County county: countyList)
{
dataList.add(county.getCountyName());
}
adapter.notifyDataSetChanged();
listView.setSelection(0);
currentLevel = LEVEL_COUNTY;
}
else
{
int provinceCode = selectedProvince.getProvinceCode();
int cityCode = selectedCity.getCityCode();
String address = "http://guolin.tech/api/china/" + provinceCode + "/" + cityCode;
queryFromServer(address,"county");
}
}
/**
* 根据传入的地址和类型从服务器上查询省市县数据
*/
private void queryFromServer(String address, final String type)
{
showProgressDialog();
HttpUtil.sendOkHttpRequest(address, new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
//通过runOnUiThread()方法回到主线程逻辑
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
closeProgressDialog();
Toast.makeText(getContext(),"加载失败",Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String responseText = response.body().string();
boolean result = false;
if("province".equals(type))
{
result = Utility.handleProvinceResponse(responseText);
}
else if("city".equals(type))
{
result = Utility.handleCityResponse(responseText,selectedProvince.getId());
}
else if("county".equals(type))
{
result = Utility.handleCountyResponse(responseText,selectedCity.getId());
}
if (result)
{
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
closeProgressDialog();
if("province".equals(type))
{
queryProvinces();
}
else if ("city".equals(type))
{
queryCities();
}
else if ("county".equals(type))
{
queryCounties();
}
}
});
}
}
});
}
/**
* 显示进度对话框
*/
private void showProgressDialog()
{
if(progressDialog == null)
{
progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("正在加载···");
progressDialog.setCanceledOnTouchOutside(false);
}
progressDialog.show();
}
/**
* 关闭进度对话框
*/
private void closeProgressDialog()
{
if(progressDialog != null)
{
progressDialog.dismiss();
}
}
}
然后我们在activity_main.xml显示碎片
代码如下:
最后我们在清单文件中声明网罗权限
到这里第二篇结束了,我们已经可以查看所有的省市县三级列表了
效果图如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210209201858563.png