Skip to content

Commit

Permalink
S09.05-Exercise-MoreDetails
Browse files Browse the repository at this point in the history
  • Loading branch information
Asser Samak authored and Jeremy Silver committed Jan 19, 2017
1 parent fc185e2 commit 57bd891
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 55 deletions.
36 changes: 34 additions & 2 deletions app/src/main/java/com/example/android/sunshine/DetailActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,33 +34,47 @@
import com.example.android.sunshine.utilities.SunshineWeatherUtils;

public class DetailActivity extends AppCompatActivity {
// TODO (21) Implement LoaderManager.LoaderCallbacks<Cursor>

/*
* In this Activity, you can share the selected day's forecast. No social sharing is complete
* without using a hashtag. #BeTogetherNotTheSame
*/
private static final String FORECAST_SHARE_HASHTAG = " #SunshineApp";

// TODO (18) Create a String array containing the names of the desired data columns from our ContentProvider
// TODO (19) Create constant int values representing each column name's position above
// TODO (20) Create a constant int to identify our loader used in DetailActivity

/* A summary of the forecast that can be shared by clicking the share button in the ActionBar */
private String mForecastSummary;

// TODO (15) Declare a private Uri field called mUri

// TODO (10) Remove the mWeatherDisplay TextView declaration
private TextView mWeatherDisplay;

// TODO (11) Declare TextViews for the date, description, high, low, humidity, wind, and pressure

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);

// TODO (12) Remove mWeatherDisplay TextView
mWeatherDisplay = (TextView) findViewById(R.id.tv_display_weather);
// TODO (13) Find each of the TextViews by ID

// TODO (14) Remove the code that checks for extra text
Intent intentThatStartedThisActivity = getIntent();

if (intentThatStartedThisActivity != null) {
if (intentThatStartedThisActivity.hasExtra(Intent.EXTRA_TEXT)) {
mForecastSummary = intentThatStartedThisActivity.getStringExtra(Intent.EXTRA_TEXT);
mWeatherDisplay.setText(mForecastSummary);
}
}
// TODO (16) Use getData to get a reference to the URI passed with this Activity's Intent
// TODO (17) Throw a NullPointerException if that URI is null
// TODO (35) Initialize the loader for DetailActivity
}

/**
Expand Down Expand Up @@ -129,4 +143,22 @@ private Intent createShareForecastIntent() {
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
return shareIntent;
}

// TODO (22) Override onCreateLoader
// TODO (23) If the loader requested is our detail loader, return the appropriate CursorLoader

// TODO (24) Override onLoadFinished
// TODO (25) Check before doing anything that the Cursor has valid data
// TODO (26) Display a readable data string
// TODO (27) Display the weather description (using SunshineWeatherUtils)
// TODO (28) Display the high temperature
// TODO (29) Display the low temperature
// TODO (30) Display the humidity
// TODO (31) Display the wind speed and direction
// TODO (32) Display the pressure
// TODO (33) Store a forecast summary in mForecastSummary


// TODO (34) Override onLoaderReset, but don't do anything in it yet

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@
*/
class ForecastAdapter extends RecyclerView.Adapter<ForecastAdapter.ForecastAdapterViewHolder> {

// COMPLETED (14) Remove the mWeatherData declaration

// COMPLETED (1) Declare a private final Context field called mContext
/* The context we use to utility methods, app resources and layout inflaters */
private final Context mContext;

Expand All @@ -51,13 +48,12 @@ class ForecastAdapter extends RecyclerView.Adapter<ForecastAdapter.ForecastAdapt
* The interface that receives onClick messages.
*/
public interface ForecastAdapterOnClickHandler {
// TODO (36) Refactor onClick to accept a long as its parameter rather than a String
void onClick(String weatherForDay);
}

// COMPLETED (2) Declare a private Cursor field called mCursor
private Cursor mCursor;

// COMPLETED (3) Add a Context field to the constructor and store that context in mContext
/**
* Creates a ForecastAdapter.
*
Expand Down Expand Up @@ -105,16 +101,12 @@ public ForecastAdapterViewHolder onCreateViewHolder(ViewGroup viewGroup, int vie
*/
@Override
public void onBindViewHolder(ForecastAdapterViewHolder forecastAdapterViewHolder, int position) {
// COMPLETED (5) Delete the current body of onBindViewHolder

// COMPLETED (6) Move the cursor to the appropriate position
mCursor.moveToPosition(position);


/*******************
* Weather Summary *
*******************/
// COMPLETED (7) Generate a weather summary with the date, description, high and low
/* Read date from the cursor */
long dateInMillis = mCursor.getLong(MainActivity.INDEX_WEATHER_DATE);
/* Get human readable string using our utility method */
Expand All @@ -132,7 +124,6 @@ public void onBindViewHolder(ForecastAdapterViewHolder forecastAdapterViewHolder

String weatherSummary = dateString + " - " + description + " - " + highAndLowTemperature;

// COMPLETED (8) Display the summary that you created above
forecastAdapterViewHolder.weatherSummary.setText(weatherSummary);
}

Expand All @@ -144,13 +135,10 @@ public void onBindViewHolder(ForecastAdapterViewHolder forecastAdapterViewHolder
*/
@Override
public int getItemCount() {
// COMPLETED (9) Delete the current body of getItemCount
// COMPLETED (10) If mCursor is null, return 0. Otherwise, return the count of mCursor
if (null == mCursor) return 0;
return mCursor.getCount();
}

// COMPLETED (11) Create a new method that allows you to swap Cursors.
/**
* Swaps the cursor used by the ForecastAdapter for its weather data. This method is called by
* MainActivity after a load has finished, as well as when the Loader responsible for loading
Expand All @@ -161,7 +149,6 @@ public int getItemCount() {
*/
void swapCursor(Cursor newCursor) {
mCursor = newCursor;
// COMPLETED (12) After the new Cursor is set, call notifyDataSetChanged
notifyDataSetChanged();
}

Expand Down Expand Up @@ -190,7 +177,7 @@ class ForecastAdapterViewHolder extends RecyclerView.ViewHolder implements View.
*/
@Override
public void onClick(View v) {
// COMPLETED (13) Instead of passing the String from the data array, use the weatherSummary text!
// TODO (37) Instead of passing the String for the clicked item, pass the date from the cursor
String weatherForDay = weatherSummary.getText().toString();
mClickHandler.onClick(weatherForDay);
}
Expand Down
37 changes: 2 additions & 35 deletions app/src/main/java/com/example/android/sunshine/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,12 @@
import com.example.android.sunshine.data.WeatherContract;
import com.example.android.sunshine.utilities.FakeDataUtils;


public class MainActivity extends AppCompatActivity implements
// COMPLETED (15) Remove the implements declaration for SharedPreferences change listener
// COMPLETED (20) Implement LoaderCallbacks<Cursor> instead of String[]
LoaderManager.LoaderCallbacks<Cursor>,
ForecastAdapter.ForecastAdapterOnClickHandler {

private final String TAG = MainActivity.class.getSimpleName();

// COMPLETED (16) Create a String array containing the names of the desired data columns from our ContentProvider
/*
* The columns of data that we are interested in displaying within our MainActivity's list of
* weather data.
Expand All @@ -58,7 +54,6 @@ public class MainActivity extends AppCompatActivity implements
WeatherContract.WeatherEntry.COLUMN_WEATHER_ID,
};

// COMPLETED (17) Create constant int values representing each column name's position above
/*
* We store the indices of the values in the array of Strings above to more quickly be able to
* access the data from our query. If the order of the Strings above changes, these indices
Expand All @@ -69,7 +64,6 @@ public class MainActivity extends AppCompatActivity implements
public static final int INDEX_WEATHER_MIN_TEMP = 2;
public static final int INDEX_WEATHER_CONDITION_ID = 3;

// COMPLETED (37) Remove the error TextView

/*
* This ID will be used to identify the Loader responsible for loading our weather forecast. In
Expand All @@ -86,16 +80,13 @@ public class MainActivity extends AppCompatActivity implements

private ProgressBar mLoadingIndicator;

// COMPLETED (35) Remove the preference change flag

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forecast);
getSupportActionBar().setElevation(0f);



FakeDataUtils.insertFakeData(this);

/*
Expand All @@ -104,8 +95,6 @@ protected void onCreate(Bundle savedInstanceState) {
*/
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview_forecast);

// COMPLETED (36) Remove the findViewById call for the error TextView

/*
* The ProgressBar that will indicate to the user that we are loading data. It will be
* hidden when no data is loading.
Expand Down Expand Up @@ -141,7 +130,6 @@ protected void onCreate(Bundle savedInstanceState) {
*/
mRecyclerView.setHasFixedSize(true);

// COMPLETED (4) Pass in this again as the ForecastAdapter now requires a Context
/*
* The ForecastAdapter is responsible for linking our weather data with the Views that
* will end up displaying our weather data.
Expand All @@ -158,22 +146,15 @@ protected void onCreate(Bundle savedInstanceState) {
mRecyclerView.setAdapter(mForecastAdapter);


// COMPLETED (18) Call the showLoading method
showLoading();




/*
* Ensures a loader is initialized and active. If the loader doesn't already exist, one is
* created and (if the activity/fragment is currently started) starts the loader. Otherwise
* the last created loader is re-used.
*/
getSupportLoaderManager().initLoader(ID_FORECAST_LOADER, null, this);



// COMPLETED (19) Remove the statement that registers Mainactivity as a preference change listener
}

/**
Expand Down Expand Up @@ -202,7 +183,6 @@ private void openPreferredLocationInMap() {
}
}

// COMPLETED (21) Refactor onCreateLoader to return a Loader<Cursor>, not Loader<String[]>
/**
* Called by the {@link android.support.v4.app.LoaderManagerImpl} when a new Loader needs to be
* created. This Activity only uses one loader, so we don't necessarily NEED to check the
Expand All @@ -215,13 +195,9 @@ private void openPreferredLocationInMap() {
@Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {

// COMPLETED (23) Remove the onStartLoading method declaration
// COMPLETED (24) Remove the loadInBackground method declaration
// COMPLETED (25) Remove the deliverResult method declaration

switch (loaderId) {

// COMPLETED (22) If the loader requested is our forecast loader, return the appropriate CursorLoader
case ID_FORECAST_LOADER:
/* URI for all rows of weather data in our weather table */
Uri forecastQueryUri = WeatherContract.WeatherEntry.CONTENT_URI;
Expand All @@ -246,7 +222,6 @@ public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {
}
}

// COMPLETED (26) Change onLoadFinished parameter to a Loader<Cursor> instead of a Loader<String[]>
/**
* Called when a Loader has finished loading its data.
*
Expand All @@ -261,16 +236,10 @@ public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

// COMPLETED (27) Remove the previous body of onLoadFinished

// COMPLETED (28) Call mForecastAdapter's swapCursor method and pass in the new Cursor
mForecastAdapter.swapCursor(data);
// COMPLETED (29) If mPosition equals RecyclerView.NO_POSITION, set it to 0
if (mPosition == RecyclerView.NO_POSITION) mPosition = 0;
// COMPLETED (30) Smooth scroll the RecyclerView to mPosition
mRecyclerView.smoothScrollToPosition(mPosition);

// COMPLETED (31) If the Cursor's size is not equal to 0, call showWeatherDataView
if (data.getCount() != 0) showWeatherDataView();
}

Expand All @@ -282,21 +251,22 @@ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
*/
@Override
public void onLoaderReset(Loader<Cursor> loader) {
// COMPLETED (32) Call mForecastAdapter's swapCursor method and pass in null
/*
* Since this Loader's data is now invalid, we need to clear the Adapter that is
* displaying the data.
*/
mForecastAdapter.swapCursor(null);
}

// TODO (38) Refactor onClick to accept a long instead of a String as its parameter
/**
* This method is for responding to clicks from our list.
*
* @param weatherForDay String describing weather details for a particular day
*/
@Override
public void onClick(String weatherForDay) {
// TODO (39) Refactor onClick to build a URI for the clicked date and and pass it with the Intent using setData
Context context = this;
Class destinationClass = DetailActivity.class;
Intent intentToStartDetailActivity = new Intent(context, destinationClass);
Expand All @@ -318,9 +288,6 @@ private void showWeatherDataView() {
mRecyclerView.setVisibility(View.VISIBLE);
}

// COMPLETED (33) Delete showErrorMessage

// COMPLETED (34) Create a method called showLoading that shows the loading indicator and hides the data
/**
* This method will make the loading indicator visible and hide the weather View and error
* message.
Expand Down
13 changes: 11 additions & 2 deletions app/src/main/res/layout/activity_detail.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,28 @@
See the License for the specific language governing permissions and
limitations under the License.
-->

<!-- TODO (1) Change the FrameLayout to a vertical LinearLayout -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp">

<!-- TODO (2) Remove the tv_display_weather TextView -->
<!-- Text that describes the weather summary for a given day -->
<TextView
android:id="@+id/tv_display_weather"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22sp"
tools:text="Saturday, October 1 - Sunny - 78° / 63°"/>
<!-- TODO (3) Add a TextView for the selected day's date -->
<!-- TODO (4) Add a TextView for the selected day's weather description -->
<!-- TODO (5) Add a TextView for the selected day's high temperature -->
<!-- TODO (6) Add a TextView for the selected day's low temperature -->
<!-- TODO (7) Add a TextView for the selected day's humidity -->
<!-- TODO (8) Add a TextView for the selected day's pressure -->
<!-- TODO (9) Add a TextView for the selected day's wind -->

</FrameLayout>

</FrameLayout>
1 change: 0 additions & 1 deletion app/src/main/res/layout/activity_forecast.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
android:clipToPadding="false"
android:paddingBottom="8dp"/>

<!-- COMPLETED (38) Remove this error message TextView -->

<!-- A progress bar that will be shown to users to indicate that weather data is loading -->
<ProgressBar
Expand Down

0 comments on commit 57bd891

Please sign in to comment.