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

1 Answer

Boban Talevski
Boban Talevski
24,760 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.

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.