歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 天氣預報(Android版)

天氣預報(Android版)

日期:2017/3/1 10:48:03   编辑:Linux編程
今天終於把天氣預報給弄出來了,心裡小小的高興一下,雖然這東西網上早就有了,但那畢竟是別人的。在想做這個之前,以為

天氣預報軟件好高深,不知道從何下手。不過現在想想這東西也不是想象中那麼復雜。最主要的是自己親手做出來,感覺挺很爽的,要是有真機就更好了!

OK,在下面我把天氣預報簡單叫weather好了,在做weather之前我在網上有搜了一下有關它的資料,知道weather一般的是解析XML文檔來獲取信息。

本文源碼下載:

免費下載地址在 http://linux.linuxidc.com/

用戶名與密碼都是www.linuxidc.com

具體下載目錄在 /pub/Android源碼集錦/2011年/12月/天氣預報(Android版)/

可能還有別的方式Json....所以就有了之前兩篇學習解析XML的學習天氣預報Dom解析 ( http://www.linuxidc.com/Linux/2011-12/49439.htm ) 學習SAX解析 ( http://www.linuxidc.com/Linux/2011-12/49440.htm ) 以這兩篇學習做鋪墊。然

後再結合自己學的Android知識就可以完成本次小程序。本次寫的weather裡主要涉及到AutoCompleteTextView,ListView以及

SAX技術 。先上weather運行時的效果圖:

weather布局很丑,哎,俺沒啥藝術細胞,只想到這樣的布局,重在功能實現上。這次是用SAX解析XML,同樣是用到了谷歌提供

的天氣接口。在上次的學習SAX解析http://www.linuxidc.com/Linux/2011-12/49440.htm)中裡面我做的是解析本地的XML,很順利。在做weather的同時我順便寫了個控制台版的天氣

預報,發現了有同樣的問題:結果只出現溫度,而中文信息卻是亂碼。在這上面我糾結了大半天後來才知道為什麼,原因是編碼不

對,最後換成了GBK編碼就搞定了 下面是代碼片段。

  1. URL url = new URL(path);
  2. URLConnection conn = url.openConnection();
  3. InputStreamReader isr = new InputStreamReader(conn.getInputStream(),"GBK"); //GBK編碼就OK,用utf-8還是出現亂碼
  4. BufferedReader br = new BufferedReader(isr);
  5. InputSource is = new InputSource(br);
  6. xmlReader.parse(is);

另外,ListView用SimpleAdapter加載圖片,這個適配器的數據是鍵值對(Map)形式的,如果map中包含有圖片,而這個圖片不是在

drawable中存在的,比如網絡圖片,simpleAdapter本身就不支持的。除非你重寫適配器(Adapter),

或者用ViewBinder 具體用法見API文檔

public void setViewBinder (SimpleAdapter.ViewBinder viewBinder)

SimpleAdapter的外部數據(external clients)可以使用這個類將值綁定到視圖。你應該用這個類綁定值到那些不能直接通過SimpleAdapter支持的視圖,或者改變通過SimpleAdapter支持綁定的方法的視圖。

也就是說simpleAdapter不能直接支持ImageView,像TextView就直接支持,不用大費周章綁定數據。

下面是主類繼承Activity

  1. package com.weather.manymore13;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.UnsupportedEncodingException;
  6. import java.net.MalformedURLException;
  7. import java.net.URL;
  8. import java.net.URLConnection;
  9. import java.util.ArrayList;
  10. import java.util.Map;
  11. import javax.xml.parsers.ParserConfigurationException;
  12. import javax.xml.parsers.SAXParser;
  13. import javax.xml.parsers.SAXParserFactory;
  14. import org.xml.sax.InputSource;
  15. import org.xml.sax.SAXException;
  16. import org.xml.sax.XMLReader;
  17. import android.app.Activity;
  18. import android.content.Intent;
  19. import android.graphics.Bitmap;
  20. import android.graphics.Color;
  21. import android.os.Bundle;
  22. import android.text.StaticLayout;
  23. import android.view.View;
  24. import android.view.View.OnClickListener;
  25. import android.widget.ArrayAdapter;
  26. import android.widget.AutoCompleteTextView;
  27. import android.widget.Button;
  28. import android.widget.ImageView;
  29. import android.widget.ListView;
  30. import android.widget.SimpleAdapter;
  31. import android.widget.SimpleAdapter.ViewBinder;
  32. import android.widget.TextView;
  33. public class WeatherActivity extends Activity {
  34. private AutoCompleteTextView autoText;
  35. private Button btnConfirm;
  36. private TextView tViewCurrent;
  37. private ListView lv;
  38. private ArrayList<Map<String,Object>> list;
  39. private ImageView currentIcon;
  40. private TextView currentInfo;
  41. private TextView futionTime;
  42. private SimpleAdapter simpAdapter = null;
  43. private boolean visit = true;
  44. public void init()
  45. {
  46. autoText = (AutoCompleteTextView)findViewById(R.id.autoTextView);
  47. btnConfirm = (Button)findViewById(R.id.btn_confirm);
  48. tViewCurrent = (TextView)findViewById(R.id.current_time);
  49. lv = (ListView)findViewById(R.id.myListView);
  50. currentIcon = (ImageView)findViewById(R.id.current_icon);
  51. currentInfo = (TextView)findViewById(R.id.current_info);
  52. futionTime = (TextView)findViewById(R.id.future_time);
  53. }
  54. @Override
  55. public void onCreate(Bundle savedInstanceState) {
  56. super.onCreate(savedInstanceState);
  57. setContentView(R.layout.main);
  58. init();
  59. ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>
  60. (this, android.R.layout.simple_dropdown_item_1line,
  61. Tools.city);
  62. autoText.setAdapter(arrayAdapter);
  63. btnConfirm.setOnClickListener(new OnClickListener() {
  64. public void onClick(View arg0) {
  65. System.out.println("按鈕被按下");
  66. String city = autoText.getText().toString().trim();
  67. tViewCurrent.setVisibility(View.INVISIBLE);
  68. futionTime.setVisibility(View.INVISIBLE);
  69. if(!(city.equals("")))
  70. {
  71. try {
  72. obtainWeacherInfo(Tools.SEACH_URL+city);
  73. if(simpAdapter!=null)
  74. {
  75. simpAdapter.notifyDataSetChanged();
  76. }
  77. } catch (MalformedURLException e) {
  78. System.out.println("url出錯");
  79. e.printStackTrace();
  80. }
  81. catch (Exception e) {
  82. e.printStackTrace();
  83. }
  84. }
  85. }
  86. });
  87. }
  88. public void obtainWeacherInfo(String path) throws ParserConfigurationException, SAXException, UnsupportedEncodingException, IOException
  89. {
  90. SAXParserFactory parserFactory = SAXParserFactory.newInstance();
  91. SAXParser sp = parserFactory.newSAXParser();
  92. XMLReader xmlReader = sp.getXMLReader();
  93. WeacherHandler handler = new WeacherHandler();
  94. xmlReader.setContentHandler(handler);
  95. URL url = new URL(path);
  96. URLConnection conn = url.openConnection();
  97. InputStreamReader isr = new InputStreamReader(conn.getInputStream(),"GBK");
  98. BufferedReader br = new BufferedReader(isr);
  99. InputSource is = new InputSource(br);
  100. xmlReader.parse(is);
  101. br.close();
  102. displayWeatherInfo(handler);
  103. }
  104. public void displayWeatherInfo(WeacherHandler handler)
  105. {
  106. list = handler.getForecastWeachers();
  107. //顯示實時信息
  108. Bitmap bmp = handler.getCurrentWeather().getBmp();
  109. String currentInfoStr = handler.getCurrentWeather().getCurrentInfo().toString();
  110. currentIcon.setImageBitmap(bmp);
  111. currentInfo.setText(currentInfoStr);
  112. if(list.size() < 1)
  113. {
  114. System.out.println("displayWeatherInfo: list.size() < 1");
  115. currentInfo.setText(R.string.prompt);
  116. currentInfo.setTextColor(Color.YELLOW);
  117. currentInfo.setVisibility(View.VISIBLE);
  118. }
  119. // 顯示未來天氣, 我們這裡是在ListView中顯示
  120. String[] itemName = new String[]{"week","temperature","condition","icon"};
  121. int[] itemId = new int[]{R.id.week, R.id.temperature, R.id.condition,R.id.icon};
  122. simpAdapter = new SimpleAdapter(this,
  123. list,R.layout.list_item,
  124. itemName,itemId);
  125. lv.setAdapter(simpAdapter);
  126. if(list.size() > 0)
  127. {
  128. tViewCurrent.setVisibility(View.VISIBLE);
  129. futionTime.setVisibility(View.VISIBLE);
  130. }
  131. // 注意在這裡用到了綁定數據 ImageView綁定了網絡圖片
  132. simpAdapter.setViewBinder(new ViewBinder() {
  133. public boolean setViewValue(View view, Object data,
  134. String textRepresentation) {
  135. if(view instanceof ImageView && data instanceof Bitmap){
  136. ImageView iv = (ImageView) view;
  137. iv.setImageBitmap((Bitmap) data);
  138. return true;
  139. }else {
  140. return false;
  141. }
  142. }
  143. });
  144. }
  145. }

在這個裡面跟網絡地址建立連接,需要得到InputStream流,在這種情況下一般得另開一個線程,這都是耗時的操作,不然有的時

候網路出現延遲就會導致程序假死在哪裡就不好使了,在這個weather裡我沒有用線程,隨著一步一步的學習後面再加上,

最後 ,別忘了加這玩意兒 <uses-permission android:name="android.permission.INTERNET"></uses-permission>

這東西讓我蛋疼了很久,升級後,模擬器當時連個錯都不爆,千萬不要忘記。

Copyright © Linux教程網 All Rights Reserved