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

Commit

Permalink
5.12 Coding Task to Restore scroll position on rotation (quiz)
Browse files Browse the repository at this point in the history
  • Loading branch information
Lyla committed Mar 4, 2015
1 parent 57b2926 commit 1e95ccd
Showing 1 changed file with 51 additions and 11 deletions.
Expand Up @@ -37,6 +37,12 @@
* Encapsulates fetching the forecast and displaying it as a {@link ListView} layout.
*/
public class ForecastFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
private ForecastAdapter mForecastAdapter;

private ListView mListView;
private int mPosition = ListView.INVALID_POSITION;

private static final String SELECTED_KEY = "selected_position";

private static final int FORECAST_LOADER = 0;
// For the forecast view we're showing only a small subset of the stored data.
Expand Down Expand Up @@ -71,8 +77,6 @@ public class ForecastFragment extends Fragment implements LoaderManager.LoaderCa
static final int COL_COORD_LAT = 7;
static final int COL_COORD_LONG = 8;

private ForecastAdapter mForecastAdapter;

/**
* A callback interface that all activities containing this fragment must
* implement. This mechanism allows activities to be notified of item
Expand Down Expand Up @@ -116,17 +120,18 @@ public boolean onOptionsItemSelected(MenuItem item) {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// The CursorAdapter will take data from our cursor and populate the ListView.

// The ForecastAdapter will take data from a source and
// use it to populate the ListView it's attached to.
mForecastAdapter = new ForecastAdapter(getActivity(), null, 0);

View rootView = inflater.inflate(R.layout.fragment_main, container, false);

// Get a reference to the ListView, and attach this adapter to it.
ListView listView = (ListView) rootView.findViewById(R.id.listview_forecast);
listView.setAdapter(mForecastAdapter);

mListView = (ListView) rootView.findViewById(R.id.listview_forecast);
mListView.setAdapter(mForecastAdapter);
// We'll call our MainActivity
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Expand All @@ -140,8 +145,21 @@ public void onItemClick(AdapterView<?> adapterView, View view, int position, lon
locationSetting, cursor.getLong(COL_WEATHER_DATE)
));
}
mPosition = position;
}
});

// If there's instance state, mine it for useful information.
// The end-goal here is that the user never knows that turning their device sideways
// does crazy lifecycle related things. It should feel like some stuff stretched out,
// or magically appeared to take advantage of room, but data or place in the app was never
// actually *lost*.
if (savedInstanceState != null && savedInstanceState.containsKey(SELECTED_KEY)) {
// The listview probably hasn't even been populated yet. Actually perform the
// swapout in onLoadFinished.
mPosition = savedInstanceState.getInt(SELECTED_KEY);
}

return rootView;
}

Expand All @@ -163,12 +181,29 @@ private void updateWeather() {
weatherTask.execute(location);
}

@Override
public void onSaveInstanceState(Bundle outState) {
// When tablets rotate, the currently selected list item needs to be saved.
// When no item is selected, mPosition will be set to Listview.INVALID_POSITION,
// so check for that before storing.
if (mPosition != ListView.INVALID_POSITION) {
outState.putInt(SELECTED_KEY, mPosition);
}
super.onSaveInstanceState(outState);
}

@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
String locationSetting = Utility.getPreferredLocation(getActivity());
// This is called when a new Loader needs to be created. This
// fragment only uses one loader, so we don't care about checking the id.

// To only show current and future dates, filter the query to return weather only for
// dates after or including today.

// Sort order: Ascending, by date.
String sortOrder = WeatherContract.WeatherEntry.COLUMN_DATE + " ASC";

String locationSetting = Utility.getPreferredLocation(getActivity());
Uri weatherForLocationUri = WeatherContract.WeatherEntry.buildWeatherLocationWithStartDate(
locationSetting, System.currentTimeMillis());

Expand All @@ -181,12 +216,17 @@ public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
}

@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
mForecastAdapter.swapCursor(cursor);
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mForecastAdapter.swapCursor(data);
if (mPosition != ListView.INVALID_POSITION) {
// If we don't need to restart the loader, and there's a desired position to restore
// to, do so now.
mListView.smoothScrollToPosition(mPosition);
}
}

@Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
mForecastAdapter.swapCursor(null);
}
}
}

2 comments on commit 1e95ccd

@jakubosiak
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I rotate my device selected view is not highlited anymore.
I was looking for solution for this problem but I couldn't find any.
Do some of you guys run into the same problem?

@jakubosiak
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found the solution:
Hint: mListView.setItemChecked(int position, boolean value);
Good luck :)

Please sign in to comment.