From a7e613a59e44d22b3764c55b282be05993c0af6a Mon Sep 17 00:00:00 2001 From: Dan Galpin Date: Sun, 24 May 2015 17:00:55 -0700 Subject: [PATCH] Updated a11y to have more descriptive text and clean up the talkback from the forecast adapter. --- .../android/sunshine/app/DetailFragment.java | 13 ++++++++++-- .../android/sunshine/app/ForecastAdapter.java | 21 +++++++++++-------- app/src/main/res/values/strings.xml | 6 ++++++ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/example/android/sunshine/app/DetailFragment.java b/app/src/main/java/com/example/android/sunshine/app/DetailFragment.java index c298122..04ff14d 100644 --- a/app/src/main/java/com/example/android/sunshine/app/DetailFragment.java +++ b/app/src/main/java/com/example/android/sunshine/app/DetailFragment.java @@ -196,9 +196,13 @@ public class DetailFragment extends Fragment implements LoaderManager.LoaderCall // Get description from weather condition ID String description = Utility.getStringForWeatherCondition(getActivity(), weatherId); mDescriptionView.setText(description); + mDescriptionView.setContentDescription(getString(R.string.a11y_forecast, description)); - // For accessibility, add a content description to the icon field - mIconView.setContentDescription(description); + // For accessibility, add a content description to the icon field. Because the ImageView + // is independently focusable, it's better to have a description of the image. Using + // null is appropriate when the image is purely decorative or when the image already + // has text describing it in the same UI component. + mIconView.setContentDescription(getString(R.string.a11y_forecast_icon, description)); // Read high temperature from cursor and update view boolean isMetric = Utility.isMetric(getActivity()); @@ -206,24 +210,29 @@ public class DetailFragment extends Fragment implements LoaderManager.LoaderCall double high = data.getDouble(COL_WEATHER_MAX_TEMP); String highString = Utility.formatTemperature(getActivity(), high); mHighTempView.setText(highString); + mHighTempView.setContentDescription(getString(R.string.a11y_high_temp, highString)); // Read low temperature from cursor and update view double low = data.getDouble(COL_WEATHER_MIN_TEMP); String lowString = Utility.formatTemperature(getActivity(), low); mLowTempView.setText(lowString); + mLowTempView.setContentDescription(getString(R.string.a11y_low_temp, lowString)); // Read humidity from cursor and update view float humidity = data.getFloat(COL_WEATHER_HUMIDITY); mHumidityView.setText(getActivity().getString(R.string.format_humidity, humidity)); + mHumidityView.setContentDescription(mHumidityView.getText()); // Read wind speed and direction from cursor and update view float windSpeedStr = data.getFloat(COL_WEATHER_WIND_SPEED); float windDirStr = data.getFloat(COL_WEATHER_DEGREES); mWindView.setText(Utility.getFormattedWind(getActivity(), windSpeedStr, windDirStr)); + mWindView.setContentDescription(mWindView.getText()); // Read pressure from cursor and update view float pressure = data.getFloat(COL_WEATHER_PRESSURE); mPressureView.setText(getActivity().getString(R.string.format_pressure, pressure)); + mPressureView.setContentDescription(mPressureView.getText()); // We still need this for the share intent mForecast = String.format("%s - %s - %s/%s", dateText, description, high, low); diff --git a/app/src/main/java/com/example/android/sunshine/app/ForecastAdapter.java b/app/src/main/java/com/example/android/sunshine/app/ForecastAdapter.java index caab205..6c200ad 100644 --- a/app/src/main/java/com/example/android/sunshine/app/ForecastAdapter.java +++ b/app/src/main/java/com/example/android/sunshine/app/ForecastAdapter.java @@ -115,20 +115,23 @@ public class ForecastAdapter extends CursorAdapter { String description = Utility.getStringForWeatherCondition(context, weatherId); // Find TextView and set weather forecast on it viewHolder.descriptionView.setText(description); + viewHolder.descriptionView.setContentDescription(context.getString(R.string.a11y_forecast, description)); - // For accessibility, add a content description to the icon field - viewHolder.iconView.setContentDescription(description); - - // Read user preference for metric or imperial temperature units - boolean isMetric = Utility.isMetric(context); + // For accessibility, we don't want a content description for the icon field + // because the information is repeated in the description view and the icon + // is not individually selectable // Read high temperature from cursor - double high = cursor.getDouble(ForecastFragment.COL_WEATHER_MAX_TEMP); - viewHolder.highTempView.setText(Utility.formatTemperature(context, high)); + String high = Utility.formatTemperature( + context, cursor.getDouble(ForecastFragment.COL_WEATHER_MAX_TEMP)); + viewHolder.highTempView.setText(high); + viewHolder.highTempView.setContentDescription(context.getString(R.string.a11y_high_temp, high)); // Read low temperature from cursor - double low = cursor.getDouble(ForecastFragment.COL_WEATHER_MIN_TEMP); - viewHolder.lowTempView.setText(Utility.formatTemperature(context, low)); + String low = Utility.formatTemperature( + context, cursor.getDouble(ForecastFragment.COL_WEATHER_MIN_TEMP)); + viewHolder.lowTempView.setText(low); + viewHolder.lowTempView.setContentDescription(context.getString(R.string.a11y_low_temp, low)); } public void setUseTodayLayout(boolean useTodayLayout) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4ee036f..f83ebc9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -123,6 +123,12 @@ No weather information available. The server is not returning valid data. Please check for an updated version of Sunshine. No weather information available. The location in settings is not recognized by the weather server. + + Forecast: %1$s + Forecast icon: %1$s + High: %1$s + Low: %1$s + Storm Drizzle