本篇文章主要内容为:运用Volley框架进行网络请求,调用百度天气API并对得到的json数据解析。
天气接口为百度API的,地址:http://apistore.baidu.com/apiworks/servicedetail/478.html。

首先选择要查询天气的城市,然后根据城市名,得到该城市七日天气数据。其中用的城市列表是参考网上的,
原地址:http://www.okbase.net/file/item/33385

1.程序主页面:main.xml

主页面上有一个按钮,点击后进入城市列表选择城市,一个TextView显示标题,一个ListView显示城市七日天气数据。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#F0F0F0"
android:orientation="vertical" >


<Button
android:id="@+id/selectBtn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="选择城市" />


<TextView
android:id="@+id/tv_city"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="48dp"
android:textSize="18sp"
android:textColor="#000"
/>


<ListView
android:id="@+id/list_weather"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:dividerHeight="1dp"
android:divider="#E0E0E0"
/>


</LinearLayout>

2.ListView 每一项布局文件weather_item.xml

将解析到的数据格式化显示。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp"
android:padding="10dp">


<TextView
style="@style/txtStyle"
android:id="@+id/tv_date"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="2016-3-16"
/>


<TextView
style="@style/txtStyle"
android:id="@+id/tv_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/tv_date"
android:layout_marginLeft="100dp"
android:gravity="center_horizontal"
android:text="多云"
/>


<TextView
style="@style/txtStyle"
android:id="@+id/tv_max"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_toRightOf="@id/tv_date"
android:layout_below="@id/tv_status"
android:layout_marginLeft="20dp"
android:gravity="center_vertical"
android:text="15"
/>


<TextView
style="@style/txtStyle"
android:id="@+id/tv_min"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_toRightOf="@id/tv_max"
android:layout_below="@id/tv_status"
android:layout_marginLeft="60dp"
android:gravity="center_vertical"
android:text="6"
/>


</RelativeLayout>

3.MainActivity.java文件

主要业务是选择城市,通过Volley向天气接口发出请求,解析返回的json数据。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import com.android.volley.AuthFailureError;
import com.android.volley.Request.Method;
import com.android.volley.RequestQueue;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.dialog.CustomProgressDialog;

public class MainActivity extends Activity {

private Button btn;
private TextView tv_city;
private ListView list_weather;
private WeatherAdapter mAdapter;
private static final int REQUEST_CITY = 0;
private RequestQueue mQueue; // volley的请求队列
private static final String apikey = "1a03add595481b304fdef3660c02d97d"; //此处为你申请的apikey
private List<Map<String, String>>weatherDatas = new ArrayList<Map<String,String>>();
private String date,max,min,tv_status;
private CustomProgressDialog processDialog;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

mQueue = Volley.newRequestQueue(getApplicationContext()); //新建请求队列

tv_city = (TextView) findViewById(R.id.tv_city);
list_weather = (ListView) findViewById(R.id.list_weather);

btn = (Button) findViewById(R.id.selectBtn);
btn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, CityList.class);

//因为要接收城市列表中选择的城市,所以此处用startActivityForResult
startActivityForResult(intent, REQUEST_CITY);
}
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

switch (requestCode) {
case REQUEST_CITY:
if (resultCode == RESULT_OK) {
showProcessDialog();
String cityName = data.getStringExtra("cityName");

//去掉最后一个字"市",因为请求参数中不包含"市"字,(例如:参数是北京,而不是北京市) 所以数据库中的有些城市查询不到
String city = cityName.substring(0, cityName.length() - 1);
weatherDatas.clear(); //这句话要加上,否则新的数据会加在原来数据的后面
getWeather(city);
}
break;

default:
break;
}
}

private void getWeather(final String city) {
String url = "http://apis.baidu.com/heweather/weather/free?city="+city;

//请求成功
Listener<String>listener = new Listener<String>() {
@Override
public void onResponse(String arg0) {
dismissProcessDialog();
Log.d("onResponse", arg0);
tv_city.setText(city + "市七日天气");
parseData(arg0);
mAdapter = new WeatherAdapter(MainActivity.this, weatherDatas);
list_weather.setAdapter(mAdapter);
}

};

//请求失败
ErrorListener errorListener = new ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
Log.d("onErrorResponse", arg0.toString());
tv_city.setText("暂不支持该城市!");
}
};

StringRequest request = new StringRequest(Method.GET, url,
listener, errorListener){

@Override
public Map<String, String> getHeaders()
throws AuthFailureError {
Map<String, String>mHeaders = new HashMap<String, String>();
mHeaders.put("apikey", apikey);
return mHeaders;
}

};
mQueue.add(request); //加入请求队列
}


//对返回的json数据进行解析
private void parseData(String arg0) {
try {
JSONArray results = new JSONObject(arg0).optJSONArray("HeWeather data service 3.0");
JSONArray daily_forecast = results.optJSONObject(0).optJSONArray("daily_forecast");
for(int i = 0; i < daily_forecast.length(); i++){
HashMap<String, String>map = new HashMap<String, String>();

date = daily_forecast.optJSONObject(i).optString("date");
tv_status = daily_forecast.optJSONObject(i).optJSONObject("cond").optString("txt_d");
max = daily_forecast.optJSONObject(i).optJSONObject("tmp").optString("max");
min = daily_forecast.optJSONObject(i).optJSONObject("tmp").optString("min");

map.put("tv_date", date);
map.put("tv_status", tv_status);
map.put("tv_max", max);
map.put("tv_min", min);

weatherDatas.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
}

public void showProcessDialog() {

if (processDialog == null){
processDialog = new CustomProgressDialog(this,"loading...");
processDialog.show();
processDialog.setCanceledOnTouchOutside(true);
}
if (processDialog.isShowing() == false)
processDialog.show();
}

public void dismissProcessDialog() {

if (processDialog != null)
processDialog.dismiss();
}

}

4.天气数据适配器WeatherAdapter.java

public class WeatherAdapter extends BaseAdapter {

private Context mContext;
private List<Map<String, String>>datas;
private LayoutInflater inflater;

public WeatherAdapter(Context mContext, List<Map<String, String>> datas) {
this.mContext = mContext;
this.datas = datas;
inflater = LayoutInflater.from(mContext);
}

@Override
public int getCount() {
return datas.size();
}

@Override
public Object getItem(int arg0) {
return datas.get(arg0);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;

if(convertView == null){
convertView = inflater.inflate(R.layout.weather_item, null);
holder = new ViewHolder();
holder.tv_date = (TextView) convertView.findViewById(R.id.tv_date);
holder.tv_status = (TextView) convertView.findViewById(R.id.tv_status);
holder.tv_max = (TextView) convertView.findViewById(R.id.tv_max);
holder.tv_min = (TextView) convertView.findViewById(R.id.tv_min);

convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}

holder.tv_date.setText(datas.get(position).get("tv_date"));
holder.tv_status.setText(datas.get(position).get("tv_status"));
holder.tv_max.setText("最高温:" + datas.get(position).get("tv_max"));
holder.tv_min.setText("最低温:" + datas.get(position).get("tv_min"));

return convertView;
}

static class ViewHolder{
private TextView tv_date;
private TextView tv_status;
private TextView tv_max;
private TextView tv_min;
}
}

城市列表部分的代码请见源码

5.运行截图


6.源码下载

更多相关文章

  1. Android本地数据存储之Sharedpreference
  2. [置顶] Android数据库框架GreenDao封装使用,易理解、易扩
  3. AIDL详解2——复杂数据通信
  4. Android数据的四种存储方式
  5. Android原生Contacts——界面和数据库
  6. [Android]如何导入已有的外部数据库
  7. Android ListView获取当前可视区域条目数据
  8. Java操作数据库之jdbc【原生方式】
  9. java数据结构--链表

随机推荐

  1. Android 视频列表(RecyclerView)实现自动
  2. android market过滤规则研究 - 第二届 Go
  3. Android创建和使用数据库详细指南(7)
  4. 【Android 设计】:启航_ 创作意图 | 设计
  5. Android实现网络视频播放
  6. android程序实现简单拨号器功能
  7. Android简单音乐播放器
  8. 按powerkey唤醒启动上层Andord
  9. android:layout_gravity 和 android:grav
  10. android studio创建新项目color.xml文件