private void openPreferredLocationInMap() {
    // Using the URI scheme for showing a location found on a map.  This super-handy
    // intent can is detailed in the "Common Intents" page of Android's developer site:
    // http://developer.android.com/guide/components/intents-common.html#Maps
    if (null != mForecastAdapter) {
      Cursor c = mForecastAdapter.getCursor();
      if (null != c) {
        c.moveToPosition(0);
        String posLat = c.getString(COL_COORD_LAT);
        String posLong = c.getString(COL_COORD_LONG);
        Uri geoLocation = Uri.parse("geo:" + posLat + "," + posLong);

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(geoLocation);

        if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
          startActivity(intent);
        } else {
          Log.d(
              LOG_TAG,
              "Couldn't call " + geoLocation.toString() + ", no receiving apps installed!");
        }
      }
    }
  }
 /*
    Updates the empty list view with contextually relevant information that the user can
    use to determine why they aren't seeing weather.
 */
 private void updateEmptyView() {
   if (mForecastAdapter.getItemCount() == 0) {
     TextView tv = (TextView) getView().findViewById(R.id.recyclerview_forecast_empty);
     if (null != tv) {
       // if cursor is empty, why? do we have an invalid location
       int message = R.string.empty_forecast_list;
       @SunshineSyncAdapter.LocationStatus int location = Utility.getLocationStatus(getActivity());
       switch (location) {
         case SunshineSyncAdapter.LOCATION_STATUS_SERVER_DOWN:
           message = R.string.empty_forecast_list_server_down;
           break;
         case SunshineSyncAdapter.LOCATION_STATUS_SERVER_INVALID:
           message = R.string.empty_forecast_list_server_error;
           break;
         case SunshineSyncAdapter.LOCATION_STATUS_INVALID:
           message = R.string.empty_forecast_list_invalid_location;
           break;
         default:
           if (!Utility.isNetworkAvailable(getActivity())) {
             message = R.string.empty_forecast_list_no_network;
           }
       }
       tv.setText(message);
     }
   }
 }
 @Override
 public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
   mForecastAdapter.swapCursor(data);
   updateEmptyView();
   if (data.getCount() == 0) {
     getActivity().supportStartPostponedEnterTransition();
   } else {
     mRecyclerView
         .getViewTreeObserver()
         .addOnPreDrawListener(
             new ViewTreeObserver.OnPreDrawListener() {
               @Override
               public boolean onPreDraw() {
                 // Since we know we're going to get items, we keep the listener around until
                 // we see Children.
                 if (mRecyclerView.getChildCount() > 0) {
                   mRecyclerView.getViewTreeObserver().removeOnPreDrawListener(this);
                   int position = mForecastAdapter.getSelectedItemPosition();
                   if (position == RecyclerView.NO_POSITION && -1 != mInitialSelectedDate) {
                     Cursor data = mForecastAdapter.getCursor();
                     int count = data.getCount();
                     int dateColumn =
                         data.getColumnIndex(WeatherContract.WeatherEntry.COLUMN_DATE);
                     for (int i = 0; i < count; i++) {
                       data.moveToPosition(i);
                       if (data.getLong(dateColumn) == mInitialSelectedDate) {
                         position = i;
                         break;
                       }
                     }
                   }
                   if (position == RecyclerView.NO_POSITION) position = 0;
                   // If we don't need to restart the loader, and there's a desired position to
                   // restore
                   // to, do so now.
                   mRecyclerView.smoothScrollToPosition(position);
                   RecyclerView.ViewHolder vh =
                       mRecyclerView.findViewHolderForAdapterPosition(position);
                   if (null != vh && mAutoSelectView) {
                     mForecastAdapter.selectView(vh);
                   }
                   if (mHoldForTransition) {
                     getActivity().supportStartPostponedEnterTransition();
                   }
                   return true;
                 }
                 return false;
               }
             });
   }
 }
 public void setUseTodayLayout(boolean useTodayLayout) {
   mUseTodayLayout = useTodayLayout;
   if (mForecastAdapter != null) {
     mForecastAdapter.setUseTodayLayout(mUseTodayLayout);
   }
 }
 @Override
 public void onLoaderReset(Loader<Cursor> loader) {
   mForecastAdapter.swapCursor(null);
 }
 @Override
 public void onSaveInstanceState(Bundle outState) {
   // When tablets rotate, the currently selected list item needs to be saved.
   mForecastAdapter.onSaveInstanceState(outState);
   super.onSaveInstanceState(outState);
 }
  @Override
  public View onCreateView(
      LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

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

    // Get a reference to the RecyclerView, and attach this adapter to it.
    mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview_forecast);

    // Set the layout manager
    mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    View emptyView = rootView.findViewById(R.id.recyclerview_forecast_empty);

    // use this setting to improve performance if you know that changes
    // in content do not change the layout size of the RecyclerView
    mRecyclerView.setHasFixedSize(true);

    // The ForecastAdapter will take data from a source and
    // use it to populate the RecyclerView it's attached to.
    mForecastAdapter =
        new ForecastAdapter(
            getActivity(),
            new ForecastAdapter.ForecastAdapterOnClickHandler() {
              @Override
              public void onClick(Long date, ForecastAdapter.ForecastAdapterViewHolder vh) {
                String locationSetting = Utility.getPreferredLocation(getActivity());
                ((Callback) getActivity())
                    .onItemSelected(
                        WeatherContract.WeatherEntry.buildWeatherLocationWithDate(
                            locationSetting, date),
                        vh);
              }
            },
            emptyView,
            mChoiceMode);

    // specify an adapter (see also next example)
    mRecyclerView.setAdapter(mForecastAdapter);

    final View parallaxView = rootView.findViewById(R.id.parallax_bar);
    if (null != parallaxView) {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        mRecyclerView.addOnScrollListener(
            new RecyclerView.OnScrollListener() {
              @TargetApi(Build.VERSION_CODES.HONEYCOMB)
              @Override
              public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                int max = parallaxView.getHeight();
                if (dy > 0) {
                  parallaxView.setTranslationY(
                      Math.max(-max, parallaxView.getTranslationY() - dy / 2));
                } else {
                  parallaxView.setTranslationY(
                      Math.min(0, parallaxView.getTranslationY() - dy / 2));
                }
              }
            });
      }
    }

    final AppBarLayout appbarView = (AppBarLayout) rootView.findViewById(R.id.appbar);
    if (null != appbarView) {
      ViewCompat.setElevation(appbarView, 0);
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        mRecyclerView.addOnScrollListener(
            new RecyclerView.OnScrollListener() {
              @TargetApi(Build.VERSION_CODES.LOLLIPOP)
              @Override
              public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                if (0 == mRecyclerView.computeVerticalScrollOffset()) {
                  appbarView.setElevation(0);
                } else {
                  appbarView.setElevation(appbarView.getTargetElevation());
                }
              }
            });
      }
    }

    // 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) {
      mForecastAdapter.onRestoreInstanceState(savedInstanceState);
    }

    mForecastAdapter.setUseTodayLayout(mUseTodayLayout);

    return rootView;
  }