Skip to content

Commit ce3459b

Browse files
committed
Updated the project with GridLayout and other changes.
1 parent 7bd1eeb commit ce3459b

13 files changed

Lines changed: 402 additions & 248 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Android SDK 21 or Higher
99
Build Tools version 21.1.2
1010
Android Support AppCompat 22.2.0
1111
Android Support Annotations 22.2.0
12+
Android Support GridLayout 22.2.0
1213
Google Play Services GCM 7.0.0
1314
BumpTech Glide 3.5.2
1415

app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@ dependencies {
2424
compile 'com.github.bumptech.glide:glide:3.5.2'
2525
compile 'com.android.support:appcompat-v7:22.1.0'
2626
compile 'com.android.support:support-annotations:22.1.0'
27+
compile 'com.android.support:gridlayout-v7:22.1.0'
2728
compile 'com.google.android.gms:play-services-gcm:7.0.0'
2829
}

app/src/main/java/com/example/android/sunshine/app/DetailActivity.java

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ protected void onCreate(Bundle savedInstanceState) {
3131
super.onCreate(savedInstanceState);
3232
setContentView(R.layout.activity_detail);
3333

34-
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
35-
setSupportActionBar(toolbar);
36-
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
37-
3834
if (savedInstanceState == null) {
3935
// Create the detail fragment and add it to the activity
4036
// using a fragment transaction.
@@ -50,24 +46,4 @@ protected void onCreate(Bundle savedInstanceState) {
5046
.commit();
5147
}
5248
}
53-
54-
@Override
55-
public boolean onCreateOptionsMenu(Menu menu) {
56-
// Inflate the menu; this adds items to the action bar if it is present.
57-
getMenuInflater().inflate(R.menu.detail, menu);
58-
return true;
59-
}
60-
61-
@Override
62-
public boolean onOptionsItemSelected(MenuItem item) {
63-
// Handle action bar item clicks here. The action bar will
64-
// automatically handle clicks on the Home/Up button, so long
65-
// as you specify a parent activity in AndroidManifest.xml.
66-
int id = item.getItemId();
67-
if (id == R.id.action_settings) {
68-
startActivity(new Intent(this, SettingsActivity.class));
69-
return true;
70-
}
71-
return super.onOptionsItemSelected(item);
72-
}
7349
}

app/src/main/java/com/example/android/sunshine/app/DetailFragment.java

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
import android.support.v4.content.CursorLoader;
2525
import android.support.v4.content.Loader;
2626
import android.support.v4.view.MenuItemCompat;
27+
import android.support.v7.app.AppCompatActivity;
2728
import android.support.v7.widget.ShareActionProvider;
29+
import android.support.v7.widget.Toolbar;
2830
import android.view.LayoutInflater;
2931
import android.view.Menu;
3032
import android.view.MenuInflater;
@@ -84,14 +86,16 @@ public class DetailFragment extends Fragment implements LoaderManager.LoaderCall
8486
public static final int COL_WEATHER_CONDITION_ID = 9;
8587

8688
private ImageView mIconView;
87-
private TextView mFriendlyDateView;
8889
private TextView mDateView;
8990
private TextView mDescriptionView;
9091
private TextView mHighTempView;
9192
private TextView mLowTempView;
9293
private TextView mHumidityView;
94+
private TextView mHumidityLabelView;
9395
private TextView mWindView;
96+
private TextView mWindLabelView;
9497
private TextView mPressureView;
98+
private TextView mPressureLabelView;
9599

96100
public DetailFragment() {
97101
setHasOptionsMenu(true);
@@ -109,30 +113,30 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
109113
View rootView = inflater.inflate(R.layout.fragment_detail, container, false);
110114
mIconView = (ImageView) rootView.findViewById(R.id.detail_icon);
111115
mDateView = (TextView) rootView.findViewById(R.id.detail_date_textview);
112-
mFriendlyDateView = (TextView) rootView.findViewById(R.id.detail_day_textview);
113116
mDescriptionView = (TextView) rootView.findViewById(R.id.detail_forecast_textview);
114117
mHighTempView = (TextView) rootView.findViewById(R.id.detail_high_textview);
115118
mLowTempView = (TextView) rootView.findViewById(R.id.detail_low_textview);
116119
mHumidityView = (TextView) rootView.findViewById(R.id.detail_humidity_textview);
120+
mHumidityLabelView = (TextView) rootView.findViewById(R.id.detail_humidity_label_textview);
117121
mWindView = (TextView) rootView.findViewById(R.id.detail_wind_textview);
122+
mWindLabelView = (TextView) rootView.findViewById(R.id.detail_wind_label_textview);
118123
mPressureView = (TextView) rootView.findViewById(R.id.detail_pressure_textview);
124+
mPressureLabelView = (TextView) rootView.findViewById(R.id.detail_pressure_label_textview);
119125
return rootView;
120126
}
121127

122-
@Override
123-
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
124-
// Inflate the menu; this adds items to the action bar if it is present.
125-
inflater.inflate(R.menu.detailfragment, menu);
126-
128+
private void finishCreatingMenu(Menu menu) {
127129
// Retrieve the share menu item
128130
MenuItem menuItem = menu.findItem(R.id.action_share);
131+
menuItem.setIntent(createShareForecastIntent());
132+
}
129133

130-
// Get the provider and hold onto it to set/change the share intent.
131-
mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(menuItem);
132-
133-
// If onLoadFinished happens before this, we can go ahead and set the share intent now.
134-
if (mForecast != null) {
135-
mShareActionProvider.setShareIntent(createShareForecastIntent());
134+
@Override
135+
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
136+
if ( getActivity() instanceof DetailActivity ){
137+
// Inflate the menu; this adds items to the action bar if it is present.
138+
inflater.inflate(R.menu.detailfragment, menu);
139+
finishCreatingMenu(menu);
136140
}
137141
}
138142

@@ -184,18 +188,20 @@ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
184188
// Read weather condition ID from cursor
185189
int weatherId = data.getInt(COL_WEATHER_CONDITION_ID);
186190

187-
// Use weather art image
188-
Glide.with(this)
189-
.load(Utility.getArtUrlForWeatherCondition(getActivity(), weatherId))
190-
.error(Utility.getArtResourceForWeatherCondition(weatherId))
191-
.crossFade()
192-
.into(mIconView);
191+
if ( Utility.usingLocalGraphics(getActivity()) ) {
192+
mIconView.setImageResource(Utility.getArtResourceForWeatherCondition(weatherId));
193+
} else {
194+
// Use weather art image
195+
Glide.with(this)
196+
.load(Utility.getArtUrlForWeatherCondition(getActivity(), weatherId))
197+
.error(Utility.getArtResourceForWeatherCondition(weatherId))
198+
.crossFade()
199+
.into(mIconView);
200+
}
193201

194202
// Read date from cursor and update views for day of week and date
195203
long date = data.getLong(COL_WEATHER_DATE);
196-
String friendlyDateText = Utility.getDayName(getActivity(), date);
197-
String dateText = Utility.getFormattedMonthDay(getActivity(), date);
198-
mFriendlyDateView.setText(friendlyDateText);
204+
String dateText = Utility.getFullFriendlyDayString(getActivity(),date);
199205
mDateView.setText(dateText);
200206

201207
// Get description from weather condition ID
@@ -226,18 +232,21 @@ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
226232
// Read humidity from cursor and update view
227233
float humidity = data.getFloat(COL_WEATHER_HUMIDITY);
228234
mHumidityView.setText(getActivity().getString(R.string.format_humidity, humidity));
229-
mHumidityView.setContentDescription(mHumidityView.getText());
235+
mHumidityView.setContentDescription(getString(R.string.a11y_humidity, mHumidityView.getText()));
236+
mHumidityLabelView.setContentDescription(mHumidityView.getContentDescription());
230237

231238
// Read wind speed and direction from cursor and update view
232239
float windSpeedStr = data.getFloat(COL_WEATHER_WIND_SPEED);
233240
float windDirStr = data.getFloat(COL_WEATHER_DEGREES);
234241
mWindView.setText(Utility.getFormattedWind(getActivity(), windSpeedStr, windDirStr));
235-
mWindView.setContentDescription(mWindView.getText());
242+
mWindView.setContentDescription(getString(R.string.a11y_wind, mWindView.getText()));
243+
mWindLabelView.setContentDescription(mWindView.getContentDescription());
236244

237245
// Read pressure from cursor and update view
238246
float pressure = data.getFloat(COL_WEATHER_PRESSURE);
239-
mPressureView.setText(getActivity().getString(R.string.format_pressure, pressure));
240-
mPressureView.setContentDescription(mPressureView.getText());
247+
mPressureView.setText(getString(R.string.format_pressure, pressure));
248+
mPressureView.setContentDescription(getString(R.string.a11y_pressure, mPressureView.getText()));
249+
mPressureLabelView.setContentDescription(mPressureView.getContentDescription());
241250

242251
// We still need this for the share intent
243252
mForecast = String.format("%s - %s - %s/%s", dateText, description, high, low);
@@ -247,6 +256,27 @@ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
247256
mShareActionProvider.setShareIntent(createShareForecastIntent());
248257
}
249258
}
259+
AppCompatActivity activity = (AppCompatActivity)getActivity();
260+
Toolbar toolbarView = (Toolbar) getView().findViewById(R.id.toolbar);
261+
262+
// We need to start the enter transition after the data has loaded
263+
if (activity instanceof DetailActivity) {
264+
activity.supportStartPostponedEnterTransition();
265+
266+
if ( null != toolbarView ) {
267+
activity.setSupportActionBar(toolbarView);
268+
269+
activity.getSupportActionBar().setDisplayShowTitleEnabled(false);
270+
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
271+
}
272+
} else {
273+
if ( null != toolbarView ) {
274+
Menu menu = toolbarView.getMenu();
275+
if ( null != menu ) menu.clear();
276+
toolbarView.inflateMenu(R.menu.detailfragment);
277+
finishCreatingMenu(toolbarView.getMenu());
278+
}
279+
}
250280
}
251281

252282
@Override

app/src/main/java/com/example/android/sunshine/app/Utility.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,24 @@ public static String getFriendlyDayString(Context context, long dateInMillis) {
104104
}
105105
}
106106

107+
/**
108+
* Helper method to convert the database representation of the date into something to display
109+
* to users. As classy and polished a user experience as "20140102" is, we can do better.
110+
*
111+
* @param context Context to use for resource localization
112+
* @param dateInMillis The date in milliseconds
113+
* @return a user-friendly representation of the date.
114+
*/
115+
public static String getFullFriendlyDayString(Context context, long dateInMillis) {
116+
117+
String day = getDayName(context, dateInMillis);
118+
int formatId = R.string.format_full_friendly_date;
119+
return String.format(context.getString(
120+
formatId,
121+
day,
122+
getFormattedMonthDay(context, dateInMillis)));
123+
}
124+
107125
/**
108126
* Given a day, returns just the name to use for that day.
109127
* E.g "today", "tomorrow", "wednesday".
@@ -217,6 +235,19 @@ public static int getIconResourceForWeatherCondition(int weatherId) {
217235
return -1;
218236
}
219237

238+
/**
239+
* Helper method to return whether or not Sunshine is using local graphics.
240+
*
241+
* @param context Context to use for retrieving the preference
242+
* @return true if Sunshine is using local graphics, false otherwise.
243+
*/
244+
public static boolean usingLocalGraphics(Context context) {
245+
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
246+
String sunshineArtPack = context.getString(R.string.pref_art_pack_sunshine);
247+
return prefs.getString(context.getString(R.string.pref_art_pack_key),
248+
sunshineArtPack).equals(sunshineArtPack);
249+
}
250+
220251
/**
221252
* Helper method to provide the art urls according to the weather condition id returned
222253
* by the OpenWeatherMap call.

app/src/main/res/layout/activity_detail.xml

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,10 @@
1313
See the License for the specific language governing permissions and
1414
limitations under the License.
1515
-->
16-
<LinearLayout
17-
xmlns:android="http://schemas.android.com/apk/res/android"
16+
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
17+
xmlns:tools="http://schemas.android.com/tools"
18+
android:id="@+id/weather_detail_container"
1819
android:layout_width="match_parent"
19-
android:layout_height="wrap_content"
20-
android:orientation="vertical">
21-
22-
<android.support.v7.widget.Toolbar
23-
android:id="@+id/toolbar"
24-
android:layout_width="match_parent"
25-
android:layout_height="?attr/actionBarSize"
26-
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
27-
28-
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
29-
xmlns:tools="http://schemas.android.com/tools"
30-
android:id="@+id/weather_detail_container"
31-
android:layout_width="match_parent"
32-
android:layout_height="match_parent"
33-
tools:context="com.example.android.sunshine.app.DetailActivity"
34-
tools:ignore="MergeRootFrame" />
35-
</LinearLayout>
20+
android:layout_height="match_parent"
21+
tools:context="com.example.android.sunshine.app.DetailActivity"
22+
tools:ignore="MergeRootFrame" />
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<!--
2+
Copyright (C) 2015 The Android Open Source Project
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
<!-- Detail Layout for Grid -->
17+
<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
18+
xmlns:app="http://schemas.android.com/apk/res-auto"
19+
xmlns:tools="http://schemas.android.com/tools"
20+
android:layout_width="match_parent"
21+
android:layout_height="match_parent"
22+
android:background="@android:color/white"
23+
app:columnCount="2">
24+
25+
<android.support.v7.widget.Space
26+
app:layout_columnSpan="2"
27+
app:layout_columnWeight="1"
28+
app:layout_rowWeight="1" />
29+
30+
<TextView
31+
android:id="@+id/detail_date_textview"
32+
android:layout_marginBottom="@dimen/abc_list_item_padding_horizontal_material"
33+
android:layout_marginTop="@dimen/abc_list_item_padding_horizontal_material"
34+
android:fontFamily="sans-serif"
35+
android:gravity="center_horizontal"
36+
android:textAppearance="@style/TextAppearance.AppCompat.Title"
37+
android:textColor="@color/secondary_text"
38+
app:layout_columnSpan="2"
39+
app:layout_columnWeight="1"
40+
app:layout_gravity="fill_horizontal"
41+
tools:text="Today, April 03" />
42+
43+
<ImageView
44+
android:id="@+id/detail_icon"
45+
android:layout_width="0dp"
46+
android:adjustViewBounds="true"
47+
android:maxHeight="@dimen/today_icon"
48+
android:maxWidth="@dimen/today_icon"
49+
app:layout_columnWeight="1"
50+
app:layout_gravity="fill_horizontal"
51+
tools:src="@drawable/art_clouds" />
52+
53+
<TextView
54+
android:id="@+id/detail_high_textview"
55+
android:layout_width="0dp"
56+
android:fontFamily="sans-serif-light"
57+
android:gravity="center_horizontal"
58+
android:textColor="@color/primary_text"
59+
android:textSize="72sp"
60+
app:layout_columnWeight="1"
61+
app:layout_gravity="fill_horizontal"
62+
tools:text="19" />
63+
64+
<TextView
65+
android:id="@+id/detail_forecast_textview"
66+
android:layout_width="0dp"
67+
android:fontFamily="sans-serif"
68+
android:gravity="center_horizontal"
69+
android:textAppearance="@style/TextAppearance.AppCompat.Title"
70+
android:textColor="@color/secondary_text"
71+
app:layout_columnWeight="1"
72+
tools:text="Rainy" />
73+
74+
<TextView
75+
android:id="@+id/detail_low_textview"
76+
android:layout_width="0dp"
77+
android:layout_marginBottom="@dimen/abc_list_item_padding_horizontal_material"
78+
android:fontFamily="sans-serif-light"
79+
android:gravity="center_horizontal"
80+
android:textColor="@color/secondary_text"
81+
android:textSize="36sp"
82+
app:layout_columnWeight="1"
83+
tools:text="10" />
84+
85+
<android.support.v7.widget.Space
86+
app:layout_columnSpan="2"
87+
app:layout_columnWeight="1"
88+
app:layout_rowWeight="1" />
89+
90+
</android.support.v7.widget.GridLayout>
91+

0 commit comments

Comments
 (0)