From ce3459bd874994f3856c404afc764f3447de5275 Mon Sep 17 00:00:00 2001 From: Dan Galpin Date: Mon, 25 May 2015 01:45:41 -0700 Subject: [PATCH] Updated the project with GridLayout and other changes. --- README.md | 1 + app/build.gradle | 1 + .../android/sunshine/app/DetailActivity.java | 24 --- .../android/sunshine/app/DetailFragment.java | 84 +++++--- .../example/android/sunshine/app/Utility.java | 31 +++ app/src/main/res/layout/activity_detail.xml | 25 +-- app/src/main/res/layout/detail_today_grid.xml | 91 +++++++++ app/src/main/res/layout/fragment_detail.xml | 182 +++++++++-------- .../main/res/layout/fragment_detail_wide.xml | 184 +++++++++--------- app/src/main/res/menu/detailfragment.xml | 4 +- app/src/main/res/values/colors.xml | 6 + app/src/main/res/values/dimens.xml | 7 + app/src/main/res/values/strings.xml | 14 +- 13 files changed, 404 insertions(+), 250 deletions(-) create mode 100644 app/src/main/res/layout/detail_today_grid.xml diff --git a/README.md b/README.md index af53014..dd1731f 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Android SDK 21 or Higher Build Tools version 21.1.2 Android Support AppCompat 22.2.0 Android Support Annotations 22.2.0 +Android Support GridLayout 22.2.0 Google Play Services GCM 7.0.0 BumpTech Glide 3.5.2 diff --git a/app/build.gradle b/app/build.gradle index 2068d3d..b8b3914 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -24,5 +24,6 @@ dependencies { compile 'com.github.bumptech.glide:glide:3.5.2' compile 'com.android.support:appcompat-v7:22.1.0' compile 'com.android.support:support-annotations:22.1.0' + compile 'com.android.support:gridlayout-v7:22.1.0' compile 'com.google.android.gms:play-services-gcm:7.0.0' } diff --git a/app/src/main/java/com/example/android/sunshine/app/DetailActivity.java b/app/src/main/java/com/example/android/sunshine/app/DetailActivity.java index 80185b3..a23c185 100644 --- a/app/src/main/java/com/example/android/sunshine/app/DetailActivity.java +++ b/app/src/main/java/com/example/android/sunshine/app/DetailActivity.java @@ -31,10 +31,6 @@ public class DetailActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_detail); - Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar); - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - if (savedInstanceState == null) { // Create the detail fragment and add it to the activity // using a fragment transaction. @@ -50,24 +46,4 @@ public class DetailActivity extends AppCompatActivity { .commit(); } } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.detail, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - if (id == R.id.action_settings) { - startActivity(new Intent(this, SettingsActivity.class)); - return true; - } - return super.onOptionsItemSelected(item); - } } \ No newline at end of file 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 0c88c6f..6a83b4b 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 @@ -24,7 +24,9 @@ import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.view.MenuItemCompat; +import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.ShareActionProvider; +import android.support.v7.widget.Toolbar; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -84,14 +86,16 @@ public class DetailFragment extends Fragment implements LoaderManager.LoaderCall public static final int COL_WEATHER_CONDITION_ID = 9; private ImageView mIconView; - private TextView mFriendlyDateView; private TextView mDateView; private TextView mDescriptionView; private TextView mHighTempView; private TextView mLowTempView; private TextView mHumidityView; + private TextView mHumidityLabelView; private TextView mWindView; + private TextView mWindLabelView; private TextView mPressureView; + private TextView mPressureLabelView; public DetailFragment() { setHasOptionsMenu(true); @@ -109,30 +113,30 @@ public class DetailFragment extends Fragment implements LoaderManager.LoaderCall View rootView = inflater.inflate(R.layout.fragment_detail, container, false); mIconView = (ImageView) rootView.findViewById(R.id.detail_icon); mDateView = (TextView) rootView.findViewById(R.id.detail_date_textview); - mFriendlyDateView = (TextView) rootView.findViewById(R.id.detail_day_textview); mDescriptionView = (TextView) rootView.findViewById(R.id.detail_forecast_textview); mHighTempView = (TextView) rootView.findViewById(R.id.detail_high_textview); mLowTempView = (TextView) rootView.findViewById(R.id.detail_low_textview); mHumidityView = (TextView) rootView.findViewById(R.id.detail_humidity_textview); + mHumidityLabelView = (TextView) rootView.findViewById(R.id.detail_humidity_label_textview); mWindView = (TextView) rootView.findViewById(R.id.detail_wind_textview); + mWindLabelView = (TextView) rootView.findViewById(R.id.detail_wind_label_textview); mPressureView = (TextView) rootView.findViewById(R.id.detail_pressure_textview); + mPressureLabelView = (TextView) rootView.findViewById(R.id.detail_pressure_label_textview); return rootView; } + private void finishCreatingMenu(Menu menu) { + // Retrieve the share menu item + MenuItem menuItem = menu.findItem(R.id.action_share); + menuItem.setIntent(createShareForecastIntent()); + } + @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - // Inflate the menu; this adds items to the action bar if it is present. - inflater.inflate(R.menu.detailfragment, menu); - - // Retrieve the share menu item - MenuItem menuItem = menu.findItem(R.id.action_share); - - // Get the provider and hold onto it to set/change the share intent. - mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(menuItem); - - // If onLoadFinished happens before this, we can go ahead and set the share intent now. - if (mForecast != null) { - mShareActionProvider.setShareIntent(createShareForecastIntent()); + if ( getActivity() instanceof DetailActivity ){ + // Inflate the menu; this adds items to the action bar if it is present. + inflater.inflate(R.menu.detailfragment, menu); + finishCreatingMenu(menu); } } @@ -184,18 +188,20 @@ public class DetailFragment extends Fragment implements LoaderManager.LoaderCall // Read weather condition ID from cursor int weatherId = data.getInt(COL_WEATHER_CONDITION_ID); - // Use weather art image - Glide.with(this) - .load(Utility.getArtUrlForWeatherCondition(getActivity(), weatherId)) - .error(Utility.getArtResourceForWeatherCondition(weatherId)) - .crossFade() - .into(mIconView); + if ( Utility.usingLocalGraphics(getActivity()) ) { + mIconView.setImageResource(Utility.getArtResourceForWeatherCondition(weatherId)); + } else { + // Use weather art image + Glide.with(this) + .load(Utility.getArtUrlForWeatherCondition(getActivity(), weatherId)) + .error(Utility.getArtResourceForWeatherCondition(weatherId)) + .crossFade() + .into(mIconView); + } // Read date from cursor and update views for day of week and date long date = data.getLong(COL_WEATHER_DATE); - String friendlyDateText = Utility.getDayName(getActivity(), date); - String dateText = Utility.getFormattedMonthDay(getActivity(), date); - mFriendlyDateView.setText(friendlyDateText); + String dateText = Utility.getFullFriendlyDayString(getActivity(),date); mDateView.setText(dateText); // Get description from weather condition ID @@ -226,18 +232,21 @@ public class DetailFragment extends Fragment implements LoaderManager.LoaderCall // 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()); + mHumidityView.setContentDescription(getString(R.string.a11y_humidity, mHumidityView.getText())); + mHumidityLabelView.setContentDescription(mHumidityView.getContentDescription()); // 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()); + mWindView.setContentDescription(getString(R.string.a11y_wind, mWindView.getText())); + mWindLabelView.setContentDescription(mWindView.getContentDescription()); // 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()); + mPressureView.setText(getString(R.string.format_pressure, pressure)); + mPressureView.setContentDescription(getString(R.string.a11y_pressure, mPressureView.getText())); + mPressureLabelView.setContentDescription(mPressureView.getContentDescription()); // We still need this for the share intent mForecast = String.format("%s - %s - %s/%s", dateText, description, high, low); @@ -247,6 +256,27 @@ public class DetailFragment extends Fragment implements LoaderManager.LoaderCall mShareActionProvider.setShareIntent(createShareForecastIntent()); } } + AppCompatActivity activity = (AppCompatActivity)getActivity(); + Toolbar toolbarView = (Toolbar) getView().findViewById(R.id.toolbar); + + // We need to start the enter transition after the data has loaded + if (activity instanceof DetailActivity) { + activity.supportStartPostponedEnterTransition(); + + if ( null != toolbarView ) { + activity.setSupportActionBar(toolbarView); + + activity.getSupportActionBar().setDisplayShowTitleEnabled(false); + activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + } else { + if ( null != toolbarView ) { + Menu menu = toolbarView.getMenu(); + if ( null != menu ) menu.clear(); + toolbarView.inflateMenu(R.menu.detailfragment); + finishCreatingMenu(toolbarView.getMenu()); + } + } } @Override diff --git a/app/src/main/java/com/example/android/sunshine/app/Utility.java b/app/src/main/java/com/example/android/sunshine/app/Utility.java index bad6d0c..7e1dacb 100644 --- a/app/src/main/java/com/example/android/sunshine/app/Utility.java +++ b/app/src/main/java/com/example/android/sunshine/app/Utility.java @@ -104,6 +104,24 @@ public class Utility { } } + /** + * 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 getFullFriendlyDayString(Context context, long dateInMillis) { + + String day = getDayName(context, dateInMillis); + int formatId = R.string.format_full_friendly_date; + return String.format(context.getString( + formatId, + day, + getFormattedMonthDay(context, dateInMillis))); + } + /** * Given a day, returns just the name to use for that day. * E.g "today", "tomorrow", "wednesday". @@ -217,6 +235,19 @@ public class Utility { return -1; } + /** + * Helper method to return whether or not Sunshine is using local graphics. + * + * @param context Context to use for retrieving the preference + * @return true if Sunshine is using local graphics, false otherwise. + */ + public static boolean usingLocalGraphics(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + String sunshineArtPack = context.getString(R.string.pref_art_pack_sunshine); + return prefs.getString(context.getString(R.string.pref_art_pack_key), + sunshineArtPack).equals(sunshineArtPack); + } + /** * Helper method to provide the art urls according to the weather condition id returned * by the OpenWeatherMap call. diff --git a/app/src/main/res/layout/activity_detail.xml b/app/src/main/res/layout/activity_detail.xml index fd45611..280300c 100644 --- a/app/src/main/res/layout/activity_detail.xml +++ b/app/src/main/res/layout/activity_detail.xml @@ -13,23 +13,10 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - - - - \ No newline at end of file + android:layout_height="match_parent" + tools:context="com.example.android.sunshine.app.DetailActivity" + tools:ignore="MergeRootFrame" /> diff --git a/app/src/main/res/layout/detail_today_grid.xml b/app/src/main/res/layout/detail_today_grid.xml new file mode 100644 index 0000000..de8f317 --- /dev/null +++ b/app/src/main/res/layout/detail_today_grid.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_detail.xml b/app/src/main/res/layout/fragment_detail.xml index be69a26..f4108dd 100644 --- a/app/src/main/res/layout/fragment_detail.xml +++ b/app/src/main/res/layout/fragment_detail.xml @@ -14,115 +14,127 @@ limitations under the License. --> - + android:layout_height="match_parent" + android:orientation="vertical"> + + + + + android:paddingBottom="@dimen/abc_list_item_padding_horizontal_material" + android:paddingEnd="@dimen/forecast_detail_horizontal_padding" + android:paddingLeft="@dimen/forecast_detail_horizontal_padding" + android:paddingRight="@dimen/forecast_detail_horizontal_padding" + android:paddingStart="@dimen/forecast_detail_horizontal_padding" + android:paddingTop="@dimen/abc_list_item_padding_horizontal_material"> - - - - - - - + + - - - - - - - - - - - - + android:paddingEnd="@dimen/forecast_detail_horizontal_padding" + android:paddingRight="@dimen/forecast_detail_horizontal_padding" + android:id="@+id/detail_humidity_textview" + android:gravity="center_vertical" + android:textAppearance="@style/TextAppearance.AppCompat.Headline" + android:textColor="@android:color/white" + tools:text="38%" /> - + android:layout_height="wrap_content" + android:orientation="horizontal"> + android:paddingEnd="@dimen/forecast_detail_horizontal_padding" + android:paddingRight="@dimen/forecast_detail_horizontal_padding" + android:id="@+id/detail_pressure_label_textview" + android:fontFamily="sans-serif" + android:gravity="center_vertical" + android:text="@string/pressure" + android:textAppearance="@style/TextAppearance.AppCompat.Title" + android:textColor="@color/detail_accent_label" /> + + android:gravity="center_vertical" + android:textAppearance="@style/TextAppearance.AppCompat.Headline" + android:textColor="@android:color/white" + tools:text="995 hPa" /> + + + + + android:paddingEnd="@dimen/forecast_detail_horizontal_padding" + android:paddingRight="@dimen/forecast_detail_horizontal_padding" + android:id="@+id/detail_wind_label_textview" + android:fontFamily="sans-serif" + android:gravity="center_vertical" + android:text="@string/wind" + android:textColor="@color/detail_accent_label" + android:textAppearance="@style/TextAppearance.AppCompat.Title" /> + + + - + + + diff --git a/app/src/main/res/layout/fragment_detail_wide.xml b/app/src/main/res/layout/fragment_detail_wide.xml index 4724e23..b92648a 100644 --- a/app/src/main/res/layout/fragment_detail_wide.xml +++ b/app/src/main/res/layout/fragment_detail_wide.xml @@ -14,113 +14,119 @@ limitations under the License. --> - + android:layout_height="match_parent"> + android:layout_height="match_parent" + android:orientation="horizontal"> - + + + + + + + + + android:layout_height="match_parent" + app:columnCount="2" + android:background="@color/detail_accent_pane_background" + android:paddingEnd="@dimen/abc_list_item_padding_horizontal_material" + android:paddingRight="@dimen/abc_list_item_padding_horizontal_material" + > - - + - - - - - + android:id="@+id/detail_humidity_label_textview" + android:fontFamily="sans-serif" + android:gravity="center_vertical" + android:text="@string/humidity" + android:textColor="@color/detail_accent_label" + android:textAppearance="@style/TextAppearance.AppCompat.Title" + android:paddingLeft="@dimen/abc_list_item_padding_horizontal_material" + android:paddingRight="@dimen/abc_list_item_padding_horizontal_material" + android:paddingBottom="@dimen/abc_list_item_padding_horizontal_material" + /> - - - - - + android:fontFamily="sans-serif" + android:gravity="center_vertical" + tools:text="38%" + android:textColor="@android:color/white" + android:textAppearance="@style/TextAppearance.AppCompat.Title" + /> + + + + android:fontFamily="sans-serif" + android:gravity="center_vertical" + tools:text="995 hPa" + android:textColor="@android:color/white" + android:textAppearance="@style/TextAppearance.AppCompat.Title" + /> + + - + android:fontFamily="sans-serif" + android:gravity="center_vertical" + tools:text="4km/h NW" + android:textColor="@android:color/white" + android:textAppearance="@style/TextAppearance.AppCompat.Title" + /> - + - - - - + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/menu/detailfragment.xml b/app/src/main/res/menu/detailfragment.xml index b929cc8..c92c7c6 100644 --- a/app/src/main/res/menu/detailfragment.xml +++ b/app/src/main/res/menu/detailfragment.xml @@ -18,6 +18,6 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> + android:icon="@drawable/abc_ic_menu_share_mtrl_alpha" + app:showAsAction="always"/> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index ab9ea4d..d36c35c 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -26,5 +26,11 @@ #0288D1 #B3E5FC #FFD740 + #212121 + #727272 + + + #455A64 + #90A4AE \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index b12ae05..5d125fb 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -19,4 +19,11 @@ 16dp 48dp + 32dp + + + 96dp + + + @dimen/abc_list_item_padding_horizontal_material diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f330d64..1263e48 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -111,17 +111,20 @@ %1.0f\u00B0 + Wind - Wind: %1$1.0f mph %2$s + %1$1.0f mph %2$s - Wind: %1$1.0f km/h %2$s + %1$1.0f km/h %2$s + Pressure - Pressure: %1.0f hPa + %1.0f hPa + Humidity - Humidity: %1.0f %% + %1.0f %% sunshine.example.com @@ -145,6 +148,9 @@ Forecast icon: %1$s High: %1$s Low: %1$s + Humidity: %1$s + Barometric Pressure: %1$s + Wind speed and direction: %1$s Storm