Skip to content
This repository has been archived by the owner on Jun 23, 2022. It is now read-only.

5.03 update forecast adapter #331

Open
wants to merge 2 commits into
base: 5.02_build_today_item
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/build.gradle
Expand Up @@ -17,6 +17,9 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
buildTypes.each {
it.buildConfigField 'String', 'OPEN_WEATHER_MAP_API_KEY', MyOpenWeatherMapApiKey
}
}

dependencies {
Expand Down
Expand Up @@ -278,12 +278,14 @@ protected Void doInBackground(String... params) {
final String FORMAT_PARAM = "mode";
final String UNITS_PARAM = "units";
final String DAYS_PARAM = "cnt";
final String APPID_PARAM = "APPID";

Uri builtUri = Uri.parse(FORECAST_BASE_URL).buildUpon()
.appendQueryParameter(QUERY_PARAM, params[0])
.appendQueryParameter(FORMAT_PARAM, format)
.appendQueryParameter(UNITS_PARAM, units)
.appendQueryParameter(DAYS_PARAM, Integer.toString(numDays))
.appendQueryParameter(APPID_PARAM, BuildConfig.OPEN_WEATHER_MAP_API_KEY)
.build();

URL url = new URL(builtUri.toString());
Expand Down
Expand Up @@ -6,6 +6,8 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

/**
* {@link ForecastAdapter} exposes a list of weather forecasts
Expand All @@ -16,29 +18,6 @@ public ForecastAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
}

/**
* Prepare the weather high/lows for presentation.
*/
private String formatHighLows(double high, double low) {
boolean isMetric = Utility.isMetric(mContext);
String highLowStr = Utility.formatTemperature(high, isMetric) + "/" + Utility.formatTemperature(low, isMetric);
return highLowStr;
}

/*
This is ported from FetchWeatherTask --- but now we go straight from the cursor to the
string.
*/
private String convertCursorRowToUXFormat(Cursor cursor) {
String highAndLow = formatHighLows(
cursor.getDouble(ForecastFragment.COL_WEATHER_MAX_TEMP),
cursor.getDouble(ForecastFragment.COL_WEATHER_MIN_TEMP));

return Utility.formatDate(cursor.getLong(ForecastFragment.COL_WEATHER_DATE)) +
" - " + cursor.getString(ForecastFragment.COL_WEATHER_DESC) +
" - " + highAndLow;
}

/*
Remember that these views are reused as needed.
*/
Expand All @@ -57,7 +36,35 @@ public void bindView(View view, Context context, Cursor cursor) {
// our view is pretty simple here --- just a text view
// we'll keep the UI functional with a simple (and slow!) binding.

//TextView tv = (TextView)view;
//tv.setText(convertCursorRowToUXFormat(cursor));
// Read weather icon ID from cursor
int weatherId = cursor.getInt(ForecastFragment.COL_WEATHER_ID);
// Use placeholder image for now
ImageView iconView = (ImageView) view.findViewById(R.id.list_item_icon);
iconView.setImageResource(R.drawable.ic_launcher);

// Read date from cursor
long dateInMillis = cursor.getLong(ForecastFragment.COL_WEATHER_DATE);
// Find TextView and set formatted date on it
TextView dateView = (TextView) view.findViewById(R.id.list_item_date_textview);
dateView.setText(Utility.getFriendlyDayString(context, dateInMillis));

// Read weather forecast from cursor
String description = cursor.getString(ForecastFragment.COL_WEATHER_DESC);
// Find TextView and set weather forecast on it
TextView descriptionView = (TextView) view.findViewById(R.id.list_item_forecast_textview);
descriptionView.setText(description);

// Read user preference for metric or imperial temperature units
boolean isMetric = Utility.isMetric(context);

// Read high temperature from cursor
double high = cursor.getDouble(ForecastFragment.COL_WEATHER_MAX_TEMP);
TextView highView = (TextView) view.findViewById(R.id.list_item_high_textview);
highView.setText(Utility.formatTemperature(high, isMetric));

// Read low temperature from cursor
double low = cursor.getDouble(ForecastFragment.COL_WEATHER_MIN_TEMP);
TextView lowView = (TextView) view.findViewById(R.id.list_item_low_textview);
lowView.setText(Utility.formatTemperature(low, isMetric));
}
}
96 changes: 94 additions & 2 deletions app/src/main/java/com/example/android/sunshine/app/Utility.java
Expand Up @@ -18,8 +18,10 @@
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.text.format.Time;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Utility {
Expand All @@ -46,8 +48,98 @@ static String formatTemperature(double temperature, boolean isMetric) {
return String.format("%.0f", temp);
}

static String formatDate(long dateInMillis) {
Date date = new Date(dateInMillis);
static String formatDate(long dateInMilliseconds) {
Date date = new Date(dateInMilliseconds);
return DateFormat.getDateInstance().format(date);
}

// Format used for storing dates in the database. ALso used for converting those strings
// back into date objects for comparison/processing.
public static final String DATE_FORMAT = "yyyyMMdd";

/**
* Helper method to convert the database representation of the date into something to display
* to users. As classy and polished a user experience as "20140102" is, we can do better.
*
* @param context Context to use for resource localization
* @param dateInMillis The date in milliseconds
* @return a user-friendly representation of the date.
*/
public static String getFriendlyDayString(Context context, long dateInMillis) {
// The day string for forecast uses the following logic:
// For today: "Today, June 8"
// For tomorrow: "Tomorrow"
// For the next 5 days: "Wednesday" (just the day name)
// For all days after that: "Mon Jun 8"

Time time = new Time();
time.setToNow();
long currentTime = System.currentTimeMillis();
int julianDay = Time.getJulianDay(dateInMillis, time.gmtoff);
int currentJulianDay = Time.getJulianDay(currentTime, time.gmtoff);

// If the date we're building the String for is today's date, the format
// is "Today, June 24"
if (julianDay == currentJulianDay) {
String today = context.getString(R.string.today);
int formatId = R.string.format_full_friendly_date;
return String.format(context.getString(
formatId,
today,
getFormattedMonthDay(context, dateInMillis)));
} else if ( julianDay < currentJulianDay + 7 ) {
// If the input date is less than a week in the future, just return the day name.
return getDayName(context, dateInMillis);
} else {
// Otherwise, use the form "Mon Jun 3"
SimpleDateFormat shortenedDateFormat = new SimpleDateFormat("EEE MMM dd");
return shortenedDateFormat.format(dateInMillis);
}
}

/**
* Given a day, returns just the name to use for that day.
* E.g "today", "tomorrow", "wednesday".
*
* @param context Context to use for resource localization
* @param dateInMillis The date in milliseconds
* @return
*/
public static String getDayName(Context context, long dateInMillis) {
// If the date is today, return the localized version of "Today" instead of the actual
// day name.

Time t = new Time();
t.setToNow();
int julianDay = Time.getJulianDay(dateInMillis, t.gmtoff);
int currentJulianDay = Time.getJulianDay(System.currentTimeMillis(), t.gmtoff);
if (julianDay == currentJulianDay) {
return context.getString(R.string.today);
} else if ( julianDay == currentJulianDay +1 ) {
return context.getString(R.string.tomorrow);
} else {
Time time = new Time();
time.setToNow();
// Otherwise, the format is just the day of the week (e.g "Wednesday".
SimpleDateFormat dayFormat = new SimpleDateFormat("EEEE");
return dayFormat.format(dateInMillis);
}
}

/**
* Converts db date format to the format "Month day", e.g "June 24".
* @param context Context to use for resource localization
* @param dateInMillis The db formatted date string, expected to be of the form specified
* in Utility.DATE_FORMAT
* @return The day in the form of a string formatted "December 6"
*/
public static String getFormattedMonthDay(Context context, long dateInMillis ) {
Time time = new Time();
time.setToNow();
SimpleDateFormat dbDateFormat = new SimpleDateFormat(Utility.DATE_FORMAT);
SimpleDateFormat monthDayFormat = new SimpleDateFormat("MMMM dd");
String monthDayString = monthDayFormat.format(dateInMillis);
return monthDayString;
}

}
15 changes: 5 additions & 10 deletions app/src/main/res/layout/list_item_forecast.xml
Expand Up @@ -12,8 +12,7 @@
<ImageView
android:id="@+id/list_item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"/>
android:layout_height="wrap_content"/>

<LinearLayout
android:layout_height="wrap_content"
Expand All @@ -25,14 +24,12 @@
<TextView
android:id="@+id/list_item_date_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tomorrow"/>
android:layout_height="wrap_content"/>

<TextView
android:id="@+id/list_item_forecast_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clear"/>
android:layout_height="wrap_content"/>

</LinearLayout>

Expand All @@ -44,14 +41,12 @@
<TextView
android:id="@+id/list_item_high_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="81"/>
android:layout_height="wrap_content"/>

<TextView
android:id="@+id/list_item_low_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="68"/>
android:layout_height="wrap_content"/>
</LinearLayout>

</LinearLayout>
14 changes: 12 additions & 2 deletions app/src/main/res/values/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<resources xmlns:xliff="http://schemas.android.com/apk/res-auto">

<!--
Used in Action Bar, and in AndroidManifest to tell the device the name of this app.
Expand Down Expand Up @@ -48,4 +48,14 @@
<!-- Value in SharedPreferences for imperial temperature unit option [CHAR LIMIT=NONE] -->
<string name="pref_units_imperial" translatable="false">imperial</string>

</resources>

<!-- Date label when displaying today's weather forecast [CHAR LIMIT=20] -->
<string name="today">Today</string>

<!-- Date label when displaying tomorrow's weather forecast [CHAR LIMIT=20] -->
<string name="tomorrow">Tomorrow</string>

<!-- Date format for displaying day of week and date (i.e. Mon Jun 1) [CHAR LIMIT=20] -->
<string name="format_full_friendly_date"><xliff:g id="day">%1$s</xliff:g>, <xliff:g id="date">%2$s</xliff:g></string>

</resources>