Android——天氣預報(酷歐天氣)(第二篇)
阿新 • • 發佈:2021-02-10
技術標籤:Android Studioandroidjavaandroid studio
**接著上一篇**
然後我們在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圖片是我們事先準備好的
程式碼如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#fff"> <RelativeLayout android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary"> <TextView android:id="@+id/title_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:textColor="#fff" android:textSize="20sp"/> <Button android:id="@+id/back_button" android:layout_width="25dp" android:layout_height="25dp" android:layout_marginLeft="10dp" android:layout_marginStart="10dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_alignParentStart="true" android:background="@drawable/back"/> </RelativeLayout> <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
效果如下:
然後寫一個遍歷省市縣三級的碎片類
名為: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<String> adapter;
private List<String> dataList = new ArrayList<>();
/**
* 省列表
*/
private List<Province> provinceList;
/**
* 市列表
*/
private List<City> cityList;
/**
* 縣列表
*/
private List<County> 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顯示碎片
程式碼如下:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/choose_area_fragment"
android:name="com.example.weather2.ChooseAreaFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
最後我們在清單檔案中宣告網羅許可權
<uses-permission android:name="android.permission.INTERNET" />
到這裡第二篇結束了,我們已經可以檢視所有的省市縣三級列表了
效果圖如下:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20210209201858563.png