初學者安卓筆記——天氣項目(1)

歡迎大家閱讀我的初學者安卓筆記导匣,學習安卓的一些基礎知識有了很長一段時間魂挂,也是看了《第一行代碼》這本書旺芽,從我看過的幾本書中瘾婿,截止目前我認為《第一行代碼》是一本最適合初學者學習安卓的書籍宾濒,這本書中不僅內容極為豐富祈餐,而且作者將知識表達的通俗易懂褥符,再加上一些比較有意思的章節(jié)一小段話家破。我強烈建議想學習安卓的小伙伴買此書學習仓坞,由于最近寫了這本書最后的天氣項目背零,所以在這里寫下關于天氣項目的一些心得。

對于一個應用程序來說會有大量的數據的處理无埃,那么數據是從哪里得到的那侦镇?分兩種织阅,一種是從數據庫中壳繁,數據庫中獲取大家應該并不陌生,例如安卓本身自帶的SQLite相信很多人在剛開始學習的時候都有用過。另一種則是從服務器中獲取氮趋,本項目中用到了中國天氣網提供的API接口實現(xiàn)的從服務器中獲取的信息剩胁。

做一個項目我們當然首先要分析出我們這個應用都應該具備哪些功能诉植,用什么樣的技術去實現(xiàn)。

第一個功能:天氣項目自然而然會涉及到我國的城市信息啊犬,也就是能夠羅列出我國所有的省灼擂、市、縣觉至。技術方面我們通過下面這個網址www.weather.com.cn/data/list3/city.xml從服務器中獲取城市信息剔应,大家可以看一下進入該網址后服務器給我返回的信息.

省級城市

這是我在調試程序下看到的從該網址返回的省份的信息。不難發(fā)現(xiàn)省份之間是由逗號隔開语御,同時每個省份前面都有其編號依次排列峻贮。如果想要知道當前省份所含的市級地區(qū)也不難,www.weather.com.cn/data/list3/city省級代號.xml 舉例黑龍江省級代號是05应闯,把網址中省級代號替代為05即可纤控,下圖是服務器返回的黑龍江所含市級地區(qū)。

市級城市

由圖中不難看出我們輕松的獲取到了黑龍江省下所含市級城市碉纺,獲取縣級城市和上面獲取市級城市的方法一樣船万,即把省級代號那里換成市級代號就可以完成,下圖是伊春市所含縣級地區(qū)骨田。


縣級城市

下面我們就看看怎么在代碼中實現(xiàn)吧耿导。
在這之前有一個非常重要的事情要提前說一下,我覺得項目中文件的結構非常重要态贤,我們應該像把書放入書柜中一樣舱呻,把一類的書放到一個書柜的位置中,項目中就是把不同作用的文件放到不同的包中抵卫,下圖的結構是一個比較不錯的文件結構狮荔。


文件結構

activity不用多說自然是我們存放活動代碼的地方
db是數據庫(Date base)的縮寫自然存放數據庫相關代碼
model我用于存放表的代碼
util(工具)自然是將工具相關的代碼(網絡工具等)

正式步入正題

我們在使用應用時胎撇,不難發(fā)現(xiàn)關閉網絡后在上網時顯示的內容依然可以顯示介粘,這是因為應用中將從服務器獲取的數據存儲到了本地,所以我們先創(chuàng)建一個數據庫晚树,在這里我們直接用安卓自帶的數據庫SQLite姻采。
我們在db包中先創(chuàng)建CoolWeatherOpenHelper類(用于建表),繼承SQLiteOpenHelper類爵憎,繼承和擴展SQLiteOpenHelper類主要做的工作就是重寫以下兩個方法慨亲。

onCreate(SQLiteDatabase db) : 當數據庫被首次創(chuàng)建時執(zhí)行該方法婚瓜,一般將創(chuàng)建表等初始化操作在該方法中執(zhí)行。

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL(CREATE_PROVINCE);//創(chuàng)建Province表
    db.execSQL(CREATE_CITY);//創(chuàng)建City表
    db.execSQL(CREATE_COUNTY);//創(chuàng)建County表
}

onUpgrade(SQLiteDatabse dv, int oldVersion,int new Version):當打開數據庫時傳入的版本號與當前的版本號不同時會調用該方法刑棵。

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}

建三張表 分別是Province巴刻、City、County 作用是分別存放省蛉签、市胡陪、縣的數據信息。建表的語句是SQL語句碍舍,很簡單柠座,大家如果不太了解可以上網百度一下,記住一些基本的語句就沒有問題片橡,下面是建表語句:

  /*
    Province表建表語句
 */
public static final String CREATE_PROVINCE="create table Province ("
        +"id integer primary key autoincrement,"
        +"province_name text,"
        +"province_code text)";
/*
* City表建表語句
* */
public  static final String CREATE_CITY="create table City ("
        +"id integer primary key autoincrement,"
        +"city_name text,"
        +"city_code text,"
        +"province_id integer)";
/*
* County表建表語句
* */
public static final String CREATE_COUNTY="create table County ("
        +"id integer primary key autoincrement,"
        +"county_name text,"
        +"county_code text,"
        +"city_id integer)";

CoolWeatherOpenHelper類的代碼我們就完成了妈经,我們有了建表語句,當然也需要定義一下這三個表捧书,于是在model包中定義這三個類

三個類

類中的寫法很簡單在這里我就以City類舉例吹泡,大家可以去下載源碼看一下那兩個類的寫法。

public class City {
private int id;//數據庫中存儲的id
private String cityName;//市級名
private String cityCode;//市級代號
private int provinceId;//市級所屬于的省級的id

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getCityName() {
    return cityName;
}

public void setCityName(String cityName) {
    this.cityName = cityName;
}

public String getCityCode() {
    return cityCode;
}

public void setCityCode(String cityCode) {
    this.cityCode = cityCode;
}

public int getProvinceId() {
    return provinceId;
}

public void setProvinceId(int provinceId) {
    this.provinceId = provinceId;
}

}

我們在數據庫中建表的工作就完成了鳄厌!表中都是get和set的方法荞胡,用于對表中的數據進行獲取和修改,感謝朋友們的支持了嚎,繼續(xù)往下寫...

我們在db包中新建一個CoolWeatherDB類泪漂,此類用于操作數據庫,大家思考一下這個類中需要什么方法歪泳,首先肯定需要將省萝勤、市、縣的數據存儲呐伞,隨之而然還需要能夠獲取到他們敌卓,簡而言之這個類中我們需要6個方法×媲猓看下面的代碼趟径,我會詳細注釋

package com.example.coolweather.db;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.example.coolweather.model.City;
import com.example.coolweather.model.County;
import com.example.coolweather.model.Province;

import java.util.ArrayList;
import java.util.List;


public class CoolWeatherDB {

    /*
    * 數據庫名
    * */

    public static final String DB_NAME = "cool_weather";

    /*
    * 數據庫版本
    * */

    public static final int VERSION=1;

    private static CoolWeatherDB coolWeatherDB;//創(chuàng)建對象

    private SQLiteDatabase db;//這個類用于管理和操作SQLite數據庫,對數據庫的操作離不開這個類

    /*
    * 將構造方法私有化
    * 保證全局范圍內只會有一個實例
    * */
    private CoolWeatherDB(Context context){
        CoolWeatherOpenHelper dbHelper = new CoolWeatherOpenHelper(context,DB_NAME,null,VERSION);
        //創(chuàng)建建表類癣防,傳入的參數分別是上下文蜗巧,數據庫名,第三個參數不用管蕾盯,數據庫版本
        db=dbHelper.getWritableDatabase();//通過getWritableDatabase()方法獲取到db實例
    }

    /*
    * 獲取CoolWeather的實例
    * */
    public synchronized static CoolWeatherDB getInstance(Context context){
    //對synchronized類不太了解的朋友可以百度一下
        if(coolWeatherDB==null){
        //如果數據庫的操作類對象不存在則創(chuàng)建對象
            coolWeatherDB=new CoolWeatherDB(context);
        }
        return coolWeatherDB;
    }

    /*
    * 將Province實例存儲到數據庫
    * */
    public void saveProvince(Province province){
        if(province!=null){
        //ContentValues類是負責存儲一些鍵值對幕屹,但是它存儲的鍵值對當中的名是一個String類型(第一個參數),而值都是基本類型。
       //說白了此類在這里用就是存儲一下省的名字及代號
            ContentValues values = new ContentValues();
            values.put("province_name",province.getProvinceName());
            values.put("province_code",province.getProvinceCode());
            db.insert("Province",null,values);
        }
    }
    /*
    * 從數據庫讀取全國所有的省份信息
    * */
    public List<Province> loadProvince(){
        List<Province> list = new ArrayList<>();
//這個應該很熟悉list集合且該集合存儲的均為Province類型望拖,如果對集合不是很清楚可以看一下java的基礎知識
//Cursor 類是每行的集合渺尘,先查詢Province表將其中的數據內容放到Cursor類中
        Cursor cursor =db.query("Province",null,null,null,null,null,null);
        if(cursor.moveToFirst()){//從第一行開始
            do{
                Province province =new Province();
                province.setId(cursor.getInt(cursor.getColumnIndex("id")));
            //getColumnIndex是返回指定列的名稱,然后用get方法獲取到想要的值并放到新創(chuàng)建的Province類中    
                province.setProvinceName(cursor.getString(cursor.getColumnIndex("province_name")));
                province.setProvinceCode(cursor.getString(cursor.getColumnIndex("province_code")));
                list.add(province);//添加到集合中
            }while(cursor.moveToNext());
        }
        return list;
    }

    /*
    * 將City實例存儲到數據庫
    * */
    public void saveCity(City city){
        if(city!=null){
            ContentValues values = new ContentValues();
            values.put("city_name",city.getCityName());
            values.put("city_code",city.getCityCode());
            values.put("province_id",city.getProvinceId());
            db.insert("City",null,values);

        }
    }

    /*
    * 從數據庫讀取某省下所有的城市信息
    * */

    public List<City> loadCities(int provinceId){
        List<City> list = new ArrayList<>();
        Cursor cursor = db.query("City",null,"province_id=?",new String[] {String.valueOf(provinceId)}
                ,null,null,null);
        if(cursor.moveToFirst()){
            do{
                City city = new City();
                city.setId(cursor.getInt(cursor.getColumnIndex("id")));
                city.setCityName(cursor.getString(cursor.getColumnIndex("city_name")));
                city.setCityCode(cursor.getString(cursor.getColumnIndex("city_code")));
                city.setProvinceId(provinceId);
                list.add(city);
            }while(cursor.moveToNext());
        }
        return list;
    }

    /*
    * 將County實例存儲到數據庫中
    * */
    public void saveCounty(County county){
        if(county!=null){
            ContentValues values = new ContentValues();
            values.put("county_name",county.getCountyName());
            values.put("county_code",county.getCountyCode());
            values.put("city_id",county.getCityId());
            db.insert("County",null,values);
        }
    }

    /*
    * 從數據庫讀取某城市下所有縣的信息
    * */
    public List<County> loadCounties(int cityId){
        List<County> list = new ArrayList<>();
        Cursor cursor = db.query("County",null,"city_id=?",new String[]{String.valueOf(cityId)},
                null,null,null);
        if(cursor.moveToFirst()){
            do{
                County county = new County();
                county.setId(cursor.getInt(cursor.getColumnIndex("id")));
                county.setCountyName(cursor.getString(cursor.getColumnIndex("county_name")));
                county.setCountyCode(cursor.getString(cursor.getColumnIndex("county_code")));
                county.setCityId(cityId);
                list.add(county);
            }while(cursor.moveToNext());

        }
        return list;
    }
}

是不是非常的簡單说敏,我詳細的注釋了Province表的存儲和獲取信息鸥跟,其他兩個表中個方法類似,因此你可以輕松的理解盔沫。到這里我們已經完成了對數據庫操作的基本代碼锌雀,下面就是如何從服務器中獲取到我們所需要的數據,相信你也已經迫不及待了迅诬,接著往下看吧腋逆。

由于要從服務器中獲取,所以我們在util(工具)包中新建一個HttpUtil類侈贷,這個類中的代碼如下:

package com.example.coolweather.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;


public class HttpUtil {

//用static是因為可以不用創(chuàng)建實例惩歉,即可調用該方法。開子線程是因為網絡獲取數據非常耗時俏蛮,防止堵塞
//我們還用到了HttpCallbackListener接口為了實現(xiàn)回調接收服務器返回的結果
    public static void sendHttpRequest(final String address,final HttpCallbackListener listener){
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection =null;
                try {
                    //下面是安卓的網絡操作撑蚌,很簡單為大家介紹一下
                    //URL說白了就是一個網址,在這里我們也可以稱之為網絡接口
                    //  首先我們獲取到了接口搏屑,然后用openConnection獲取到了HttpURLConnection的實例争涌,再往下就是設置他的屬性
                    URL url = new URL(address);
                    connection = (HttpURLConnection) url.openConnection();
                    //GET表示從服務器中獲取數據,下面設置的是連接超時辣恋,讀取超時毫秒數
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    //我們還要定義一個輸入流亮垫,用于讀取connection中的信息
                    //下面是讀取信息的代碼
                    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);//依行添加到respond對象中
                    }
                    if(listener!=null){
                        //回調onFinish()方法
                        listener.onFinish(response.toString());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    if(listener!=null){
                        listener.onError(e);
                    }
                }finally {
                    if(connection!=null){
                        connection.disconnect();//斷開連接
                    }
                }
            }
        }).start();//運行線程
    }
}

上面提到了我們用的是HttpCallbackListener接口實現(xiàn)的回調(Java提供的回調機制),因此我把接口的代碼也展示出來。

public interface HttpCallbackListener {
    void onFinish(String response);

    void onError(Exception e);
}

現(xiàn)在我們可以獲取到從服務器返回的數據伟骨,在上文中我也說過其返回數據的格式是“代號|城市饮潦,代號|城市”,我們想要獲取代號或者城市携狭,必然涉及到解析過程继蜡,那么如何解析那,很簡單

在util包中新建一個Utility類逛腿,這個類專門負責解析處理服務器返回的數據稀并,下面是我們解析的代碼,我會詳細的說明如何解析:

package com.example.coolweather.util;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.text.TextUtils;

import com.example.coolweather.db.CoolWeatherDB;
import com.example.coolweather.model.City;
import com.example.coolweather.model.County;
import com.example.coolweather.model.Province;

import org.json.JSONException;
import org.json.JSONObject;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;


public class Utility {
    /*
    * 解析和處理服務器返回的省級數據
    * */
    public synchronized  static boolean handleProvinceResponse(CoolWeatherDB coolWeatherDB
            ,String response){
        if(!TextUtils.isEmpty(response)){
            String[] allProvince = response.split(",");//將response字符串中的內容以逗號為界限分開存儲到allProvince數組中
            if(allProvince!=null&&allProvince.length>0){
                for(String p:allProvince){
                    String[] array = p.split("\\|");//split中傳入的參數為正則表達式 需要兩個\\才能代表|
                    Province province = new Province();
                    //解析后 代號位于數組第一個位置单默,名字位于第二個位置
                    province.setProvinceCode(array[0]);
                    province.setProvinceName(array[1]);
                    //將解析出來的數據存儲到Province表
                    coolWeatherDB.saveProvince(province);
                }
                return true;//成功解析
            }
        }
        return false;
    }

    /*
    * 解析和處理服務器返回的市級數據
    * */

    public static boolean handleCitiesponse(CoolWeatherDB coolWeatherDB,String response,int provinceId){
        if(!TextUtils.isEmpty(response)){
            String[] allCities = response.split(",");
            if(allCities!=null&&allCities.length>0){
                for(String c:allCities){
                    String[] array = c.split("\\|");
                    City city = new City();
                    city.setCityCode(array[0]);
                    city.setCityName(array[1]);
                    city.setProvinceId(provinceId);
                    //將解析出來的數據存儲到City表中
                    coolWeatherDB.saveCity(city);
                }
                return true;
            }
        }
        return false;
    }

    /*
    * 解析和處理服務器返回的縣級數據
    * */

    public static boolean handleCountiesResponse(CoolWeatherDB coolWeatherDB,String response,int cityId){
        if(!TextUtils.isEmpty(response)){
            String[] allCounties = response.split(",");
            if(allCounties!=null&&allCounties.length>0){
                for(String c:allCounties){
                    String[] array = c.split("\\|");
                    County county = new County();
                    county.setCountyCode(array[0]);
                    county.setCountyName(array[1]);
                    county.setCityId(cityId);
                    //將解析出來的數據存儲到County表中
                    coolWeatherDB.saveCounty(county);
                }
                return true;
            }
        }
        return false;

    }

   
}

簡單的說我們的解析規(guī)則就是先按逗號分隔碘举,再按單數線分割并放入數組中,再從數組中取出雕凹。解析也搞定了殴俱!

下面的工作自然是將我們解析出來的城市顯示到界面上,我們做了這么多的幕后工作枚抵,為界面的顯示做了非常充分的工作线欲,下面讓我們一起寫一下顯示城市的界面,界面自然要放到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_parent"
        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>

把代碼粘貼到你的Android studio中你就可以清楚的知道這些代碼的作用了汽摹,其實就是簡單的加了一個顯示文本內容的主標題和一個用于顯示城市名的listview李丰,寫法非常簡單。

布局文件寫完了逼泣,下面自然要寫與它相關聯(lián)的類文件ChooseAreaActivity


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<>();//數據列表

    /*
    * 省列表
    * */
    private List<Province> provinceList;
    /*
    * 市列表
    * */
    private List<City> cityList;
    /*
    * 縣列表
    * */
    private List<County> countyList;
    /*
    * 選中的省份
    * */
    private Province selectedProvince;
    /*
    * 選中的城市
    * */
    private City selectedCity;
    /*
    * 當前選中的級別
    * */
    private int currentLevel;

    @Override
    public 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);
        //初始化適配器 并顯示在listview中
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, dataList);
        listView.setAdapter(adapter);
        //獲取到CoolWeatherDB的實例
        coolWeatherDB = coolWeatherDB.getInstance(this);
        //listview的點擊事件
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (currentLevel == LEVEL_PROVINCE) {//如果當前選中的級別是省級
                    //省列表中獲取到當前點擊位置的省的信息
                    selectedProvince = provinceList.get(position);
                    queryCities();//加載市級數據
                } else if (currentLevel == LEVEL_CITY) {
                    selectedCity = cityList.get(position);
                    queryCounties();//加載縣級數據
                }
            }
        });
        queryProvinces();//加載省級數據
    }


    /*
    * 查詢全國所有的省趴泌,優(yōu)先從數據庫查詢,如果沒有查詢到再去服務器上查詢
    * */
    private void queryProvinces() {
        //從數據庫中讀取省級數據
        provinceList = coolWeatherDB.loadProvince();//加載省份
        if (provinceList.size() > 0) {
            dataList.clear();//清空dataList中的數據
            for (Province province : provinceList) {
                dataList.add(province.getProvinceName());//向dataList中添加省份名字信息
            }
            adapter.notifyDataSetChanged();
            listView.setSelection(0);//滑動列表默認第一個位置
            titleText.setText("中國");//更改標題為中國
            currentLevel = LEVEL_PROVINCE;
        } else {
            queryFromServer(null, "province");
        }
    }

    /*
    * 查詢全國所有的市拉庶,優(yōu)先從數據庫中查詢嗜憔,如果沒有查詢到再去服務器上查詢
    * */
    private void queryCities() {
        cityList = coolWeatherDB.loadCities(selectedProvince.getId());//加載該省份所含的城市信息 需要傳入省份地址參數
        //從數據庫中獲取
        if (cityList.size() > 0) {
            dataList.clear();//如果dataList中有數據就清空
            for (City city : cityList) {//遍歷cityList
                dataList.add(city.getCityName());
            }
            adapter.notifyDataSetChanged();
            listView.setSelection(0);//將滑動列表設置默認第一行
            titleText.setText(selectedProvince.getProvinceName());//將標題設置為選中的省份的名字
            currentLevel = LEVEL_CITY;//設置當前級別為市級
        } else {
            //從服務器上獲取
            queryFromServer(selectedProvince.getProvinceCode(), "city");
        }
    }

    /*
    * 查詢所有的縣,優(yōu)先從數據庫中查詢氏仗,如果沒有則再到服務器中查詢
    * */
    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.handleProvinceResponse(coolWeatherDB, response);
                    //調用解析服務器返回數據的方法
                } else if ("city".equals(type)) {
                    result = Utility.handleCitiesponse(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(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);//點擊對話框外部不取消對話框顯示
        }
    }

    /*
    * 關閉進度對話框
    * */
    private void closeProgressDialog() {
        if (progressDialog != null) {
            progressDialog.dismiss();//釋放資源
        }
    }

    /*
    * 捕獲Back按鍵 根據當前的級別來判斷吉捶,此時應該返回市列表、省列表皆尔、還是直接退出
    * */

    @Override
    public void onBackPressed() {
        //當為縣級時 點擊返回鍵后退到市級
        if(currentLevel==LEVEL_COUNTY){
            queryCities();
        }else if(currentLevel==LEVEL_CITY){
            queryProvinces();
        }
            finish();
        }
    }
}

這個類實現(xiàn)的是從服務器中獲取到數據并通過工具包中的Utility類將服務器返回的數據解析并放到了ListView中顯示呐舔。對于ListView顯示數據通過適配器在這里不在贅述,代碼中還寫了點擊事件慷蠕,因為根據用戶所點擊的不同等級的城市(省珊拼、市)其調用的方法自然不同,如果是省級則我們應該從服務器中獲取該省所包含的市級的信息流炕。在最后面處onBackPressed()方法實現(xiàn)的是將返回鍵重寫澎现,當我們的界面位于縣級城市時,點擊返回鍵返回市級城市每辟。當我們的界面位于市級城市時昔头,點擊返回鍵返回省級城市。最后不要忘記在AndroidManifest.xml文件中添加網絡權限

網絡權限

我們天氣項目的第一個功能獲取城市信息的功能就完美的完成了影兽!

省信息

市信息

縣信息

請等待后續(xù)(2)...

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末揭斧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子峻堰,更是在濱河造成了極大的恐慌讹开,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捐名,死亡現(xiàn)場離奇詭異旦万,居然都是意外死亡,警方通過查閱死者的電腦和手機镶蹋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來断箫,“玉大人仲义,你說我怎么就攤上這事〉迹” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拇厢。 經常有香客問我爷抓,道長传透,這世上最難降的妖魔是什么躯肌? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任怜瞒,我火速辦了婚禮,結果婚禮上近刘,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好呐芥,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布思瘟。 她就那樣靜靜地躺著,像睡著了一般虾攻。 火紅的嫁衣襯著肌膚如雪铡买。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天霎箍,我揣著相機與錄音奇钞,去河邊找鬼。 笑死漂坏,一個胖子當著我的面吹牛景埃,可吹牛的內容都是我干的。 我是一名探鬼主播顶别,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谷徙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了驯绎?” 一聲冷哼從身側響起完慧,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎剩失,沒想到半個月后屈尼,有當地人在樹林里發(fā)現(xiàn)了一具尸體册着,經...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年脾歧,在試婚紗的時候發(fā)現(xiàn)自己被綠了甲捏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡鞭执,死狀恐怖司顿,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情兄纺,我是刑警寧澤大溜,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站囤热,受9級特大地震影響猎提,放射性物質發(fā)生泄漏获三。R本人自食惡果不足惜旁蔼,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疙教。 院中可真熱鬧棺聊,春花似錦、人聲如沸贞谓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽裸弦。三九已至祟同,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間理疙,已是汗流浹背晕城。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留窖贤,地道東北人砖顷。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓毡咏,卻偏偏與公主長得像奋救,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子嘱巾,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,129評論 25 707
  • 1. Java基礎部分 基礎部分的順序:基本語法授嘀,類相關的語法物咳,內部類的語法,繼承相關的語法蹄皱,異常的語法所森,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理囱持,服務發(fā)現(xiàn),斷路器焕济,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • 一個人纷妆,一件事,一顆平常心晴弃。留不住的人掩幢,留不住的心。好想睡一覺上鞠,靜靜的夢鄉(xiāng)际邻,只有歡快的芳香,慢慢的走芍阎,細細的游...
    御雨閱讀 161評論 0 0
  • 心隨物動,情隨事遷岭佳,如果一個人的房間里充斥的是不需要的東西血巍,自己也會有一種不被需要的感覺。 只買自己需要和喜歡的珊随,...
    當向上翊遇上文藝翊閱讀 275評論 0 0