android天气预报开发_Android应用程式开发:天气预报的天气应用程式

本教程详述了如何开发一个Android天气应用程序,包括应用布局设计、使用HTTP和AsyncTask获取JSON数据、JSON解析以及利用ViewPager展示天气预报。内容涵盖了布局设计、HTTP连接、JSON数据解析、数据模型创建以及使用ViewPager和适配器处理多个页面。
摘要由CSDN通过智能技术生成

android天气预报开发

本教程将介绍如何开发android应用程序 。 在本教程中,我们将探讨创建Android应用程序所需的内容以及可用于创建应用程序的积木。 例如,我们将创建一个天气应用程序。 几个月前我们谈到了它 ,我们将开发具有天气状况和天气预报的天气应用程序。 要开发一个android应用程序,我们至少需要:

  • 一个活动
  • 布局

这些是我们可以使用的基本组件。 当然,我们想创建一些更复杂的东西,因为我们必须从远程服务器(在本例中为openweathermap)中检索信息,并且必须解析结果数据。 因此,我们需要添加以下基本组件:

  • HTTP连接
  • AsyncTask(没有ANR问题)
  • JSON解析
  • 数据模型(包含JSON数据)

最后,我们将获得:

android_weather_app [4]

应用布局

第一步是创建布局。 从下面的图像中可以看到,我们的布局分为两部分:一个保存当前的天气状况,另一个保存天气预报。 在天气预报中,我们必须在不同的日期之间移动,以便可以使用ViewPager. 在这种情况下,我们可以使用LinearLayout:

android_linearlayout [4]

现在我们有了布局,我们可以开始每个部分的工作了。 在第一部分(当前天气)中,我们可以使用RelativeLayout将每个小部件放置在正确的位置:

<RelativeLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:layout_weight="1" >

<TextView
    android:id="@+id/cityText"
    style="?android:attr/textAppearanceMedium"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true">        
</TextView>

<TextView
    android:id="@+id/temp"
    style="@style/tempStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/cityText"
    android:layout_centerHorizontal="true">        
</TextView>
<TextView
    android:id="@+id/unittemp"        
    android:layout_width="wrap_content"
    style="?android:attr/textAppearanceMedium"
    android:layout_height="wrap_content"
    android:layout_below="@id/cityText"
    android:layout_toRightOf="@id/temp"
    android:layout_alignBaseline="@id/temp">        
</TextView>
<TextView
    android:id="@+id/skydesc"        
    android:layout_width="wrap_content"
    style="?android:attr/textAppearanceMedium"
    android:layout_height="wrap_content"
    android:layout_below="@id/temp"        
    android:layout_alignStart="@id/temp"
    android:layout_toRightOf="@id/temp">
</TextView>

<!--  Image weather condition -->
<ImageView android:id="@+id/condIcon"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_alignTop="@id/temp"
            android:layout_toRightOf="@id/temp"/>

</RelativeLayout>

正如我们所说的,在第二部分中,我们必须显示几天的预测。 在这种情况下,我们可以使用ViewPager来帮助我们在页面之间滑动,因此我们具有:

<android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="6" >

      <android.support.v4.view.PagerTitleStrip
            android:id="@+id/pager_title_strip"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:background="#E6E6E6"
            android:paddingBottom="4dp"
            android:paddingTop="4dp"
            android:textColor="#fff" />

</android.support.v4.view.ViewPager>

这是我们的布局。 现在我们要填写天气数据。

HTTP,AsyncTask和json数据解析

下一步是使用HTTP连接和asynctask来检索数据,以避免ANR问题。 有了数据后,我们将使用JSON解析器对其进行解析。 让我们使用以下链接询问我们的浏览器天气预报:

http://api.openweathermap.org/data/2.5/forecast/daily?q=Rome,IT&mode=json&units=metric&cnt=3

其中,cnt是我们要具有天气状况的天数。 结果如下所示:

{
   "cod": "200",
   "message": 0.0192,
   "city": {
      "id": "3169070",
      "name": "Rome",
      "coord": {
         "lon": 12.4958,
         "lat": 41.903
      },
      "country": "Italy",
      "population": 0
   },
   "cnt": 7,
   "list": [
      {
         "dt": 1377774000,
         "temp": {
            "day": 26.83,
            "min": 16.41,
            "max": 29.12,
            "night": 16.41,
            "eve": 24.81,
            "morn": 26.83
         },
         "pressure": 1007.2,
         "humidity": 72,
         "weather": [
            {
               "id": 800,
               "main": "Clear",
               "description": "sky is clear",
               "icon": "01d"
            }
         ],
         "speed": 0.71,
         "deg": 146,
         "clouds": 0
      },
      {
         "dt": 1377860400,
         "temp": {
            "day": 29.84,
            "min": 16.8,
            "max": 29.84,
            "night": 16.8,
            "eve": 24.81,
            "morn": 17.93
         },
         "pressure": 1006.68,
         "humidity": 50,
         "weather": [
            {
               "id": 800,
               "main": "Clear",
               "description": "sky is clear",
               "icon": "02d"
            }
         ],
         "speed": 2.2,
         "deg": 235,
         "clouds": 8
      },
      {
         "dt": 1377946800,
         "temp": {
            "day": 29.14,
            "min": 14.11,
            "max": 29.14,
            "night": 14.11,
            "eve": 24.08,
            "morn": 18.32
         },
         "pressure": 1005.17,
         "humidity": 45,
         "weather": [
            {
               "id": 801,
               "main": "Clouds",
               "description": "few clouds",
               "icon": "02d"
            }
         ],
         "speed": 1.56,
         "deg": 320,
         "clouds": 20
      },
      {
         "dt": 1378033200,
         "temp": {
            "day": 28.43,
            "min": 12.11,
            "max": 28.95,
            "night": 14.28,
            "eve": 23.89,
            "morn": 12.11
         },
         "pressure": 1005.23,
         "humidity": 39,
         "weather": [
            {
               "id": 800,
               "main": "Clear",
               "description": "sky is clear",
               "icon": "01d"
            }
         ],
         "speed": 1.55,
         "deg": 289,
         "clouds": 0
      },
      {
         "dt": 1378119600,
         "temp": {
            "day": 29.83,
            "min": 16.02,
            "max": 29.83,
            "night": 18.86,
            "eve": 25.35,
            "morn": 16.02
         },
         "pressure": 1006.57,
         "humidity": 32,
         "weather": [
            {
               "id": 800,
               "main": "Clear",
               "description": "sky is clear",
               "icon": "01d"
            }
         ],
         "speed": 3.3,
         "deg": 292,
         "clouds": 0
      },
      {
         "dt": 1378206000,
         "temp": {
            "day": 27.76,
            "min": 19.68,
            "max": 27.76,
            "night": 19.68,
            "eve": 25,
            "morn": 20.25
         },
         "pressure": 1014.89,
         "humidity": 0,
         "weather": [
            {
               "id": 800,
               "main": "Clear",
               "description": "sky is clear",
               "icon": "01d"
            }
         ],
         "speed": 4.05,
         "deg": 298,
         "clouds": 0
      },
      {
         "dt": 1378292400,
         "temp": {
            "day": 27.85,
            "min": 19.91,
            "max": 27.85,
            "night": 19.91,
            "eve": 24.78,
            "morn": 20.13
         },
         "pressure": 1017.2,
         "humidity": 0,
         "weather": [
            {
               "id": 800,
               "main": "Clear",
               "description": "sky is clear",
               "icon": "01d"
            }
         ],
         "speed": 1.91,
         "deg": 252,
         "clouds": 0
      }
   ]
}

分析结果,我们发现我们正在寻找的信息在list标记内,这是一个数组。 为了保存此信息,我们可以在两个保存每日预测的类上创建另一个,保存另一个每日预测类:

public class DayForecast {

    private static SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
    public Weather weather = new Weather();
    public ForecastTemp forecastTemp = new ForecastTemp();
    public long timestamp;

    public class ForecastTemp {
        public float day;
        public float min;
        public float max;
        public float night;
        public float eve;
        public float morning;
    }

    public String getStringDate() {
        return sdf.format(new Date(timestamp));
    }
}

另一个:

public class WeatherForecast {

    private List<DayForecast> daysForecast = new ArrayList<DayForecast>();

    public void addForecast(DayForecast forecast) {
        daysForecast.add(forecast);
        System.out.println("Add forecast ["+forecast+"]");
    }

    public DayForecast getForecast(int dayNum) {
        return daysForecast.get(dayNum);
    }
}

现在我们有了数据模型,并且使用简单的类(如上一篇文章(JSONWeatherParser)中使用的类)简单地解析了JSON数据。

public static WeatherForecast getForecastWeather(String data) throws JSONException  {

    WeatherForecast forecast = new WeatherForecast();

    // We create out JSONObject from the data
    JSONObject jObj = new JSONObject(data);

    JSONArray jArr = jObj.getJSONArray("list"); // Here we have the forecast for every day

    // We traverse all the array and parse the data
    for (int i=0; i < jArr.length(); i++) {
        JSONObject jDayForecast = jArr.getJSONObject(i);

        // Now we have the json object so we can extract the data
        DayForecast df = new DayForecast();

        // We retrieve the timestamp (dt)
        df.timestamp = jDayForecast.getLong("dt");

        // Temp is an object
        JSONObject jTempObj = jDayForecast.getJSONObject("temp");

        df.forecastTemp.day = (float) jTempObj.getDouble("day");
        df.forecastTemp.min = (float) jTempObj.getDouble("min");
        df.forecastTemp.max = (float) jTempObj.getDouble("max");
        df.forecastTemp.night = (float) jTempObj.getDouble("night");
        df.forecastTemp.eve = (float) jTempObj.getDouble("eve");
        df.forecastTemp.morning = (float) jTempObj.getDouble("morn");

        // Pressure & Humidity
        df.weather.currentCondition.setPressure((float) jDayForecast.getDouble("pressure"));
        df.weather.currentCondition.setHumidity((float) jDayForecast.getDouble("humidity"));

        // ...and now the weather
        JSONArray jWeatherArr = jDayForecast.getJSONArray("weather");
        JSONObject jWeatherObj = jWeatherArr.getJSONObject(0);
        df.weather.currentCondition.setWeatherId(getInt("id", jWeatherObj));
        df.weather.currentCondition.setDescr(getString("description", jWeatherObj));
        df.weather.currentCondition.setCondition(getString("main", jWeatherObj));
        df.weather.currentCondition.setIcon(getString("icon", jWeatherObj));

        forecast.addForecast(df);
    }

    return forecast;
}

做得好! 我们还需要什么呢?……我们必须处理ViewPager并创建适配器来保存每天的天气预报。

ViewPager,片段和适配器

首先,我们必须创建我们的适配器,以处理显示每日天气详细信息的每个片段。 在这种情况下,要创建我们的适配器,我们必须扩展FragmentPagerAdapter:

public class DailyForecastPageAdapter extends FragmentPagerAdapter {

private int numDays;
private FragmentManager fm;
private WeatherForecast forecast;
private final static SimpleDateFormat sdf = new SimpleDateFormat("E, dd-MM");

public DailyForecastPageAdapter(int numDays, FragmentManager fm, WeatherForecast forecast) {
    super(fm);
    this.numDays = numDays;
    this.fm = fm;
    this.forecast = forecast;    
}

// Page title
@Override
public CharSequence getPageTitle(int position) {
    // We calculate the next days adding position to the current date
    Date d = new Date();
    Calendar gc =  new GregorianCalendar();
    gc.setTime(d);
    gc.add(GregorianCalendar.DAY_OF_MONTH, position);

    return sdf.format(gc.getTime());    
}

@Override
public Fragment getItem(int num) {
    DayForecast dayForecast = (DayForecast) forecast.getForecast(num);
    DayForecastFragment f = new DayForecastFragment();
    f.setForecast(dayForecast);
    return f;
}

/* 
 * Number of the days we have the forecast
 */
@Override
public int getCount() {

    return numDays;
}

两种方法很重要:一种“创建”片段,另一种“创建”页面标题。 第一个实例化一个片段,该片段显示通过dayForecast数据传递的每日预测,另一个则使用GregorianCalendar创建页面图块。

最后一步是对片段进行编码:

public class DayForecastFragment extends Fragment {

...

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.dayforecast_fragment, container, false);

        TextView tempView = (TextView) v.findViewById(R.id.tempForecast);
        TextView descView = (TextView) v.findViewById(R.id.skydescForecast);
        tempView.setText( (int) (dayForecast.forecastTemp.min - 275.15) + "-" + (int) (dayForecast.forecastTemp.max - 275.15) );
        descView.setText(dayForecast.weather.currentCondition.getDescr());
        iconWeather = (ImageView) v.findViewById(R.id.forCondIcon);
        // Now we retrieve the weather icon
        JSONIconWeatherTask task = new JSONIconWeatherTask();
        task.execute(new String[]{dayForecast.weather.currentCondition.getIcon()});

        return v;
    }
...
}

在onCreateView中,我们增加布局并使用(AsyncTask)检索天气图标。

源代码可用@ github

参考: Android应用程序开发:天气应用程序,由我们的JCG合作伙伴 Francesco Azzola在Surviving w / Android博客上进行了预测

翻译自: https://www.javacodegeeks.com/2013/09/android-app-developmentweather-app-with-forecast.html

android天气预报开发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值