实战 Walker 之天气预报的实现分析

来源:互联网 发布:gta5开车掉帧如何优化 编辑:程序博客网 时间:2024/05/16 19:55

一、获取天气预报数据 

1、首先搞定天气预报数据来源的问题,提高天气预报服务的有很多网站,这些网站一般都会提供比较详细的 API 接口供应用程序调用,完成调用后再把准备好图片资源和所需要的文字资源导入进去。

二、编写网络数据访问工具类

1、首先需要在 uiti 包下定义一个接口,比如将它命名成 HttpCallbackListener,代码如下: 

public interface HttpCallbackListener {  void onFinish(String response);  void onError(Exception e);  } 
2、然后定义 HttpUtil 类,代码如下:
public class HttpUtil {  public static void sendHttpRequest(final String address, final HttpCallbackListener listener) {  new Thread(new Runnable() {  @Override  public void run() {  HttpURLConnection connection = null;  try {  URL url = new URL(address);  connection = (HttpURLConnection) url.openConnection();  connection.setRequestMethod("GET");  connection.setConnectTimeout(8000);  connection.setReadTimeout(8000);  connection.setDoInput(true);  connection.setDoOutput(true);  InputStream in = connection.getInputStream();  BufferedReader reader =  new BufferedReader(new InputStreamReader(in));  StringBuilder response = new StringBuilder();  String line;  while ((line = reader.readLine()) != null) {  response.append(line);  }  if (listener != null) {  // 回调 onFinish()方法  listener.onFinish(response.toString());  }  } catch (Exception e) {  if (listener != null) {  // 回调 onError()方法  listener.onError(e);  }  } finally {  if (connection != null) {  connection.disconnect();  }  }  }  }).start();  } 
3、测试一下能否正常访问天气预报接口得到返回的数据。 

<pre name="code" class="java">public class WeatherGetTest extends AndroidTestCase{  public void testGetData(){  String weatherUrl="http://v.juhe.cn/weather/index?format=2&cityname= 滨 州&key=ab9d7e2007472d723baf71fcdc4ba094";  HttpUtil.sendHttpRequest(weatherUrl, new HttpCallbackListener() {  @Override  public void onFinish(String response) {  System.out.println(response);  }  @Override  public void onError(Exception e) {   }  });  }  } 

(由于涉及到访问网络,需要在 AndroidManifest.xml 文件中加入访问网络的权限。 
<uses-permission android:name="android.permisson.Internet"/> )

三、UI 设计
1、新建 WeatherActivity 
2、修改自动生成的 activity_weather.xml 文件,整体布局代码如下: 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:background="@drawable/activity_weather_bg"  tools:context=".WeatherActivity" >  <LinearLayout  android:id="@+id/linearLayout1"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:orientation="horizontal" >  <EditText  android:id="@+id/etCity"  android:layout_width="0dp"  android:layout_height="wrap_content"  android:layout_marginLeft="10dp"  android:layout_marginTop="20dp"  android:layout_weight="1"  android:background="@android:drawable/edit_text"  android:drawableLeft="@drawable/icons_weather_city"  android:drawablePadding="5dp"  android:ems="10"  android:hint="@string/etCity" >  <requestFocus />  </EditText>  <ImageButton  android:id="@+id/btnQuery"  android:layout_width="50dp"  android:layout_height="50dp"  android:layout_marginTop="20dp"  android:background="@null"  android:src="@drawable/icons_weather_query" />  </LinearLayout>  <ListView  android:id="@+id/lvFutureWeather"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:layout_below="@+id/linearLayout1"  android:layout_centerHorizontal="true"  android:layout_marginLeft="10dp"  android:layout_marginRight="10dp"  android:dividerHeight="10dp"  android:layoutAnimation="@anim/weather_list_layout_animation" >  </ListView>  </RelativeLayout>
其中 weather_list_layout_animation.xml 文件是一个设置布局动画的,实现过程如下:  在 res 目录下新建 anim 文件夹,在其下新建 weather_list_layout_animation.xml 文件,如下:
<?xml version="1.0" encoding="utf-8"?> <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"  android:animation="@anim/weather_list_animation"  android:animationOrder="normal" android:delay="2" />
其中 weather_list_animation.xml 文件也是一动画文件,如下: 
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android">  <scale  android:interpolator="@android:anim/accelerate_decelerate_interpolator"  android:fromXScale="0.0"  android:toXScale="1.0"  android:fromYScale="0.0"  android:toYScale="1.0"  android:duration="1000"  /> </set>
3、定义整体布局中 ListView 控件所对应的子布局 activity_weather_listitem.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="wrap_content"  android:padding="10dp"  android:layout_margin="10dp"  android:background="@drawable/list_item_shape" >  <TextView  android:id="@+id/tvDayofWeek"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignParentLeft="true"  android:layout_alignParentTop="true"  android:layout_marginLeft="15dp"  android:text="星期日" />  <TextView  android:id="@+id/tvDate"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignBaseline="@+id/tvDayofWeek"  android:layout_alignBottom="@+id/tvDayofWeek"  android:layout_alignParentRight="true"  android:text="20160207" />  <TextView  android:id="@+id/tvTemperature"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignLeft="@+id/tvDayofWeek"  android:layout_below="@+id/tvDayofWeek"  android:layout_marginTop="15dp"  android:text="temperature" />  <TextView  android:id="@+id/tvWeather"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignLeft="@+id/tvTemperature"  android:layout_below="@+id/tvTemperature"  android:layout_marginTop="15dp"  android:text="weather" /> </RelativeLayout> 
其中 list_item_shape.xml 文件定义如下:

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" >  <corners  android:radius="5dp"/>  <solid  android:color="@color/azure"/> </shape> 
布局后的效果图如下所示: 


4、在 model 包下定义 Weather 实体类封装所关心的信息,如下:

/**  * 天气实体类  * @author cabbage  */ public class Weather {  private String dayOfWeek;//星期几  private String date;//日期  private String temperature;//温度  private String weather;//天气  public Weather(){   }  public Weather(String dayOfWeek, String date, String temperature,  String weather) {  super();  this.dayOfWeek = dayOfWeek;  this.date = date;  this.temperature = temperature;  this.weather = weather;  }  public String getDayOfWeek() {  return dayOfWeek;  }  public void setDayOfWeek(String dayOfWeek) {  this.dayOfWeek = dayOfWeek;  }  public String getDate() {  return date;  }  public void setDate(String date) {  this.date = date;  }  public String getTemperature() {  return temperature;  }  public void setTemperature(String temperature) {  this.temperature = temperature;  }  public String getWeather() {  return weather;  }  public void setWeather(String weather) {  this.weather = weather;  }  @Override  public String toString() {  return "Weather [dayOfWeek=" + dayOfWeek + ", date=" + date  + ", temperature=" + temperature + ", weather=" + weather + "]";  }  }
 5、在 adapter 包下定义适配器 WeatherAdapter,代码如下: 
/**  * 天气适配器  * @author cabbage  */ public class WeatherAdapter extends ArrayAdapter<Weather> {  private int resourceId;  public WeatherAdapter(Context context, int textViewResourceId,  List<Weather> objects) {  super(context, textViewResourceId, objects);  resourceId = textViewResourceId;  }  @Override  public View getView(int position, View convertView, ViewGroup viewgroup) {  Weather weather=getItem(position);  ViewHolder viewHolder=null;  if(convertView==null){  viewHolder=new ViewHolder();  convertView=LayoutInflater.from(getContext()).inflate(resourceId, null);  viewHolder.tvDayOfWeek=(TextView) convertView.findViewById(R.id.tvDayofWeek);  viewHolder.tvDate=(TextView) convertView.findViewById(R.id.tvDate);  viewHolder.tvTemperature=(TextView) convertView.findViewById(R.id.tvTemperature);  viewHolder.tvWeather=(TextView) convertView.findViewById(R.id.tvWeather);  convertView.setTag(viewHolder);  }else{  viewHolder=(ViewHolder) convertView.getTag();  }  viewHolder.tvDayOfWeek.setText(weather.getDayOfWeek());  viewHolder.tvDate.setText(weather.getDate());  viewHolder.tvTemperature.setText(weather.getTemperature());  viewHolder.tvWeather.setText(weather.getWeather());  return convertView;  }   private class ViewHolder{  TextView tvDayOfWeek;  TextView tvDate;  TextView tvTemperature;  TextView tvWeather;  } }
6、编写 WeatherActivity 类 

package cn.edu.bztc.walkersimulate; import java.util.ArrayList; import java.util.List;import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.view.animation.LayoutAnimationController; import android.view.animation.ScaleAnimation; import android.widget.EditText; import android.widget.ImageButton; import android.widget.ListView; import android.widget.Toast; import cn.edu.bztc.walkersimulate.adapter.WeatherAdapter; import cn.edu.bztc.walkersimulate.model.Weather; import cn.edu.bztc.walkersimulate.util.HttpCallbackListener; import cn.edu.bztc.walkersimulate.util.HttpUtil; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParser;  public class WeahterActivity extends Activity {  private EditText etCity;  private ImageButton btnQuery;  private ListView lvFutureWeather;  public static final int SHOW_RESPONSE = 1;  private List<Weather> data;  private Handler handler = new Handler() {  public void handleMessage(android.os.Message msg) {  switch (msg.what) {  case SHOW_RESPONSE:  String response = (String) msg.obj;  if (response != null) {  parseWithJSON(response);  WeatherAdapter weatherAdapter = new WeatherAdapter(  WeahterActivity.this,  R.layout.activity_weather_listitem, data);  lvFutureWeather.setAdapter(weatherAdapter);  ScaleAnimation scaleAnimation = new ScaleAnimation(0, 1, 0,  1);  scaleAnimation.setDuration(1000);  LayoutAnimationController animationController = new LayoutAnimationController(  scaleAnimation, 0.6f);  lvFutureWeather.setLayoutAnimation(animationController);  }  default:  break;  }  }   private void parseWithJSON(String response) {  data = new ArrayList<Weather>();  JsonParser parser = new JsonParser();// json 解析器  JsonObject obj = (JsonObject) parser.parse(response);  /* 获取返回状态码 */  String resultcode = obj.get("resultcode").getAsString();  /* 如果状态码是 200 说明返回数据成功 */  if (resultcode != null && resultcode.equals("200")) {  JsonObject resultObj = obj.get("result").getAsJsonObject();  JsonArray futureWeatherArray = resultObj.get("future")  .getAsJsonArray();  for (int i = 0; i < futureWeatherArray.size(); i++) {  Weather weather = new Weather();  JsonObject weatherObject = futureWeatherArray.get(i)  .getAsJsonObject();  weather.setDayOfWeek(weatherObject.get("week")  .getAsString());  weather.setDate(weatherObject.get("date").getAsString());  weather.setTemperature(weatherObject.get("temperature")  .getAsString());  weather.setWeather(weatherObject.get("weather")  .getAsString());  data.add(weather);  }  }  }  };   @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_weahter);  initViews();  setListeners();  }   private void initViews() {   etCity = (EditText) findViewById(R.id.etCity);  btnQuery = (ImageButton) findViewById(R.id.btnQuery);  lvFutureWeather = (ListView) findViewById(R.id.lvFutureWeather);  }   private void setListeners() {  btnQuery.setOnClickListener(new OnClickListener() {  @Override  public void onClick(View view) {  String city = etCity.getText().toString();  System.out.println("lvFutureWeather=" + lvFutureWeather);  Toast.makeText(WeahterActivity.this, "success",  Toast.LENGTH_LONG).show();  String weatherUrl = "http://v.juhe.cn/weather/index?format=2&cityname="  + city + "&key=ab9d7e2007472d723baf71fcdc4ba094";  HttpUtil.sendHttpRequest(weatherUrl,  new HttpCallbackListener() {  @Override  public void onFinish(String response) {  Message message = new Message();  message.what = SHOW_RESPONSE;  // 将服务器返回的结果存放到 Message 中  message.obj = response.toString();  handler.sendMessage(message);  }   @Override  public void onError(Exception e) {  System.out.println("访问失败");  }  });  }  });   } } 
四、最终实现效果图




2 0
原创粉丝点击