Android Core

Develop android weather app with Material Design

This post describes how to create a weather app using material design guidelines. Material Design is  a set of rules for visual design, UI interaction, motion and so on. These rules help developer when they design and create an Android app.

This post wants to describe how we create a weather app using Weatherlib as weather layer and Material design rules. We want to develop this app not only for Android 5 Lollipop that supports Material design natively but we want to support previous version of Android like 4.x Kitkat. For that reason we will introduce appCompat v7 library that helps us to implement the Material Design even in the previous Android versions.

We want to code an app that has a extended Toolbar that holds some information about the location and current weather and some basic weather information about temperature, weather icon, humidity, wind and pressure. At the end we will get something like the pic shown below:

android_material_weather_1

Android project set up

The first thing we have to do is configuring our project so that we can use Weatherlib and especially appCompat v7. We can open build.graddle and add these lines:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.+'
    compile 'com.mcxiaoke.volley:library:1.0.6@aar'
    compile 'com.survivingwithandroid:weatherlib:1.5.3'
    compile 'com.survivingwithandroid:weatherlib_volleyclient:1.5.3'
}

Now we have our project correctly set up, we can start defining our app layout.

App layout: Material design

As briefly explained before, we want to use the Toolbar in our case the extended toolbar. a Toolbar is action bar generalization that gives us more control. Differently from Action bar that is tightly bound to an Actvitiy, a Toolbar can be placed everywhere inside the View hierarchy.

So our layout will be divided in three main areas:

  • Toolbar area
  • Weather icon and temperature
  • Other weather data

The layout is shown below:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".WeatherActivity"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/my_toolbar"
        android:layout_height="128dp"
        app:popupTheme="@style/ActionBarPopupThemeOverlay"
        android:layout_width="match_parent"
        android:background="?attr/colorPrimary"
        android:paddingLeft="72dp"
        android:paddingBottom="16dp"
        android:gravity="bottom"
        app:titleTextAppearance="@style/Toolbartitle"
        app:subtitleTextAppearance="@style/ToolbarSubtitle"
        app:theme="@style/ThemeOverlay.AppCompat.Light"
        android:title="@string/location_placeholder"
        />

 ....
</RelativeLayout>

As you can see we used Toolbar. We set the toolbar height equals to 128dp as stated in the guidelines, moreover we used the primary color as background. The primary color is defined in colors.xml. You can refer to material design color guidelines for more information. We should define at least three different color:

  • The primary color, identified by 500
  • The primary dark color identified by 700
  • Accent color that should be for primary action buttons and so on

Our toolbar background color is set to primary color.

<resources>
    <color name="primaryColor_500">#03a9f4</color>
    <color name="primaryDarkColor_700">#0288d1</color>
    ....
</resources>

Moreover the left padding and the bottom padding inside the toolbar are defined according to the guidelines. At the end we add the menu items as we are used to do with action bar. The main result is shown below:

android_material_weather

As you can notice the toolbar has the background equals to the primary color.

Search city: Popup with Material Design

We can use the popup to let the user to enter the location. The popup is very simple, it is made by a EditText that is used to enter the data and a simple ListView that shows the city that match the pattern inserted in the EditText. I will not cover how to search a city in weatherlib because i already covered it. The result is shown here:

The popup layout is very shown below:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
   >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/dialog.city.header"
        style="@style/Theme.AppCompat.Dialog"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8sp"
        android:text="@string/dialog.city.pattern"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:id="@+id/ptnEdit"/>

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/cityList"
        android:clickable="true"/>

</LinearLayout>

The code to create and handle the dialog is shown below:

private Dialog createDialog() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    LayoutInflater inflater = this.getLayoutInflater();
    View v = inflater.inflate(R.layout.select_city_dialog, null);
    builder.setView(v);

    EditText et = (EditText) v.findViewById(R.id.ptnEdit);
    ....
    et.addTextChangedListener(new TextWatcher() {
         ....
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (count > 3) {
                // We start searching
                weatherclient.searchCity(s.toString(), new WeatherClient.CityEventListener() {
                    @Override
                    public void onCityListRetrieved(List<City> cities) {
                        CityAdapter ca = new CityAdapter(WeatherActivity.this, cities);
                        cityListView.setAdapter(ca);

                    }

                });
            }
        }

    });
    builder.setPositiveButton("Accept", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
            // We update toolbar
            toolbar.setTitle(currentCity.getName() + "," + currentCity.getCountry());
            // Start getting weather
            getWeather();
        }
    });

    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
        }
    });

    return builder.create();
}

An important thing to notice it is at line 33, where we set the toolbar title according to the city selected by the user and then we get the current weather. The result of this piece of code is shown here:

android_material_weather_popup

Weatherlib: weather

To get the current weather we use Weatherlib:

private void getWeather() {
    weatherclient.getCurrentCondition(new WeatherRequest(currentCity.getId()),
                         new WeatherClient.WeatherEventListener() {
                             @Override
                             public void onWeatherRetrieved(CurrentWeather currentWeather) {
                                 // We have the current weather now
                                 // Update subtitle toolbar
                                 toolbar.setSubtitle(currentWeather.weather.currentCondition.getDescr());
                                 tempView.setText(String.format("%.0f",currentWeather.weather.temperature.getTemp()));
                                 pressView.setText(String.valueOf(currentWeather.weather.currentCondition.getPressure()));
                                 windView.setText(String.valueOf(currentWeather.weather.wind.getSpeed()));
                                 humView.setText(String.valueOf(currentWeather.weather.currentCondition.getHumidity()));
                                 weatherIcon.setImageResource(WeatherIconMapper.getWeatherResource(currentWeather.weather.currentCondition.getIcon(), currentWeather.weather.currentCondition.getWeatherId()));

                                setToolbarColor(currentWeather.weather.temperature.getTemp());
                             }
     ....
}

You can notice at line 8 we set the toolbar subtitle according to the current weather while at line 15 we change the toolbar color according to the current temperature. As toolbar background color we used the primary colors shown in the guidelines.

android_material_weather_moscow
android_material_weather_miami

android_material_weather_victoria
android_material_weather_russia

  • Source code is available @ github.

Francesco Azzola

He's a senior software engineer with more than 15 yrs old experience in JEE architecture. He's SCEA certified (Sun Certified Enterprise Architect), SCWCD, SCJP. He is an android enthusiast and he has worked for long time in the mobile development field.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
云上太阳zr
云上太阳zr
9 years ago

“Develop android weather app with Material Design” is very good

Back to top button