歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

天氣預報(Android版)

今天終於把天氣預報給弄出來了,心裡小小的高興一下,雖然這東西網上早就有了,但那畢竟是別人的。在想做這個之前,以為

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

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

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

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

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

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

Copyright © Linux教程網 All Rights Reserved