Android天气预报程序(四)
2016-04-16 10:24
489 查看
现在我们可以开始写界面了
在res/layout目录中新建choose_area.xml布局,代码如下所示:
我们先是定义了一个50dp高的头布局,在里面放置了一个TextView用于显示标题内容
然后在头布局下面定义了一个ListView,省市县的数据就将显示在这里
接下来就要编写用于遍历省市县数据的活动了
在activity包下新建ChooseAreaActivity继承自Activity,代码如下所示:
queryProvince()方法的内部会首先调用CoolWeatherDB的loadProvince()方法来从数据库中读取省级数据,如果读取到了就直接将数据显示到界面上,如果没有就调用queryFromServer()方法来从服务器上查询数据。
queryFromServer()方法会先根据传入的参数来拼装查询地址,具体可见Android天气预报程序(一)
确定了查询地址之后,接下来就调用HttpUtil的sendHttpRequest()方法来向服务器发送请求,响应的数据会回调到onFinish()方法中,然后我们在这里去调用handleProvinceResponse()方法来解析和处理服务器返回的数据,并存储到数据库中。
接下来这一步很关键,在解析和处理完数据之后,我们再次调用了queryProvince()方法来重新加载省级数据,由于queryProvince()方法牵扯到了UI操作,因此必须要在主线程中调用,这里借助了runOnUiThread()方法来实现从子线程切换到主线程,它的实现原理其实也是基于异步消息处理机制的。
现在数据库中已经存在了数据,因此调用queryProvince()就会直接将数据显示到界面了。
当你点击了某个省的时候会进入到ListView的onItemClick()方法中,这个时候会根据当前的级别来判断是去调用queryCities()方法还是queryCounties()方法。
我们重写了onBackPressed()方法来覆盖默认Back键的行为,这里会根据当前的级别来判断是返回市级列表、省级列表、还是直接退出。
接下来就是配置AndroidManifest.xml文件了
主要就修改了两点,第一是添加了访问网络的权限,第二是将ChooseAreaActivity配置成主活动,这样一旦打开程序就会直接进入ChooseAreaActivity了。
现在可以运行一下程序了
可以看到,全国所有省级单位都显示出来了
我们还可以继续查看市级单位,比如点击广东省
然后再点击广州市
在res/layout目录中新建choose_area.xml布局,代码如下所示:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="match_content" android:layout_height="50dp" android:background="#484E61" > <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="24sp" /> </RelativeLayout> <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="match_parent" > </ListView> </LinearLayout>
我们先是定义了一个50dp高的头布局,在里面放置了一个TextView用于显示标题内容
然后在头布局下面定义了一个ListView,省市县的数据就将显示在这里
接下来就要编写用于遍历省市县数据的活动了
在activity包下新建ChooseAreaActivity继承自Activity,代码如下所示:
public class ChooseAreaActivity extends Activity { 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 ListView listView; private ArrayAdapter<String> adapter; private CoolWeatherDB coolWeatherDB; private List<String> dataList = new ArrayList<String>(); /** * 省列表 */ private List<Province> provinceList; /** * 市列表 */ private List<City> cityList; /** * 县列表 */ private List<County> countyList; /** * 选中的省份 */ private Province selectedProvince; /** * 选中的城市 */ private City selectedCity; /** * 当前选中的级别 */ private int currentLevel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.choose_area); listView = (ListView) findViewById(R.id.list_view); titleText = (TextView) findViewById(R.id.title_text); adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, dataList); listView.setAdapter(adapter); coolWeatherDB = CoolWeatherDB.getInstance(this); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View view, int index, long arg3) { if (currentLevel == LEVEL_PROVINCE) { selectedProvince = provinceList.get(index); queryCities(); } else if (currentLevel == LEVEL_CITY) { selectedCity = cityList.get(index); queryCounties(); } } }); queryProvinces(); // 加载省级数据 } /** * 查询全国所有的省,优先从数据库查询,如果没有查询到再去服务器上查询 */ private void queryProvinces() { provinceList = coolWeatherDB.loadProvinces(); if (provinceList.size() > 0) { dataList.clear(); for (Province province : provinceList) { dataList.add(province.getProvinceName()); } adapter.notifyDataSetChanged(); listView.setSelection(0); titleText.setText("中国"); currentLevel = LEVEL_PROVINCE; } else { queryFromServer(null, "province"); } } /** * 查询选中省内所有的市,优先从数据库查询,如果没有查询到再去服务器上查询 */ private void queryCities() { cityList = coolWeatherDB.loadCities(selectedProvince.getId()); if (cityList.size() > 0) { dataList.clear(); for (City city : cityList) { dataList.add(city.getCityName()); } adapter.notifyDataSetChanged(); listView.setSelection(0); titleText.setText(selectedProvince.getProvinceName()); currentLevel = LEVEL_CITY; } else { queryFromServer(selectedProvince.getProvinceCode(), "city"); } } /** * 查询选中市内所有的县,优先从数据库查询,如果没有查询到再去服务器上查询 */ private void queryCounties() { countyList = coolWeatherDB.loadCounties(selectedCity.getId()); if (countyList.size() > 0) { dataList.clear(); for (County county : countyList) { dataList.add(county.getCountyName()); } adapter.notifyDataSetChanged(); listView.setSelection(0); titleText.setText(selectedCity.getCityName()); currentLevel = LEVEL_COUNTY; } else { queryFromServer(selectedCity.getCityCode(), "county"); } } /** * 根据传入的代号和类型从服务器上查询省市县数据 */ private void queryFromServer(final String code, final String type) { String address; if (!TextUtils.isEmpty(code)) { address = "http://www.weather.com.cn/data/list3/city" + code + ".xml"; } else { address = "http://www.weather.com.cn/data/list3/city.xml"; } showProgressDialog(); HttpUtil.sendHttpRequest(address, new HttpCallbackListener() { @Override public void onFinish(String response) { boolean result = false; if ("province".equals(type)) { result = Utility.handleProvincesResponse(coolWeatherDB, response); } else if ("city".equals(type)) { result = Utility.handleCitiesResponse(coolWeatherDB, response, selectedProvince.getId()); } else if ("county".equals(type)) { result = Utility.handleCountiesResponse(coolWeatherDB, response, selectedCity.getId()); } if (result) { // 通过runOnUiThread()方法回到主线程处理逻辑 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(); } } }); } } @Override public void onError(Exception e) { // 通过runOnUiThread()方法回到主线程处理逻辑 runOnUiThread(new Runnable() { @Override public void run() { closeProgressDialog(); Toast.makeText(ChooseAreaActivity.this, "加载失败", Toast.LENGTH_SHORT).show(); } }); } }); } /** * 显示进度对话框 */ private void showProgressDialog() { if (progressDialog == null) { progressDialog = new ProgressDialog(this); progressDialog.setMessage("正在加载..."); progressDialog.setCanceledOnTouchOutside(false); } progressDialog.show(); } /** * 关闭进度对话框 */ private void closeProgressDialog() { if (progressDialog != null) { progressDialog.dismiss(); } } /** * 捕获Back按键,根据当前的级别来判断,此时应该返回市列表、省列表、还是直接退出 */ @Override public void onBackPressed() { if (currentLevel == LEVEL_COUNTY) { queryCities(); } else if ( currentLevel == LEVEL_CITY) { queryProvinces(); } else { finish(); } } }
queryProvince()方法的内部会首先调用CoolWeatherDB的loadProvince()方法来从数据库中读取省级数据,如果读取到了就直接将数据显示到界面上,如果没有就调用queryFromServer()方法来从服务器上查询数据。
queryFromServer()方法会先根据传入的参数来拼装查询地址,具体可见Android天气预报程序(一)
确定了查询地址之后,接下来就调用HttpUtil的sendHttpRequest()方法来向服务器发送请求,响应的数据会回调到onFinish()方法中,然后我们在这里去调用handleProvinceResponse()方法来解析和处理服务器返回的数据,并存储到数据库中。
接下来这一步很关键,在解析和处理完数据之后,我们再次调用了queryProvince()方法来重新加载省级数据,由于queryProvince()方法牵扯到了UI操作,因此必须要在主线程中调用,这里借助了runOnUiThread()方法来实现从子线程切换到主线程,它的实现原理其实也是基于异步消息处理机制的。
现在数据库中已经存在了数据,因此调用queryProvince()就会直接将数据显示到界面了。
当你点击了某个省的时候会进入到ListView的onItemClick()方法中,这个时候会根据当前的级别来判断是去调用queryCities()方法还是queryCounties()方法。
我们重写了onBackPressed()方法来覆盖默认Back键的行为,这里会根据当前的级别来判断是返回市级列表、省级列表、还是直接退出。
接下来就是配置AndroidManifest.xml文件了
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.coolweather.app" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.coolweather.app.activity.ChooseAreaActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
主要就修改了两点,第一是添加了访问网络的权限,第二是将ChooseAreaActivity配置成主活动,这样一旦打开程序就会直接进入ChooseAreaActivity了。
现在可以运行一下程序了
可以看到,全国所有省级单位都显示出来了
我们还可以继续查看市级单位,比如点击广东省
然后再点击广州市
相关文章推荐
- android如何让listView加入的HeaderView或FooterView不可点击
- Android学习(声明)
- 判断一个service是否启动
- Ant自动编译打包&发布 android项目
- 关于Android studio 的优化
- android permission权限与安全机制解析(上)
- Android ViewSwitcher、TextSwitcher、ImageSwitcher
- 提高android gradle构建速度的努力
- android studio笔记-2
- android studio笔记-1
- Android总结 - 保存数据
- Android真机adb被酷狗等流氓软件抢占进程最好的解决办法
- EasyPusher安卓Android手机直播推送之RTSP流媒体协议流程
- EasyPusher安卓Android手机直播推送之RTSP流媒体协议流程
- Android获取屏幕高度、状态栏高度、标题栏高度
- Android与H5交互(java与js的交互)
- Android的资源功能篇
- Android Studio 小技巧
- 具有弹性的ListView
- Android 自定义View之随手指滑动的ToggleButton