Android Build a Weather App Hooking Up the Model to the View Plugging in the Data

android:text="@{`At ` + String.valueOf(weather.formattedTime) + ` it will be`}"

Where did the .formattedTime come from ?

All I see is the getFormattedTime(); method...unless I'm missing something

2 Answers

Boban Talevski
Boban Talevski
24,778 Points

Calling weather.formattedTime actually accesses the getFormattedTime() method. That's just the way it works. https://developer.android.com/topic/libraries/data-binding/expressions

public class User {
  public final String firstName;
  public final String lastName;
  public User(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
  }
}
public class User {
  private final String firstName;
  private final String lastName;
  public User(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
  }
  public String getFirstName() {
      return this.firstName;
  }
  public String getLastName() {
      return this.lastName;
  }
}

From the perspective of data binding, these two classes are equivalent. The expression @{user.firstName} used for the android:text attribute accesses the firstName field in the former class and the getFirstName() method in the latter class. Alternatively, it is also resolved to firstName() if that method exists.

Stephen Wall
PRO
Stephen Wall
Pro Student 25,320 Points

In the course though, the getFormattedTime is a method that plays off of a member variable "time", which is represented as a long. The getFormattedTime method is therefore not accessible from the data binding and also caused errors for me going through the course. To get around this, I added a member variable "formattedTime" and in the CurrentWeather constructer added a line to populate it with the getFormattedTime method:

    private String formattedTime;

    public CurrentWeather() { }

    public CurrentWeather(String locationLabel, String icon, String timeZone, long time,
                          double temperature, double humidity, double precipChance, String summary) {
        this.locationLabel = locationLabel;
        this.icon = icon;
        this.timeZone = timeZone;
        this.time = time;
        this.temperature = temperature;
        this.humidity = humidity;
        this.precipChance = precipChance;
        this.summary = summary;
        this.formattedTime = getFormattedTime();  //<<< Right here was the fix for me. 
    }

    public String getFormattedTime() {
        SimpleDateFormat formatter = new SimpleDateFormat("h:mm a");
        formatter.setTimeZone(TimeZone.getTimeZone(timeZone));
        Date date = new Date(time * 1000);
        return formatter.format(date);
    }

Interestingly this still caused an issue with the layout showing my default value for the time while it was loading and would instead show "At null it will be ".... Maybe my version of Android Studio is the culprit.

Steve Hunter
Steve Hunter
Treehouse Moderator 57,652 Points

I'm sure you're not here any more but the getFormattedTime method takes an argument. Without that, I'm surprised it compiles but the null would be caused by the returned string pointing to nothing.

I had the same issue with this error and implemented a similar solution to yours. It worked for me ... Github repo is here