@Override
 public void onPause() {
   // Remove listeners
   if (mWatchNetworkState) {
     getActivity().unregisterReceiver(mInternetStateReceiver);
   }
   mCallback.removeCursorListener(this);
   mCallback.removeScreenListener(mPosition);
   resetPhotoView();
   super.onPause();
 }
 private void displayPhoto(BitmapResult result) {
   if (result.status == BitmapResult.STATUS_EXCEPTION) {
     mProgressBarNeeded = false;
     mEmptyText.setText(R.string.failed);
     mEmptyText.setVisibility(View.VISIBLE);
     mCallback.onFragmentPhotoLoadComplete(this, false /* success */);
   } else {
     final Drawable data = result.getDrawable(getResources());
     bindPhoto(data);
     mCallback.onFragmentPhotoLoadComplete(this, true /* success */);
   }
 }
 @Override
 public void onViewActivated() {
   if (!mCallback.isFragmentActive(this)) {
     // we're not in the foreground; reset our view
     resetViews();
   } else {
     if (!isPhotoBound()) {
       // Restart the loader
       getLoaderManager().restartLoader(PhotoViewCallbacks.BITMAP_LOADER_THUMBNAIL, null, this);
     }
     mCallback.onFragmentVisible(this);
   }
 }
  @Override
  public boolean onInterceptMoveRight(float origX, float origY) {
    if (!mCallback.isFragmentActive(this)) {
      // we're not in the foreground; don't intercept any touches
      return false;
    }

    return (mPhotoView != null && mPhotoView.interceptMoveRight(origX, origY));
  }
  @Override
  public void onLoadFinished(Loader<BitmapResult> loader, BitmapResult result) {
    // If we don't have a view, the fragment has been paused. We'll get the cursor again later.
    // If we're not added, the fragment has detached during the loading process. We no longer
    // need the result.
    if (getView() == null || !isAdded()) {
      return;
    }

    final Drawable data = result.getDrawable(getResources());

    final int id = loader.getId();
    switch (id) {
      case PhotoViewCallbacks.BITMAP_LOADER_THUMBNAIL:
        if (mDisplayThumbsFullScreen) {
          displayPhoto(result);
        } else {
          if (isPhotoBound()) {
            // There is need to do anything with the thumbnail
            // image, as the full size image is being shown.
            return;
          }

          if (data == null) {
            // no preview, show default
            mPhotoPreviewImage.setImageResource(R.drawable.default_image);
            mThumbnailShown = false;
          } else {
            // show preview
            mPhotoPreviewImage.setImageDrawable(data);
            mThumbnailShown = true;
          }
          mPhotoPreviewImage.setVisibility(View.VISIBLE);
          if (getResources().getBoolean(R.bool.force_thumbnail_no_scaling)) {
            mPhotoPreviewImage.setScaleType(ImageView.ScaleType.CENTER);
          }
          enableImageTransforms(false);
        }
        break;

      case PhotoViewCallbacks.BITMAP_LOADER_PHOTO:
        displayPhoto(result);
        break;
      default:
        break;
    }

    if (mProgressBarNeeded == false) {
      // Hide the progress bar as it isn't needed anymore.
      mPhotoProgressBar.setVisibility(View.GONE);
    }

    if (data != null) {
      mCallback.onNewPhotoLoaded(mPosition);
    }
    setViewVisibility();
  }
 @Override
 public void onActivityCreated(Bundle savedInstanceState) {
   super.onActivityCreated(savedInstanceState);
   mCallback = (PhotoViewCallbacks) getActivity();
   if (mCallback == null) {
     throw new IllegalArgumentException("Activity must be a derived class of PhotoViewActivity");
   }
   mAdapter = mCallback.getAdapter();
   if (mAdapter == null) {
     throw new IllegalStateException("Callback reported null adapter");
   }
   // Don't call until we've setup the entire view
   setViewVisibility();
 }
  @Override
  public void onResume() {
    super.onResume();
    mCallback.addScreenListener(mPosition, this);
    mCallback.addCursorListener(this);

    if (mWatchNetworkState) {
      if (mInternetStateReceiver == null) {
        mInternetStateReceiver = new InternetStateBroadcastReceiver();
      }
      getActivity()
          .registerReceiver(
              mInternetStateReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
      ConnectivityManager connectivityManager =
          (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
      NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
      if (activeNetInfo != null) {
        mConnected = activeNetInfo.isConnected();
      } else {
        // Best to set this to false, since it won't stop us from trying to download,
        // only allow us to try re-download if we get notified that we do have a connection.
        mConnected = false;
      }
    }

    if (!isPhotoBound()) {
      mProgressBarNeeded = true;
      mPhotoPreviewAndProgress.setVisibility(View.VISIBLE);

      getLoaderManager().initLoader(PhotoViewCallbacks.BITMAP_LOADER_THUMBNAIL, null, this);

      // FLAG: If we are displaying thumbnails at fullscreen size, then we
      // could defer the loading of the fullscreen image until the thumbnail
      // has finished loading, or even until the user attempts to zoom in.
      getLoaderManager().initLoader(PhotoViewCallbacks.BITMAP_LOADER_PHOTO, null, this);
    }
  }
 @Override
 public Loader<BitmapResult> onCreateLoader(int id, Bundle args) {
   if (mOnlyShowSpinner) {
     return null;
   }
   String uri = null;
   switch (id) {
     case PhotoViewCallbacks.BITMAP_LOADER_THUMBNAIL:
       uri = mThumbnailUri;
       break;
     case PhotoViewCallbacks.BITMAP_LOADER_PHOTO:
       uri = mResolvedPhotoUri;
       break;
   }
   return mCallback.onCreateBitmapLoader(id, args, uri);
 }
  @Override
  public void onCursorChanged(Cursor cursor) {
    if (mAdapter == null) {
      // The adapter is set in onAttach(), and is guaranteed to be non-null. We have magically
      // received an onCursorChanged without attaching to an activity. Ignore this cursor
      // change.
      return;
    }
    // FLAG: There is a problem here:
    // If the cursor changes, and new items are added at an earlier position than
    // the current item, we will switch photos here. Really we should probably
    // try to find a photo with the same url and move the cursor to that position.
    if (cursor.moveToPosition(mPosition) && !isPhotoBound()) {
      mCallback.onCursorChanged(this, cursor);

      final LoaderManager manager = getLoaderManager();

      final Loader<BitmapResult> fakePhotoLoader =
          manager.getLoader(PhotoViewCallbacks.BITMAP_LOADER_PHOTO);
      if (fakePhotoLoader != null) {
        final PhotoBitmapLoaderInterface loader = (PhotoBitmapLoaderInterface) fakePhotoLoader;
        mResolvedPhotoUri = mAdapter.getPhotoUri(cursor);
        loader.setPhotoUri(mResolvedPhotoUri);
        loader.forceLoad();
      }

      if (!mThumbnailShown) {
        final Loader<BitmapResult> fakeThumbnailLoader =
            manager.getLoader(PhotoViewCallbacks.BITMAP_LOADER_THUMBNAIL);
        if (fakeThumbnailLoader != null) {
          final PhotoBitmapLoaderInterface loader =
              (PhotoBitmapLoaderInterface) fakeThumbnailLoader;
          mThumbnailUri = mAdapter.getThumbnailUri(cursor);
          loader.setPhotoUri(mThumbnailUri);
          loader.forceLoad();
        }
      }
    }
  }
 /** Sets view visibility depending upon whether or not we're in "full screen" mode. */
 private void setViewVisibility() {
   final boolean fullScreen = mCallback == null ? false : mCallback.isFragmentFullScreen(this);
   setFullScreen(fullScreen);
 }
 @Override
 public void onClick(View v) {
   mCallback.toggleFullScreen();
 }