Develop android weather app with Material Design

This post describes how to create an android material weather app using material design guidelines. Google 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 describes how we create an android material 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 the 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.

Android Weather app tutorial

Our material android weather app should have an 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:

material weather app

 

Android material weather app: 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:23.1.0'
  compile 'com.mcxiaoke.volley:library:[email protected]'
  compile 'com.survivingwithandroid:weatherlib:1.6.0'
  compile 'com.survivingwithandroid:weatherlib_volleyclient:1.6.0'
}

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

App layout: Google 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:

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&lt;City&gt; 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:

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. The picture below shows the final result of the android material weather app.

android weather app with material design
how to implement android weather app using materil design
Do you know you can build your weather station? It is easy and in this post named Tweets from Arduino temperature and pressure data you can find all the details to build your personal weather station that can monitor your room temperature and pressure and send information via twitter. Give a look.
android

This is interesting isn’t? But….you can create your weather station using Arduino and learn IoT Arduino Programming. Arduino with sensors can measure the atmospheric temperature and pressure.

Source code is available @github

At the end of this post, you gained the knowledge about how to implement android material weather app with a step by step tutorial. You can customize the app and implement it in the way you like.

  • Sandeep

    where can I get source code of this app ?

  • yiit

    maybe you should add padding to the popup window.

  • Herbert Dai

    What is the advantage of ToolBar? Can we just use a simple LinearLayout instead of it?

  • hey, thanks for your great tutorial. i'm looking forward to check your full source code. is it possible for you to add a example of the
    Flexible toolbar and card toolbar from the material guide line?
    http://www.google.com/design/spec/layout/structure.html#structure-toolbars

    Thanks.

  • survivingwithandroid

    Of course you can use a simple LinearLayout. In this case the Toolbar adds some freedom, because you can add the tile as the City name and the subtitle as the current weather. Anyway you could get the same result using linear layout and adding the menu items to the action bar.

  • Where i can find the apk ready to install as shown in screenshot above

  • Zoubir Bouazza

    A good and clear example. Thanks!

  • Yes but my aim is not to create a production ready app!

  • At the end of the post you can find the link to the source code.

  • lovesh harchandani

    I cloned your github repo and tried to run this MaterialWeather app in android studio and the app crashed with a runtime exception `java.lang.RuntimeException: Unable to start activity ComponentInfo{com.survivingwithandroid.materialweather/com.survivingwithandroid.materialweather.WeatherActivity}: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.`

  • The problem is solved modifying style.xml (v21). In this case you have to extend "Theme.AppCompat.Light.NoActionBar" so you won't have the error anymore. You can create otherwise a base theme and extend it in v21 and in previous version (look here https://plus.google.com/+PareshMayani/posts/bFzkHuVvTPS). In github you can find the correct version.

  • Blasta

    Hi.

    This line is giving me NullPointerException

    toolbar.setTitle(currentCity.getName() + "," + currentCity.getCountry());

  • SkiourosStifado

    Hi! I am newbie to develop…but i try to learn….your examples are very good!
    When we will see a mixed tutorial weather app from your posts or a way to connect these from scratch? Thanks a lot! Keep up the good job! 😀
    (Material Design + Location api + Search City Bar + Forecast) Weather app!

    http://www.survivingwithandroid.com/2014/11/develop-android-weather-app-with-material-design.html
    http://www.survivingwithandroid.com/2013/08/android-app-development-weather-app.html

    http://www.survivingwithandroid.com/2014/04/using-android-location-api-weather-app.html

  • xuelang

    very helpfull ,thanks

  • bro, the images are not showing.

  • I should have fixed it. Thx for your support

  • manuel martinez

    Hi , thanks by the tutorial but contain a error NullPointer:

    "'void com.survivingwithandroid.weather.lib.WeatherClient.searchCity(java.lang.String, com.survivingwithandroid.weather.lib.WeatherClient$CityEventListener)' on a null object reference"

    —> weatherclient.searchCity(pattern, new WeatherClient.CityEventListener()){

  • Vijay Pareek

    i want to create Rows within row. how it can be possible..?
    Please suggest me.
    Thank you.

  • Mpilo Mylo Makae

    Mind replying to: "This line is giving me NullPointerException

    toolbar.setTitle(currentCity.getName() + "," + currentCity.getCountry());" Keep getting the same error…thank you for your tutorial!

  • I guess the currentCity is null. You should check if this is true and investigate why the object is null. Could it be you are looking for a city that doesn't exist? Let me Know and send to me the city you are using.

  • It could be that the current city is null.. have you checked it?

  • Sidbmw

    Hi, according to the images this app looks very good. I downloaded your github zip file and I opened materialweather in android studio. I ran across a few errors here and there, but I was able to fix most of them as it was just a few missing files which android studio installed. After some time all errors were gone so i decided to run the app on the inbuilt android emulator. The app opened, I clicked on the location entering icon (magnifying glass), entered my city and then the app crashed with this message(Unfortunately MaterialWeather has crashed). Can someone please help me and walk me through to get this app running. If someone has completed this app, then can you please share your github file link below.

    Thank you