Android簡易版天気予報アプリの現実(3)


本論からActivityクラスのデザインが始まります~一、comを新規作成します.czy.weather.Activityパッケージは、国内の省、都市、区などの情報を表示するために使用されるChooseAreaActivityクラス継承Activityをパッケージの下に構築します.layoutフォルダの下のデフォルトのレイアウトファイルを削除し、choose_を新規作成します.area.xmlレイアウトファイルは、ChooseAreaActivityのビューファイルとして使用されます.choose_area.xmlには2つのコンポーネント、TextViewとListViewしかありません.TextViewコンポーネントは、現在選択されているリストの範囲を表示します.省リストに「中国」が表示され、省をクリックして都市リストに入った場合、省名が表示されます.ListViewは、地域リスト情報を表示するために使用されます.
<?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>

二、ChooseAreaActivityクラスが宣言する属性は以下のように、属性が少し多いかもしれませんが、以下でもその役割を説明します.
    //          
    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 WeatherDB weatherDB;

    private List<String> dataList = new ArrayList<String>();

    private List<Province> provinceList;

    private List<City> cityList;

    private List<County> countyList;

    private Province selectedProvince;

    private City selectedCity;

    private int currentLevel;

    private boolean isFromWeatherActivity;

    private SharedPreferences prefs;

地域情報リストはListViewの形で表示されるので、ArrayAdapter adapter;プロパティは、ListViewにデータを埋め込むために使用されます.したがって、ListViewコンポーネントをロードするときは、ローカル・データベースに保存されているかどうかを確認し、存在する場合はデータベースから取得し、そうでない場合はネットワーク要求データもネットワークに接続します.ローカル・データベース情報を要求する方法は、次の3つの関数です.-private void queryProvinces();private void queryCities(); - private void queryCounties(); ネットワーク要求データの方法は、-private void queryFromServer(final String code,final String type);コードは地域番号で、コードが空の場合は省のリストを要求し、「01」では北京管轄下の都市リストを要求し、具体的な使い方は前述した.typeはリクエストタイプで、現在リクエストされているのが省か都市か区かを示します.
private void queryProvinces() {
        provinceList = weatherDB.loadProvinces();
        if (provinceList.size() > 0) {
            dataList.clear();
            for (Province province : provinceList) {
                dataList.add(province.getProvince_name());
            }
            adapter.notifyDataSetChanged();
            listView.setSelection(0);
            titleText.setText("  ");
            currentLevel = LEVEL_PROVINCE;
        } else {
            queryFromServer(null, "province");
        }
    }

    private void queryCities() {
        cityList = weatherDB.loadCities(selectedProvince.getProvince_id());
        if (cityList.size() > 0) {
            dataList.clear();
            for (City city : cityList) {
                dataList.add(city.getCity_name());
            }
            adapter.notifyDataSetChanged();
            listView.setSelection(0);
            titleText.setText(selectedProvince.getProvince_name());
            currentLevel = LEVEL_CITY;
        } else {
            queryFromServer(selectedProvince.getProvince_id(), "city");
        }
    }

    private void queryCounties() {
        countyList = weatherDB.loadCounties(selectedCity.getCity_id());
        if (countyList.size() > 0) {
            dataList.clear();
            for (County county : countyList) {
                dataList.add(county.getCounty_name());
            }
            adapter.notifyDataSetChanged();
            listView.setSelection(0);
            titleText.setText(selectedCity.getCity_name());
            currentLevel = LEVEL_COUNTY;
        } else {
            queryFromServer(selectedCity.getCity_id(), "county");
        }
    }
private void queryFromServer(final String code, final String type) {
        String address;
        // code   
        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";
        }
        showProgerssDialog();
        HttpUtil.sendHttpRequest(address, new HttpCallbackListener() {
            @Override
            public void onFinish(String response) {
                boolean result = false;
                if ("province".equals(type)) {
                    result = Utility.handleProvincesResponse(weatherDB,
                            response);
                } else if ("city".equals(type)) {
                    result = Utility.handleCitiesResponse(weatherDB, response,
                            selectedProvince.getProvince_id());
                } else if ("county".equals(type)) {
                    result = Utility.handleCountiesResponse(weatherDB,
                            response, selectedCity.getCity_id());
                }
                if (result) {
                    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();
                    }
                });
            }
        });
    }

ChooseAreraActivityクラスのprotected void onCreate(Bundle savedInstanceState)を書き換えます.方法
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        isFromWeatherActivity = getIntent().getBooleanExtra(
                "from_weather_activity", false);
        prefs = PreferenceManager.getDefaultSharedPreferences(this);
        //   city     activity            
        if (prefs.getBoolean("city_selected", false) && !isFromWeatherActivity) {
            Intent intent = new Intent(this, WeatherActivity.class);
            startActivity(intent);
            finish();
            return;
        }
        //       
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.choose_area);

        listView = (ListView) findViewById(R.id.list_view);
        titleText = (TextView) findViewById(R.id.title_text);
        adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, dataList);
        listView.setAdapter(adapter);
        weatherDB = WeatherDB.getInstance(this);
        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int index,
                    long arg3) {
                if (currentLevel == LEVEL_PROVINCE) {
                    selectedProvince = provinceList.get(index);
                    queryCities();
                } else if (currentLevel == LEVEL_CITY) {
                    selectedCity = cityList.get(index);
                    queryCounties();
                } else if (currentLevel == LEVEL_COUNTY) {
                //        ,   Intent         
                    Editor editor = prefs.edit();
                    editor.putBoolean("city_selected", true);
                    editor.commit();
                    String county_name = countyList.get(index).getCounty_name();
                    Intent intent = new Intent(ChooseAreaActivity.this,
                            WeatherActivity.class);
                    intent.putExtra("county_name", county_name);
                    startActivity(intent);
                    finish();
                }
            }
        });
        queryProvinces();
    }

ChooseAreaActivityクラスでは、ユーザーが地域を選択するために3つのリストが前後して存在するため、現在のリストが省または都市または区を表示しているかを記録するタグが必要です.これには、次の3つの定数が使用されます.
    //          
    public static final int LEVEL_PROVINCE = 0;
    //          
    public static final int LEVEL_CITY = 1;
    //         
    public static final int LEVEL_COUNTY = 2;

リストが変更されると、currentLevel値が変更され、現在表示されている階層の情報がわかります.public void onBackPressed()メソッドを書き換え、ユーザーが戻りキーをクリックしたときにリストを順次終了できるようにします.
public void onBackPressed() {
        if (currentLevel == LEVEL_COUNTY) {
            queryCities();
        } else if (currentLevel == LEVEL_CITY) {
            queryProvinces();
        } else {
            if (isFromWeatherActivity) {
                Intent intent = new Intent(this, WeatherActivity.class);
                startActivity(intent);
            }
            finish();
        }
    }

また、データをロードするときに、より良いユーザー体験を得るために、データがロードされていることを示す進捗ダイアログボックスを表示し、キャンセルできないように設定することができます.また、進捗ダイアログをキャンセルする方法もあります.
    private void showProgerssDialog() {
        if (progressDialog == null) {
            progressDialog = new ProgressDialog(this);
            progressDialog.setMessage("    ……");
            progressDialog.setCanceledOnTouchOutside(false);
        }
        progressDialog.show();
    }

    private void closeProgressDialog() {
        if (progressDialog != null) {
            progressDialog.dismiss();
        }
    }

次は天気情報提示画面WeatherActivityの作成ができます~