Ствараем дадатак "прагноз надвор'я" на Android
Belarusian (беларуская мова) translation by Alex Grigorovich (you can also view the original English article)



Многія папулярныя дадатки прагнозу надвор'я ў Google Play альбо ўтрымліваюць шмат рэкламы, альбо патрабуюць занадта вялікай колькасці дазволаў, альбо ўтрымліваюць функцыянал, які большасць з нас ніколі не выкарыстоўваюць. Было б выдатна, калі б мы маглі стварыць ўласнае прыкладанне надвор'я з нуля?
У гэтым уроку я пакажу вам, як гэта зрабіць. Наш дадатак будзе мець просты і мінімалістычны карыстацкі інтэрфейс, які паказвае карыстачу менавіта тое, што яму трэба ведаць аб бягучых умовах надвор'я. Давайце пачнем.
1. Падрыхтоўка
Перш чым працягваць, двойчы праверце, што ў вас ўстаноўлены наступныя кампаненты:
- Eclipse ADT Bundle: вы можаце спампаваць яго на вэб-сайце распрацоўніка Android.
- Ключ API OpenWeatherMap: гэта не абавязкова для выканання нашай задачы, але гэта бясплатна. Вы можаце атрымаць яго, зарэгістраваўшыся на сайце OpenWeatherMap.
- Значки: Я рэкамендую вам спампаваць шрыфт weather icons font, створаны Эрыкам Флорсом. Вам
нужно загрузить файл TTF, потому что мы будем использовать его в нативном
приложении. Мы
будем использовать этот шрифт чтобы показывать различные значки в зависимости
от погодных условий.
2. Створым новы праект
Я збіраюся назваць гэта дадатак SimpleWeather, але вы можаце даць яму любое імя, якое вам спадабаецца. Калі ласка, увядзіце унікальнае імя пакета, ўсталюйце мінімальны неабходны SDK на Android 2.2 і ўсталюйце мэтавай SDK на Android 4.4. Вы можаце пакінуць тэму Holo Dark.



Гэта дадатак будзе мець толькі адно Activity
, і яно будзе заснавана на шаблоне Blank Activity, як паказана ніжэй.



Назавіце актыўнасць
WeatherActivity. Мы будзем выкарыстоўваць Fragment
ўнутры гэтага Activity
. Макет, звязаны з Activity
называецца activity_weather.xml. Макет, звязаны з Fragment
называецца fragment _weather.xml.



3. Дададзим карыстацкі шрыфт
Скапіруйце weathericons-regular-webfont.ttf ў каталог assets / fonts вашага праекта і пераназавіце яго ў weather.ttf.
4. Адрэдагуем файл маніфесту
Адзіны дазвол, якое патрабуецца гэтаму дадатку - гэта android.permission.INTERNET
.
1 |
<uses-permission android:name="android.permission.INTERNET"/> |
Каб спрасціць гэты ўрок, мы разгледзім толькі партрэтны рэжым. Вузел актыўнасці
маніфесту павінен выглядаць так:
1 |
<activity
|
2 |
android:name="ah.hathi.simpleweather.WeatherActivity" |
3 |
android:label="@string/app_name" |
4 |
android:screenOrientation="portrait" |
5 |
>
|
6 |
<intent-filter>
|
7 |
<action android:name="android.intent.action.MAIN" /> |
8 |
<category android:name="android.intent.category.LAUNCHER" /> |
9 |
</intent-filter>
|
10 |
</activity>
|
5. Адрэдагуем макет Activity
У activity_weather.xml змен не так шмат. Ён павінен ужо ўключаць у сябе FrameLayout
. Дадайце дадатковую ўласцівасць, каб змяніць колер фону
на #FF0099CC
.
1 |
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" |
2 |
xmlns:tools="http://schemas.android.com/tools" |
3 |
android:id="@+id/container" |
4 |
android:layout_width="match_parent" |
5 |
android:layout_height="match_parent" |
6 |
tools:context="ah.hathi.simpleweather.WeatherActivity" |
7 |
tools:ignore="MergeRootFrame" |
8 |
android:background="#FF0099CC" /> |
6. Адрэдагуем макет Fragment
Зменіце файл fragment_weather.xml, дадаўшы пяць тэгаў TextView
, каб адлюстраваць наступную інфармацыю:
- горад і краіна
- бягучая тэмпература
- значок, які паказвае бягучае ўмовы надвор'я
- адзнака часу, якая ўказвае карыстальніку, калі было атрымана апошняе абнаўленне інфармацыя пра надвор'е
- больш падрабязная інфармацыя аб бягучай надвор'і, напрыклад, апісанне і вільготнасць
Выкарыстоўвайце RelativeLayout
для размяшчэння тэкставых уяўленняў. Вы можаце наладзіць textSize
для розных прылад.
1 |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
2 |
xmlns:tools="http://schemas.android.com/tools" |
3 |
android:layout_width="match_parent" |
4 |
android:layout_height="match_parent" |
5 |
android:paddingBottom="@dimen/activity_vertical_margin" |
6 |
android:paddingLeft="@dimen/activity_horizontal_margin" |
7 |
android:paddingRight="@dimen/activity_horizontal_margin" |
8 |
android:paddingTop="@dimen/activity_vertical_margin" |
9 |
tools:context="ah.hathi.simpleweather.WeatherActivity$PlaceholderFragment" > |
10 |
|
11 |
<TextView
|
12 |
android:id="@+id/city_field" |
13 |
android:layout_width="wrap_content" |
14 |
android:layout_height="wrap_content" |
15 |
android:layout_alignParentTop="true" |
16 |
android:layout_centerHorizontal="true" |
17 |
android:textAppearance="?android:attr/textAppearanceLarge" /> |
18 |
|
19 |
<TextView
|
20 |
android:id="@+id/updated_field" |
21 |
android:layout_width="wrap_content" |
22 |
android:layout_height="wrap_content" |
23 |
android:layout_below="@+id/city_field" |
24 |
android:layout_centerHorizontal="true" |
25 |
android:textAppearance="?android:attr/textAppearanceMedium" |
26 |
android:textSize="13sp" /> |
27 |
|
28 |
<TextView
|
29 |
android:id="@+id/weather_icon" |
30 |
android:layout_width="wrap_content" |
31 |
android:layout_height="wrap_content" |
32 |
android:layout_centerVertical="true" |
33 |
android:layout_centerHorizontal="true" |
34 |
android:textAppearance="?android:attr/textAppearanceLarge" |
35 |
android:textSize="70sp" |
36 |
/>
|
37 |
|
38 |
<TextView
|
39 |
android:id="@+id/current_temperature_field" |
40 |
android:layout_width="wrap_content" |
41 |
android:layout_height="wrap_content" |
42 |
android:layout_alignParentBottom="true" |
43 |
android:layout_centerHorizontal="true" |
44 |
android:textAppearance="?android:attr/textAppearanceLarge" |
45 |
android:textSize="40sp" /> |
46 |
|
47 |
<TextView
|
48 |
android:id="@+id/details_field" |
49 |
android:layout_width="wrap_content" |
50 |
android:layout_height="wrap_content" |
51 |
android:layout_below="@+id/weather_icon" |
52 |
android:layout_centerHorizontal="true" |
53 |
android:textAppearance="?android:attr/textAppearanceMedium" |
54 |
/>
|
55 |
|
56 |
</RelativeLayout>
|
7. Зменім strings.xml
Гэты файл утрымлівае радкі, якія выкарыстоўваюцца ў нашым дадатку, а таксама коды сімвалаў Юнікода, якія мы будзем выкарыстоўваць для адлюстравання значкоў надвор'я. Дазваляе прыкладанням адлюстроўваць восем розных тыпаў умоў надвор'я. Калі вам трэба больш, ўжыеце наступную хітрасць. Дадайце наступныя значэнні ў файл values/strings.xml:
1 |
<?xml version="1.0" encoding="utf-8"?>
|
2 |
<resources>
|
3 |
|
4 |
<string name="app_name">Simple Weather</string> |
5 |
<string name="change_city">Change city</string> |
6 |
|
7 |
<!-- Put your own APP ID here -->
|
8 |
<string name="open_weather_maps_app_id">11111</string> |
9 |
|
10 |
<string name="weather_sunny"></string> |
11 |
<string name="weather_clear_night"></string> |
12 |
|
13 |
<string name="weather_foggy"></string> |
14 |
<string name="weather_cloudy"></string> |
15 |
<string name="weather_rainy"></string> |
16 |
<string name="weather_snowy"></string> |
17 |
<string name="weather_thunder"></string> |
18 |
<string name="weather_drizzle"></string> |
19 |
|
20 |
<string name="place_not_found">Sorry, no weather data found.</string> |
21 |
|
22 |
</resources>
|
8. Дадзим пункт меню
Карыстальнік павінен мець магчымасць выбіраць горад, чыю надвор'е яны хочуць бачыць. Змяніце файл menu/weather.xml і дадайце элемент для гэтай опцыі.
1 |
<menu xmlns:android="http://schemas.android.com/apk/res/android" |
2 |
xmlns:app="http://schemas.android.com/apk/res-auto" |
3 |
xmlns:tools="http://schemas.android.com/tools" |
4 |
tools:context="ah.hathi.simpleweather.WeatherActivity" > |
5 |
|
6 |
<item
|
7 |
android:id="@+id/change_city" |
8 |
android:orderInCategory="1" |
9 |
android:title="@string/change_city" |
10 |
app:showAsAction="never"/> |
11 |
|
12 |
</menu>
|
Цяпер, калі ўсе XML-файлы гатовыя да выкарыстання, давайце пяройдзем да запыту на API OpenWeatherMap для атрымання дадзеных аб надвор'і.
9. Атрымліваем дадзеныя з OpenWeatherMap
Мы можам атрымаць бягучыя дадзеныя аб надвор'і ў любым горадзе, у фармаце JSON, з дапамогай API OpenWeatherMap. У радку запыту мы перадаем імя горада і сістэму вымярэння, у якой павінны быць вынікі.
Напрыклад, каб атрымаць бягучую інфармацыю пра надвор'е ў Канберре, выкарыстоўваючы метрычную сістэму, мы адпраўляем запыт на http://api.openweathermap.org/data/2.5/weather?q=Canberra&units=metric
Адказ, які мы атрымліваем праз API, выглядае так:
1 |
{
|
2 |
"base": "cmc stations", |
3 |
"clouds": { |
4 |
"all": 90 |
5 |
},
|
6 |
"cod": 200, |
7 |
"coord": { |
8 |
"lat": -35.28, |
9 |
"lon": 149.13 |
10 |
},
|
11 |
"dt": 1404390600, |
12 |
"id": 2172517, |
13 |
"main": { |
14 |
"humidity": 100, |
15 |
"pressure": 1023, |
16 |
"temp": -1, |
17 |
"temp_max": -1, |
18 |
"temp_min": -1 |
19 |
},
|
20 |
"name": "Canberra", |
21 |
"sys": { |
22 |
"country": "AU", |
23 |
"message": 0.313, |
24 |
"sunrise": 1404335563, |
25 |
"sunset": 1404370965 |
26 |
},
|
27 |
"weather": [ |
28 |
{
|
29 |
"description": "overcast clouds", |
30 |
"icon": "04n", |
31 |
"id": 804, |
32 |
"main": "Clouds" |
33 |
}
|
34 |
],
|
35 |
"wind": { |
36 |
"deg": 305.004, |
37 |
"speed": 1.07 |
38 |
}
|
39 |
}
|
Стварыце новы клас Java і назавіце яго RemoteFetch.java. Гэты клас адказвае за атрыманне дадзеных аб надвор'і праз API OpenWeatherMap.
Мы выкарыстоўваем клас HttpURLConnection
для выканання аддаленага запыту. API OpenWeatherMap чакае ключ API ў HTTP-загалоўку з імем x-api-key
. Гэта вызначана ў нашым запыце з выкарыстаннем метаду setRequestProperty
.
Мы выкарыстоўваем BufferedReader
для чытання адказу API ў StringBuffer
. Калі мы атрымаем поўны адказ, мы преобразуем яго ў аб'ект JSONObject
.
Як відаць з прыведзенага вышэй адказу, дадзеныя JSON ўтрымліваюць поле з імем cod
. Яго значэнне роўна 200
, калі запыт быў паспяховым. Мы выкарыстоўваем гэта значэнне, каб праверыць, ці мае адказ JSON бягучую інфармацыю пра надвор'е ці не.
Клас RemoteFetch.java павінен выглядаць наступным чынам:
1 |
package ah.hathi.simpleweather; |
2 |
|
3 |
import java.io.BufferedReader; |
4 |
import java.io.InputStreamReader; |
5 |
import java.net.HttpURLConnection; |
6 |
import java.net.URL; |
7 |
|
8 |
import org.json.JSONObject; |
9 |
|
10 |
import android.content.Context; |
11 |
import android.util.Log; |
12 |
|
13 |
public class RemoteFetch { |
14 |
|
15 |
private static final String OPEN_WEATHER_MAP_API = |
16 |
"http://api.openweathermap.org/data/2.5/weather?q=%s&units=metric"; |
17 |
|
18 |
public static JSONObject getJSON(Context context, String city){ |
19 |
try { |
20 |
URL url = new URL(String.format(OPEN_WEATHER_MAP_API, city)); |
21 |
HttpURLConnection connection = |
22 |
(HttpURLConnection)url.openConnection(); |
23 |
|
24 |
connection.addRequestProperty("x-api-key", |
25 |
context.getString(R.string.open_weather_maps_app_id)); |
26 |
|
27 |
BufferedReader reader = new BufferedReader( |
28 |
new InputStreamReader(connection.getInputStream())); |
29 |
|
30 |
StringBuffer json = new StringBuffer(1024); |
31 |
String tmp=""; |
32 |
while((tmp=reader.readLine())!=null) |
33 |
json.append(tmp).append("\n"); |
34 |
reader.close(); |
35 |
|
36 |
JSONObject data = new JSONObject(json.toString()); |
37 |
|
38 |
// This value will be 404 if the request was not
|
39 |
// successful
|
40 |
if(data.getInt("cod") != 200){ |
41 |
return null; |
42 |
}
|
43 |
|
44 |
return data; |
45 |
}catch(Exception e){ |
46 |
return null; |
47 |
}
|
48 |
}
|
49 |
}
|
10. Захаваем горад у настройках
Пользователь не павінен паказваць імя горада кожны раз, калі захоча выкарыстаць прыкладанне. Дадатак павінен запомніць апошні горад, які шукаў карыстальнік. Мы робім гэта, выкарыстоўваючы SharedPreferences
. Аднак замест прамога доступу да гэтых налад з нашага класа Activity
, для гэтага лепш стварыць асобны класс.
Стварыце новы клас Java і назавіце яго CityPreference.java. Каб захаваць і атрымаць імя горада, стварыце два метаду setCity
і getCity
. Аб'ект SharedPreferences
ініцыялізуецца у канструктару. Клас CityPreference.java павінен выглядаць наступным чынам:
1 |
package ah.hathi.simpleweather; |
2 |
|
3 |
import android.app.Activity; |
4 |
import android.content.SharedPreferences; |
5 |
|
6 |
public class CityPreference { |
7 |
|
8 |
SharedPreferences prefs; |
9 |
|
10 |
public CityPreference(Activity activity){ |
11 |
prefs = activity.getPreferences(Activity.MODE_PRIVATE); |
12 |
}
|
13 |
|
14 |
// If the user has not chosen a city yet, return
|
15 |
// Sydney as the default city
|
16 |
String getCity(){ |
17 |
return prefs.getString("city", "Sydney, AU"); |
18 |
}
|
19 |
|
20 |
void setCity(String city){ |
21 |
prefs.edit().putString("city", city).commit(); |
22 |
}
|
23 |
|
24 |
}
|
11. Створым Fragment
Стварыце новы клас Java і назавіце яго WeatherFragment.java. У гэтым фрагменце ў якасці макета выкарыстоўваецца fragment_weather.xml. Абвясьцеце пяць аб'ектаў TextView
і ініцыялізуецца іх у метадзе onCreateView
. Абвясьцеце новы аб'ект Typeface
з імем weatherFont
. Аб'ект TypeFace
паказвае на вэб-шрыфт, які вы загрузілі і захавалі ў тэчцы assets/fonts.
Мы будзем выкарыстоўваць асобны паток
для асінхроннага атрымання дадзеных праз API OpenWeatherMap. Мы не можам абнавіць карыстацкі інтэрфейс з падобнага фонавага патоку. Таму нам патрэбны аб'ект Handler
, які мы ініцыялізуюем у канструктару класа WeatherFragment
.
1 |
public class WeatherFragment extends Fragment { |
2 |
Typeface weatherFont; |
3 |
|
4 |
TextView cityField; |
5 |
TextView updatedField; |
6 |
TextView detailsField; |
7 |
TextView currentTemperatureField; |
8 |
TextView weatherIcon; |
9 |
|
10 |
Handler handler; |
11 |
|
12 |
public WeatherFragment(){ |
13 |
handler = new Handler(); |
14 |
}
|
15 |
|
16 |
@Override
|
17 |
public View onCreateView(LayoutInflater inflater, ViewGroup container, |
18 |
Bundle savedInstanceState) { |
19 |
View rootView = inflater.inflate(R.layout.fragment_weather, container, false); |
20 |
cityField = (TextView)rootView.findViewById(R.id.city_field); |
21 |
updatedField = (TextView)rootView.findViewById(R.id.updated_field); |
22 |
detailsField = (TextView)rootView.findViewById(R.id.details_field); |
23 |
currentTemperatureField = (TextView)rootView.findViewById(R.id.current_temperature_field); |
24 |
weatherIcon = (TextView)rootView.findViewById(R.id.weather_icon); |
25 |
|
26 |
weatherIcon.setTypeface(weatherFont); |
27 |
return rootView; |
28 |
}
|
29 |
}
|
Ініцыялізуюем аб'ект weatherFont
, выклікаючы createFromAsset
у класе Typeface
. Мы таксама выклікаем метад updateWeatherData
ў onCreate
.
1 |
@Override
|
2 |
public void onCreate(Bundle savedInstanceState) { |
3 |
super.onCreate(savedInstanceState); |
4 |
weatherFont = Typeface.createFromAsset(getActivity().getAssets(), "fonts/weather.ttf"); |
5 |
updateWeatherData(new CityPreference(getActivity()).getCity()); |
6 |
}
|
У updateWeatherData
, мы запускаем новы паток і выклікаем getJSON
у класе RemoteFetch
. Калі значэнне, якое вяртаецца getJSON
, роўна null
, мы выводзім паведамленне пра памылку карыстальніку. Калі гэта не так, мы выклікаем метад renderWeather
.
Толькі асноўны паток
дазваляе абнаўляць карыстацкі інтэрфейс прыкладання для Android. Выклік Toast
або renderWeather
прама з фонавага патоку прывядзе да памылкі выканання. Вось чаму мы выклікаем гэтыя метады з выкарыстаннем метаду post
-апрацоўшчыка
.
1 |
private void updateWeatherData(final String city){ |
2 |
new Thread(){ |
3 |
public void run(){ |
4 |
final JSONObject json = RemoteFetch.getJSON(getActivity(), city); |
5 |
if(json == null){ |
6 |
handler.post(new Runnable(){ |
7 |
public void run(){ |
8 |
Toast.makeText(getActivity(), |
9 |
getActivity().getString(R.string.place_not_found), |
10 |
Toast.LENGTH_LONG).show(); |
11 |
}
|
12 |
});
|
13 |
} else { |
14 |
handler.post(new Runnable(){ |
15 |
public void run(){ |
16 |
renderWeather(json); |
17 |
}
|
18 |
});
|
19 |
}
|
20 |
}
|
21 |
}.start(); |
22 |
}
|
Метад renderWeather
выкарыстоўвае дадзеныя JSON для абнаўлення аб'ектаў TextView
. Пагодны
вузел адказу JSON ўяўляе сабой масіў дадзеных. У гэтым уроку мы будзем выкарыстоўваць толькі першы элемент масіва метэаралагічных дадзеных.
1 |
private void renderWeather(JSONObject json){ |
2 |
try { |
3 |
cityField.setText(json.getString("name").toUpperCase(Locale.US) + |
4 |
", " + |
5 |
json.getJSONObject("sys").getString("country")); |
6 |
|
7 |
JSONObject details = json.getJSONArray("weather").getJSONObject(0); |
8 |
JSONObject main = json.getJSONObject("main"); |
9 |
detailsField.setText( |
10 |
details.getString("description").toUpperCase(Locale.US) + |
11 |
"\n" + "Humidity: " + main.getString("humidity") + "%" + |
12 |
"\n" + "Pressure: " + main.getString("pressure") + " hPa"); |
13 |
|
14 |
currentTemperatureField.setText( |
15 |
String.format("%.2f", main.getDouble("temp"))+ " ℃"); |
16 |
|
17 |
DateFormat df = DateFormat.getDateTimeInstance(); |
18 |
String updatedOn = df.format(new Date(json.getLong("dt")*1000)); |
19 |
updatedField.setText("Last update: " + updatedOn); |
20 |
|
21 |
setWeatherIcon(details.getInt("id"), |
22 |
json.getJSONObject("sys").getLong("sunrise") * 1000, |
23 |
json.getJSONObject("sys").getLong("sunset") * 1000); |
24 |
|
25 |
}catch(Exception e){ |
26 |
Log.e("SimpleWeather", "One or more fields not found in the JSON data"); |
27 |
}
|
28 |
}
|
У канцы метаду renderWeather
мы выклікаем setWeatherIcon
з ідэнтыфікатарам
бягучага надвор'я, а таксама часам усходу і заходу сонца. Настройка значка надвор'я трохі складаная, таму што API OpenWeatherMap падтрымлівае больш умоў надвор'я, чым мы можам адлюстраваць з дапамогай выкарыстоўванага вэб-шрыфта. На шчасце, ідэнтыфікатары надвор'я вынікаюць шаблону, пра які вы можаце даведацца больш на вэб-сайце OpenWeatherMap.
Так мы будзем супастаўляць ідэнтыфікатар надвор'я з абразком:
- коды надвор'я ў дыяпазоне 200 пазначаюць навальніцу, што азначае, што мы можам выкарыстоўваць
R .string.weather_thunder
для іх - коды надвор'я ў дыяпазоне 300 звязаныя з морасю, і мы выкарыстоўваем
R.string.weather_drizzle
- коды надвор'я у дыяпазоне 500 азначаюць дождж, і мы выкарыстоўваем
R.string.weather_rain
- і гэтак далей ...
Мы выкарыстоўваем час усходу і заходу сонца, каб адлюстраваць сонца або месяц, у залежнасці ад бягучага часу сутак і толькі ў тым выпадку, калі надвор'е ясная.
1 |
private void setWeatherIcon(int actualId, long sunrise, long sunset){ |
2 |
int id = actualId / 100; |
3 |
String icon = ""; |
4 |
if(actualId == 800){ |
5 |
long currentTime = new Date().getTime(); |
6 |
if(currentTime>=sunrise && currentTime<sunset) { |
7 |
icon = getActivity().getString(R.string.weather_sunny); |
8 |
} else { |
9 |
icon = getActivity().getString(R.string.weather_clear_night); |
10 |
}
|
11 |
} else { |
12 |
switch(id) { |
13 |
case 2 : icon = getActivity().getString(R.string.weather_thunder); |
14 |
break; |
15 |
case 3 : icon = getActivity().getString(R.string.weather_drizzle); |
16 |
break; |
17 |
case 7 : icon = getActivity().getString(R.string.weather_foggy); |
18 |
break; |
19 |
case 8 : icon = getActivity().getString(R.string.weather_cloudy); |
20 |
break; |
21 |
case 6 : icon = getActivity().getString(R.string.weather_snowy); |
22 |
break; |
23 |
case 5 : icon = getActivity().getString(R.string.weather_rainy); |
24 |
break; |
25 |
}
|
26 |
}
|
27 |
weatherIcon.setText(icon); |
28 |
}
|
Вядома, вы можаце апрацоўваць больш умоў
надвор'я, адпаведна змяняючы
метад setWeatherIcon
.
Нарэшце, дадамо метад changeCity
да фрагмента, каб карыстальнік мог абнавіць бягучы горад. Метад changeCity
будзе выклікацца толькі з асноўнага класа Activity
.
1 |
public void changeCity(String city){ |
2 |
updateWeatherData(city); |
3 |
}
|
12. Рэдагуем Activity
В плыні налады праекта, Eclipse запаўняе WeatherActivity.java некаторым шаблонным кодам. Заменіце стандартную рэалізацыю метаду onCreate
на прыведзеную ніжэй, у якой мы выкарыстоўваем WeatherFragment
. Метад onCreate
павінен выглядаць наступным чынам:
1 |
@Override
|
2 |
protected void onCreate(Bundle savedInstanceState) { |
3 |
super.onCreate(savedInstanceState); |
4 |
setContentView(R.layout.activity_weather); |
5 |
|
6 |
if (savedInstanceState == null) { |
7 |
getSupportFragmentManager().beginTransaction() |
8 |
.add(R.id.container, new WeatherFragment()) |
9 |
.commit(); |
10 |
}
|
11 |
}
|
Затым адрэдагуйце метад onOptionsItemSelected
і апрацуйце адзіны параметр меню, які ў нас ёсць. Усё, што вам трэба зрабіць, гэта выклікаць метад showInputDialog
.
У метадзе showInputDialog
мы выкарыстоўваем AlertDialog.Builder
для стварэння аб'екта Dialog
, які прапануе карыстачу ўвесці імя горада. Гэтая інфармацыя перадаецца метаду changeCity
, які захоўвае імя горада з выкарыстаннем класа CityPreference
і выклікае метад changeCity
ў фрагменце
.
1 |
@Override
|
2 |
public boolean onOptionsItemSelected(MenuItem item) { |
3 |
if(item.getItemId() == R.id.change_city){ |
4 |
showInputDialog(); |
5 |
}
|
6 |
return false; |
7 |
}
|
8 |
|
9 |
private void showInputDialog(){ |
10 |
AlertDialog.Builder builder = new AlertDialog.Builder(this); |
11 |
builder.setTitle("Change city"); |
12 |
final EditText input = new EditText(this); |
13 |
input.setInputType(InputType.TYPE_CLASS_TEXT); |
14 |
builder.setView(input); |
15 |
builder.setPositiveButton("Go", new DialogInterface.OnClickListener() { |
16 |
@Override
|
17 |
public void onClick(DialogInterface dialog, int which) { |
18 |
changeCity(input.getText().toString()); |
19 |
}
|
20 |
});
|
21 |
builder.show(); |
22 |
}
|
23 |
|
24 |
public void changeCity(String city){ |
25 |
WeatherFragment wf = (WeatherFragment)getSupportFragmentManager() |
26 |
.findFragmentById(R.id.container); |
27 |
wf.changeCity(city); |
28 |
new CityPreference(this).setCity(city); |
29 |
}
|
Цяпер ваш дадатак для надвор'я гатовы. Збярыце праект і устанвоите яго на Android-прыладзе для тэставання.



Заключение
Зараз у вас ёсць поўнафункцыянальны дадатак прагнозу надвор'я. Вывучайце API OpenWeatherMap для далейшага развіцця вашага дадатку. Вы таксама можаце выкарыстоўваць больш значкоў надвор'я, так як у дадатку мы выкарыстоўваем толькі нешматлікія з іх.